| /******************************************************************************* |
| * Copyright (c) 2009, 2014 Xored Software Inc 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: |
| * Xored Software Inc - initial API and implementation and/or initial documentation |
| *******************************************************************************/ |
| package org.eclipse.rcptt.ctx.parameters.ui; |
| |
| import static java.util.Arrays.asList; |
| |
| import java.io.IOException; |
| import java.io.StringWriter; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| import org.eclipse.core.databinding.observable.Diffs; |
| import org.eclipse.core.databinding.observable.value.ComputedValue; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IMenuListener; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.ToolBarManager; |
| import org.eclipse.jface.databinding.swt.SWTObservables; |
| import org.eclipse.jface.databinding.viewers.IViewerObservableList; |
| import org.eclipse.jface.databinding.viewers.ViewersObservables; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.layout.GridDataFactory; |
| import org.eclipse.jface.layout.GridLayoutFactory; |
| import org.eclipse.jface.viewers.CellEditor; |
| import org.eclipse.jface.viewers.CheckboxTreeViewer; |
| import org.eclipse.jface.viewers.ColumnLabelProvider; |
| import org.eclipse.jface.viewers.EditingSupport; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.IStructuredContentProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.viewers.TableViewer; |
| import org.eclipse.jface.viewers.TableViewerColumn; |
| import org.eclipse.jface.viewers.TextCellEditor; |
| import org.eclipse.jface.viewers.TreeViewerColumn; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerComparator; |
| import org.eclipse.rcptt.core.model.ModelException; |
| import org.eclipse.rcptt.internal.core.RcpttPlugin; |
| import org.eclipse.rcptt.internal.ui.Images; |
| import org.eclipse.rcptt.internal.ui.Q7UIPlugin; |
| import org.eclipse.rcptt.parameters.Parameter; |
| import org.eclipse.rcptt.parameters.ParametersContext; |
| import org.eclipse.rcptt.parameters.ParametersFactory; |
| import org.eclipse.rcptt.ui.commons.ArrayTreeContentProvider; |
| import org.eclipse.rcptt.ui.context.BaseContextEditor; |
| import org.eclipse.rcptt.ui.editors.EditorHeader; |
| import org.eclipse.rcptt.ui.editors.IQ7EditorActionsProvider; |
| import org.eclipse.rcptt.ui.editors.NamedElementEditorActions.INamedElementActions; |
| import org.eclipse.rcptt.util.StringUtils; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.dnd.Clipboard; |
| import org.eclipse.swt.dnd.TextTransfer; |
| import org.eclipse.swt.dnd.Transfer; |
| import org.eclipse.swt.events.FocusEvent; |
| import org.eclipse.swt.events.FocusListener; |
| import org.eclipse.swt.events.KeyAdapter; |
| import org.eclipse.swt.events.KeyEvent; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.TraverseEvent; |
| import org.eclipse.swt.events.TraverseListener; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.FontData; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableColumn; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.ToolTip; |
| import org.eclipse.swt.widgets.TreeColumn; |
| import org.eclipse.ui.ISharedImages; |
| import org.eclipse.ui.IWorkbenchSite; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.CheckedTreeSelectionDialog; |
| import org.eclipse.ui.forms.widgets.FormToolkit; |
| import org.eclipse.ui.forms.widgets.Section; |
| |
| public class ParametersContextEditor extends BaseContextEditor implements |
| IQ7EditorActionsProvider { |
| |
| private static final String NAME_PROPERTY = "name"; |
| private static final String VALUE_PROPERTY = "value"; |
| private static final String[] NAME_PROPERTIES = new String[] { NAME_PROPERTY }; |
| private static final String[] VALUE_PROPERTIES = new String[] { VALUE_PROPERTY }; |
| |
| private static Parameter newParameterItem; |
| static { |
| newParameterItem = ParametersFactory.eINSTANCE.createParameter(); |
| newParameterItem.setName("Add new parameter"); |
| newParameterItem.setValue(""); |
| } |
| |
| private Table table; |
| private TableViewer viewer; |
| private ToolTip tip; |
| private String lastNewName = ""; |
| |
| private TableColumn nameColumn; |
| private TableColumn valueColumn; |
| |
| // to preserve default sort order while keeping newParameterItem on bottom |
| private HashMap<String, Integer> nameToIndex = new HashMap<String, Integer>(); |
| |
| @Override |
| public void setSelectionAtLine(int line) { |
| if (table != null) { |
| if (line < table.getItemCount()) { |
| table.deselectAll(); |
| table.select(line); |
| table.setFocus(); |
| } |
| } |
| } |
| |
| public ParametersContext getContextElement() { |
| try { |
| return (ParametersContext) super.getElement().getNamedElement(); |
| } catch (ModelException e) { |
| Q7UIPlugin.log(e); |
| return null; |
| } |
| } |
| |
| public void dispose() { |
| tip.setVisible(false); |
| super.dispose(); |
| } |
| |
| public Control create(Composite parent, FormToolkit toolkit, |
| IWorkbenchSite site, EditorHeader header) { |
| Section section = toolkit.createSection(parent, Section.TITLE_BAR |
| | Section.TWISTIE | Section.EXPANDED |
| | Section.NO_TITLE_FOCUS_BOX); |
| GridDataFactory.fillDefaults().grab(true, true).applyTo(section); |
| section.setText("Parameters"); |
| |
| Composite composite = toolkit.createComposite(section); |
| section.setClient(composite); |
| GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); |
| viewer = createTable(composite, toolkit); |
| createPanel(composite, toolkit); |
| |
| tip = new ToolTip(parent.getShell(), SWT.BALLOON); |
| tip.setText("Error"); |
| |
| // Composite forToolbar = toolkit.createComposite(section); |
| Clipboard clipboard = new Clipboard(parent.getDisplay()); |
| pasteAction = new PasteAction(clipboard); |
| copyAction = new CopyAction(clipboard); |
| ToolBarManager toolBarManager = new ToolBarManager(SWT.HORIZONTAL); |
| toolBarManager.add(copyAction); |
| toolBarManager.add(pasteAction); |
| section.setTextClient(toolBarManager.createControl(section)); |
| MenuManager menu = new MenuManager(); |
| menu.add(copyAction); |
| menu.add(pasteAction); |
| menu.addMenuListener(new IMenuListener() { |
| |
| @Override |
| public void menuAboutToShow(IMenuManager manager) { |
| copyAction.update(); |
| pasteAction.update(); |
| } |
| }); |
| menu.update(true); |
| viewer.getControl() |
| .setMenu(menu.createContextMenu(viewer.getControl())); |
| return section; |
| } |
| |
| private void sortBy(TableColumn column) { |
| if (table.getSortColumn() != column) { |
| table.setSortColumn(column); |
| table.setSortDirection(SWT.UP); |
| viewer.setComparator(new Comparator(column, SWT.UP)); |
| } else if (table.getSortDirection() == SWT.UP) { |
| table.setSortDirection(SWT.DOWN); |
| viewer.setComparator(new Comparator(column, SWT.DOWN)); |
| } else { |
| table.setSortColumn(null); |
| table.setSortDirection(SWT.NONE); |
| viewer.setComparator(new Comparator()); |
| } |
| |
| viewer.refresh(); |
| } |
| |
| private static final ISharedImages sharedImages = PlatformUI.getWorkbench() |
| .getSharedImages(); |
| |
| class CopyAction extends Action { |
| private final Clipboard clipboard; |
| |
| public CopyAction(Clipboard clipboard) { |
| super("Copy selected parameters", sharedImages |
| .getImageDescriptor(ISharedImages.IMG_TOOL_COPY)); |
| setDisabledImageDescriptor(sharedImages |
| .getImageDescriptor(ISharedImages.IMG_TOOL_COPY_DISABLED)); |
| this.clipboard = clipboard; |
| viewer.addSelectionChangedListener(new ISelectionChangedListener() { |
| @Override |
| public void selectionChanged(SelectionChangedEvent event) { |
| update(); |
| } |
| }); |
| update(); |
| } |
| |
| @Override |
| public void run() { |
| IStructuredSelection selection = (IStructuredSelection) viewer |
| .getSelection(); |
| Parameter[] parameters = new Parameter[selection.size()]; |
| Object[] selected = selection.toArray(); |
| Properties properties = new Properties(); |
| for (int i = 0; i < selection.size(); i++) { |
| Parameter parameter = (Parameter) selected[i]; |
| parameters[i] = parameter; |
| properties.put(parameter.getName(), parameter.getValue()); |
| } |
| StringWriter writer = new StringWriter(); |
| try { |
| properties.store(writer, ""); |
| } catch (IOException e) { |
| RcpttPlugin.log(e); |
| writer = new StringWriter(); |
| } |
| |
| clipboard.setContents(new Object[] { parameters, |
| writer.getBuffer().toString() }, new Transfer[] { |
| ParametersTransfer.INSTANCE, TextTransfer.getInstance() }); |
| } |
| |
| Object[] getSelection() { |
| IStructuredSelection selection = (IStructuredSelection) viewer |
| .getSelection(); |
| return selection.toArray(); |
| } |
| |
| void update() { |
| setEnabled(getSelection().length > 0); |
| } |
| |
| } |
| |
| static class Conflict { |
| public final String name; |
| public final String value1; |
| public final String value2; |
| |
| public Conflict(String name, String value1, String value2) { |
| super(); |
| this.name = name; |
| this.value1 = value1; |
| this.value2 = value2; |
| } |
| } |
| |
| private static Map<String, String> toDictionary( |
| Collection<Parameter> parameters) { |
| Map<String, String> rv = new HashMap<String, String>(); |
| for (Parameter parameter : parameters) { |
| rv.put(parameter.getName(), parameter.getValue()); |
| } |
| return rv; |
| } |
| |
| private static Collection<Conflict> findConflicts( |
| Map<String, String> first, Map<String, String> second) { |
| List<Conflict> rv = new ArrayList<Conflict>(); |
| |
| for (Object key: (Diffs.computeMapDiff(first, second).getChangedKeys())) { |
| String name = (String) key; |
| String value1 = first.get(key); |
| String value2 = second.get(name); |
| rv.add(new Conflict(name, value1, value2)); |
| } |
| return rv; |
| } |
| |
| /** |
| * Asks user to select parameters to overwrite |
| * |
| * @return conflicts to overwrite |
| */ |
| private Collection<Conflict> resolveConflicts( |
| final Collection<Conflict> conflict) { |
| |
| CheckedTreeSelectionDialog dialog = new CheckedTreeSelectionDialog( |
| getForm().getForm().getShell(), new LabelProvider(), |
| new ArrayTreeContentProvider()) { |
| |
| @Override |
| protected CheckboxTreeViewer createTreeViewer(Composite parent) { |
| final CheckboxTreeViewer rv = super.createTreeViewer(parent); |
| TreeViewerColumn column = new TreeViewerColumn(rv, SWT.NONE); |
| column.getColumn().setText("Name"); |
| column.setLabelProvider(new ColumnLabelProvider() { |
| |
| @Override |
| public String getText(Object element) { |
| return ((Conflict) element).name; |
| } |
| |
| }); |
| column = new TreeViewerColumn(rv, SWT.NONE); |
| column.getColumn().setText("Original value"); |
| column.setLabelProvider(new ColumnLabelProvider() { |
| |
| @Override |
| public String getText(Object element) { |
| return ((Conflict) element).value1; |
| } |
| |
| }); |
| column = new TreeViewerColumn(rv, SWT.NONE); |
| column.getColumn().setText("New value"); |
| column.setLabelProvider(new ColumnLabelProvider() { |
| |
| @Override |
| public String getText(Object element) { |
| return ((Conflict) element).value2; |
| } |
| |
| }); |
| rv.getTree().setHeaderVisible(true); |
| rv.refresh(); |
| for (TreeColumn col : rv.getTree().getColumns()) { |
| col.pack(); |
| } |
| rv.addSelectionChangedListener(new ISelectionChangedListener() { |
| @Override |
| public void selectionChanged(final SelectionChangedEvent event) { |
| if (!event.getSelection().isEmpty()) { |
| rv.setSelection(StructuredSelection.EMPTY); |
| } |
| } |
| }); |
| return rv; |
| } |
| }; |
| |
| dialog.setTitle("Parameters name conflict"); |
| dialog.setMessage("Select parameters to overwrite with new values"); |
| dialog.setInput(conflict); |
| if (dialog.open() != Dialog.OK) |
| return null; |
| Object[] result = dialog.getResult(); |
| if (result == null) |
| return null; |
| List<Conflict> rv = new ArrayList<Conflict>(); |
| for (Object object : result) { |
| rv.add((Conflict) object); |
| } |
| return rv; |
| } |
| |
| class PasteAction extends Action { |
| private final Clipboard clipboard; |
| |
| public PasteAction(Clipboard clipboard) { |
| super("Paste", PlatformUI.getWorkbench().getSharedImages() |
| .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE)); |
| setDisabledImageDescriptor(sharedImages |
| .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED)); |
| this.clipboard = clipboard; |
| viewer.getControl().addFocusListener(new FocusListener() { |
| |
| @Override |
| public void focusLost(FocusEvent e) { |
| update(); |
| } |
| |
| @Override |
| public void focusGained(FocusEvent e) { |
| update(); |
| } |
| }); |
| update(); |
| } |
| |
| protected void update() { |
| setEnabled(getPasted().length > 0); |
| } |
| |
| @Override |
| public void run() { |
| ParametersContext element = getContextElement(); |
| List<Parameter> newParameters = asList(getPasted()); |
| |
| Map<String, String> origMap = toDictionary(element.getParameters()); |
| Map<String, String> newMap = toDictionary(newParameters); |
| |
| |
| Collection<Conflict> conflicts = findConflicts(origMap, newMap); |
| |
| if (conflicts.size() > 0) { |
| // only overwrite conflicts selected by user |
| for (Conflict conflict : conflicts) { |
| newMap.remove(conflict.name); |
| } |
| conflicts = resolveConflicts(conflicts); |
| if (conflicts == null) |
| return; |
| for (Conflict conflict : conflicts) { |
| newMap.put(conflict.name, conflict.value2); |
| } |
| } |
| |
| Map<String, Parameter> paramMap = new HashMap<String, Parameter>(); |
| for (Parameter parameter : element.getParameters()) { |
| paramMap.put(parameter.getName(), parameter); |
| } |
| |
| for (Map.Entry<String, String> entry : newMap.entrySet()) { |
| Parameter parameter = paramMap.get(entry.getKey()); |
| if (parameter == null) { |
| parameter = ParametersFactory.eINSTANCE.createParameter(); |
| parameter.setName(entry.getKey()); |
| element.getParameters().add(parameter); |
| } |
| parameter.setValue(entry.getValue()); |
| } |
| |
| updateIndexes(); |
| viewer.refresh(); |
| } |
| |
| private Parameter[] getPasted() { |
| Parameter[] rv = (Parameter[]) clipboard |
| .getContents(ParametersTransfer.INSTANCE); |
| if (rv == null) |
| rv = new Parameter[0]; |
| return rv; |
| } |
| } |
| |
| PasteAction pasteAction; |
| CopyAction copyAction; |
| |
| private TableViewer createTable(Composite parent, FormToolkit toolkit) { |
| table = new Table(parent, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); |
| GridDataFactory.fillDefaults().grab(true, true).hint(100, 50) |
| .applyTo(table); |
| table.setHeaderVisible(true); |
| toolkit.adapt(table); |
| table.setLinesVisible(true); |
| |
| nameColumn = new TableColumn(table, SWT.LEFT); |
| nameColumn.setText("Name"); |
| nameColumn.setWidth(200); |
| nameColumn.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| sortBy(nameColumn); |
| } |
| }); |
| |
| valueColumn = new TableColumn(table, SWT.LEFT); |
| valueColumn.setText("Value"); |
| valueColumn.setWidth(350); |
| valueColumn.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| sortBy(valueColumn); |
| } |
| }); |
| |
| table.addKeyListener(new KeyAdapter() { |
| |
| public void keyPressed(KeyEvent e) { |
| switch (e.keyCode) { |
| case SWT.DEL: |
| case SWT.BS: |
| removeSelected(); |
| break; |
| case SWT.INSERT: |
| addNew(); |
| break; |
| case SWT.CR: |
| case SWT.F2: |
| lastNewName = ""; |
| Object el = ((StructuredSelection) viewer.getSelection()) |
| .getFirstElement(); |
| if (el != null) |
| viewer.editElement(el, 0); |
| else |
| viewer.editElement(newParameterItem, 0); |
| break; |
| } |
| } |
| }); |
| |
| final TableViewer viewer = new TableViewer(table); |
| viewer.setContentProvider(new IStructuredContentProvider() { |
| |
| public void dispose() { |
| // do nothing |
| } |
| |
| public void inputChanged(Viewer viewer, Object oldInput, |
| Object newInput) { |
| // do nothing |
| } |
| |
| public Object[] getElements(Object inputElement) { |
| ParametersContext ctx = (ParametersContext) inputElement; |
| |
| List<Parameter> elements = new ArrayList<Parameter>(); |
| elements.addAll(ctx.getParameters()); |
| elements.add(newParameterItem); |
| |
| return elements.toArray(); |
| } |
| |
| }); |
| |
| // -- |
| |
| TableViewerColumn nameViewerColumn = new TableViewerColumn(viewer, |
| nameColumn); |
| nameViewerColumn.setLabelProvider(new ColumnLabelProvider() { |
| |
| public String getText(Object element) { |
| Parameter p = (Parameter) element; |
| return p.getName(); |
| } |
| |
| public Image getImage(Object element) { |
| return element == newParameterItem ? Images.getImageDescriptor( |
| ISharedImages.IMG_OBJ_ADD).createImage() : Images |
| .getImage(Images.PARAMETER); |
| } |
| |
| public Font getFont(Object element) { |
| if (element == newParameterItem) { |
| Font tableFont = table.getFont(); |
| FontData fd = tableFont.getFontData()[0]; |
| fd.setStyle(fd.getStyle() | SWT.ITALIC); |
| |
| return new Font(tableFont.getDevice(), fd); |
| } else |
| return null; |
| } |
| }); |
| |
| nameViewerColumn.setEditingSupport(new EditingSupport(viewer) { |
| |
| protected CellEditor getCellEditor(final Object element) { |
| final TextCellEditor editor = new TextCellEditor(table); |
| editor.getControl().addTraverseListener(new TraverseListener() { |
| |
| public void keyTraversed(TraverseEvent e) { |
| Text text = (Text) editor.getControl(); |
| |
| switch (e.detail) { |
| case SWT.TRAVERSE_TAB_NEXT: |
| if (validateName(element, text.getText())) |
| viewer.editElement(element, 1); |
| e.detail = SWT.TRAVERSE_NONE; |
| e.doit = false; |
| break; |
| case SWT.TRAVERSE_ARROW_NEXT: |
| if (e.keyCode == SWT.ARROW_DOWN) { |
| if (table.getItemCount() > table |
| .getSelectionIndex() + 1 |
| && (isNewAndBlank(element, |
| text.getText()) || validateName( |
| element, text.getText()))) |
| viewer.editElement(viewer |
| .getElementAt(table |
| .getSelectionIndex() + 1), |
| 0); |
| e.detail = SWT.TRAVERSE_NONE; |
| e.doit = false; |
| } |
| break; |
| case SWT.TRAVERSE_ARROW_PREVIOUS: |
| if (e.keyCode == SWT.ARROW_UP) { |
| if (table.getSelectionIndex() > 0 |
| && (isNewAndBlank(element, |
| text.getText()) || validateName( |
| element, text.getText()))) |
| viewer.editElement(viewer |
| .getElementAt(table |
| .getSelectionIndex() - 1), |
| 0); |
| e.detail = SWT.TRAVERSE_NONE; |
| e.doit = false; |
| } |
| break; |
| } |
| } |
| |
| }); |
| return editor; |
| } |
| |
| protected boolean canEdit(Object element) { |
| return true; |
| } |
| |
| protected Object getValue(Object element) { |
| if (lastNewName.length() > 0) |
| return lastNewName; |
| else if (element == newParameterItem) |
| return ""; |
| else { |
| Parameter p = (Parameter) element; |
| return p.getName(); |
| } |
| } |
| |
| protected void setValue(final Object element, Object value) { |
| String name = (String) value; |
| Parameter param = (Parameter) element; |
| ParametersContext ctx = getContextElement(); |
| |
| if (isNewAndBlank(element, name)) { |
| lastNewName = ""; |
| return; |
| } |
| |
| if (!validateName(element, name)) { |
| table.getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| if (!table.isDisposed()) |
| viewer.editElement(element, 0); |
| } |
| }); |
| |
| return; |
| } |
| |
| if (param != newParameterItem) { |
| if (!param.getName().equals(name)) { |
| Integer index = nameToIndex.get(param.getName()); |
| nameToIndex.remove(param.getName()); |
| nameToIndex.put(name, index); |
| |
| param.setName(name); |
| viewer.update(element, NAME_PROPERTIES); |
| } |
| } else { |
| final Parameter newParam = ParametersFactory.eINSTANCE |
| .createParameter(); |
| newParam.setName(name); |
| newParam.setValue(""); |
| |
| nameToIndex.put(name, table.getItemCount() - 1); |
| |
| ctx.getParameters().add(newParam); |
| viewer.add(newParam); |
| |
| viewer.setSelection(new StructuredSelection(newParam), true); |
| table.getDisplay().asyncExec(new Runnable() { |
| |
| public void run() { |
| viewer.editElement(newParam, 1); |
| } |
| }); |
| } |
| } |
| |
| }); |
| |
| // -- |
| |
| TableViewerColumn valueViewerColumn = new TableViewerColumn(viewer, |
| valueColumn); |
| valueViewerColumn.setLabelProvider(new ColumnLabelProvider() { |
| public String getText(Object element) { |
| Parameter p = (Parameter) element; |
| return p.getValue(); |
| } |
| }); |
| |
| valueViewerColumn.setEditingSupport(new EditingSupport(viewer) { |
| |
| protected CellEditor getCellEditor(final Object element) { |
| final TextCellEditor editor = new TextCellEditor(table); |
| editor.getControl().addTraverseListener(new TraverseListener() { |
| |
| public void keyTraversed(TraverseEvent e) { |
| Text text = (Text) editor.getControl(); |
| |
| switch (e.detail) { |
| case SWT.TRAVERSE_TAB_PREVIOUS: |
| if (validateName(element, text.getText())) |
| viewer.editElement(element, 0); |
| e.detail = SWT.TRAVERSE_NONE; |
| e.doit = false; |
| break; |
| case SWT.TRAVERSE_ARROW_NEXT: |
| if (e.keyCode == SWT.ARROW_DOWN) { |
| if (table.getItemCount() > table |
| .getSelectionIndex() + 1) |
| viewer.editElement(viewer |
| .getElementAt(table |
| .getSelectionIndex() + 1), |
| 1); |
| e.detail = SWT.TRAVERSE_NONE; |
| e.doit = false; |
| } |
| break; |
| case SWT.TRAVERSE_ARROW_PREVIOUS: |
| if (e.keyCode == SWT.ARROW_UP) { |
| if (table.getSelectionIndex() > 0) |
| viewer.editElement(viewer |
| .getElementAt(table |
| .getSelectionIndex() - 1), |
| 1); |
| e.detail = SWT.TRAVERSE_NONE; |
| e.doit = false; |
| } |
| break; |
| } |
| } |
| |
| }); |
| return editor; |
| } |
| |
| protected boolean canEdit(Object element) { |
| return element != newParameterItem; |
| } |
| |
| protected Object getValue(Object element) { |
| Parameter p = (Parameter) element; |
| return p.getValue(); |
| } |
| |
| protected void setValue(Object element, Object value) { |
| Parameter p = (Parameter) element; |
| String v = (String) value; |
| if (!p.getValue().equals(v)) { |
| p.setValue((String) value); |
| viewer.update(element, VALUE_PROPERTIES); |
| } |
| } |
| |
| }); |
| |
| // -- |
| |
| updateIndexes(); |
| viewer.setComparator(new Comparator()); |
| |
| // -- |
| |
| viewer.setInput(getContextElement()); |
| |
| return viewer; |
| } |
| |
| private void updateIndexes() { |
| nameToIndex.clear(); |
| EList<Parameter> params = getContextElement().getParameters(); |
| for (int i = 0; i < params.size(); ++i) |
| nameToIndex.put(params.get(i).getName(), i); |
| } |
| |
| private void createPanel(Composite parent, FormToolkit toolkit) { |
| Composite panel = toolkit.createComposite(parent); |
| GridLayoutFactory.fillDefaults().applyTo(panel); |
| GridDataFactory.fillDefaults().grab(false, true).applyTo(panel); |
| |
| Button addButton = toolkit.createButton(panel, "Add", SWT.PUSH); |
| GridDataFactory.fillDefaults().grab(true, false).applyTo(addButton); |
| addButton.setImage(Images.getImageDescriptor(ISharedImages.IMG_OBJ_ADD) |
| .createImage()); |
| addButton.addSelectionListener(new SelectionAdapter() { |
| |
| public void widgetSelected(SelectionEvent e) { |
| addNew(); |
| } |
| }); |
| |
| Button removeButton = toolkit.createButton(panel, "Remove", SWT.PUSH); |
| GridDataFactory.fillDefaults().grab(true, false).applyTo(removeButton); |
| removeButton.setImage(Images.getImageDescriptor( |
| ISharedImages.IMG_ETOOL_DELETE).createImage()); |
| dbc.bindValue(SWTObservables.observeEnabled(removeButton), |
| new ComputedValue() { |
| |
| protected Object calculate() { |
| IViewerObservableList selection = ViewersObservables |
| .observeMultiSelection(viewer); |
| if (selection.size() == 1 |
| && selection.get(0) == newParameterItem) |
| return false; |
| else |
| return !selection.isEmpty(); |
| } |
| }); |
| removeButton.addSelectionListener(new SelectionAdapter() { |
| |
| public void widgetSelected(SelectionEvent e) { |
| removeSelected(); |
| } |
| }); |
| } |
| |
| protected void addNew() { |
| lastNewName = ""; |
| viewer.editElement(newParameterItem, 0); |
| } |
| |
| protected void removeSelected() { |
| ParametersContext ctx = getContextElement(); |
| Object[] selection = ((IStructuredSelection) viewer.getSelection()) |
| .toArray(); |
| |
| ArrayList<Object> removed = new ArrayList<Object>(); |
| for (Object o : selection) { |
| if (o == newParameterItem) |
| continue; |
| ctx.getParameters().remove(o); |
| nameToIndex.remove(((Parameter) o).getName()); |
| removed.add(o); |
| } |
| |
| viewer.remove(removed.toArray()); |
| } |
| |
| private boolean validateName(final Object element, String name) { |
| ParametersContext ctx = getContextElement(); |
| Parameter param = (Parameter) element; |
| String error = null; |
| |
| if (StringUtils.isBlank(name)) |
| error = "Blank name"; |
| else |
| for (Parameter p : ctx.getParameters()) |
| if (p != param && p.getName().equals(name)) { |
| error = "Duplicate parameter name"; |
| break; |
| } |
| |
| if (error != null) { |
| lastNewName = name; |
| |
| Rectangle b = table.getSelection()[0].getBounds(); |
| Point p = table.toDisplay(b.x, b.y); |
| tip.setLocation(p.x + 16, p.y + b.height); |
| |
| tip.setMessage(error); |
| tip.setVisible(false); |
| tip.setVisible(true); |
| |
| return false; |
| } else { |
| tip.setVisible(false); |
| lastNewName = ""; |
| return true; |
| } |
| } |
| |
| private boolean isNewAndBlank(Object element, String name) { |
| return element == newParameterItem && StringUtils.isBlank(name); |
| } |
| |
| private class Comparator extends ViewerComparator { |
| |
| private final TableColumn column; |
| private final int direction; |
| |
| public Comparator() { |
| this(null, SWT.NONE); |
| } |
| |
| public Comparator(TableColumn column, int direction) { |
| this.column = column; |
| this.direction = direction; |
| } |
| |
| @Override |
| public int compare(Viewer viewer, Object e1, Object e2) { |
| Parameter a = (Parameter) e1; |
| Parameter b = (Parameter) e2; |
| |
| if (a == newParameterItem) |
| return +1; |
| else if (b == newParameterItem) |
| return -1; |
| |
| if (column == null) { |
| return nameToIndex.get(a.getName()) |
| - nameToIndex.get(b.getName()); |
| } else { |
| String strA = column == nameColumn ? a.getName() : a.getValue(); |
| String strB = column == nameColumn ? b.getName() : b.getValue(); |
| int r = strA.compareTo(strB); |
| return direction == SWT.UP ? r : -r; |
| } |
| } |
| |
| @Override |
| public boolean isSorterProperty(Object element, String property) { |
| if (column == nameColumn) |
| return NAME_PROPERTY.equals(property); |
| if (column == valueColumn) |
| return VALUE_PROPERTY.equals(property); |
| return false; |
| } |
| } |
| |
| private final INamedElementActions actions = new INamedElementActions() { |
| |
| @Override |
| public void undo() { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void redo() { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void paste() { |
| pasteAction.run(); |
| } |
| |
| @Override |
| public void cut() { |
| // TODO Auto-generated method stub |
| |
| } |
| |
| @Override |
| public void copy() { |
| copyAction.run(); |
| } |
| |
| @Override |
| public boolean canUndo() { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public boolean canRedo() { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public boolean canPaste() { |
| pasteAction.update(); |
| return pasteAction.isEnabled(); |
| } |
| |
| @Override |
| public boolean canCut() { |
| // TODO Auto-generated method stub |
| return false; |
| } |
| |
| @Override |
| public boolean canCopy() { |
| pasteAction.update(); |
| return copyAction.isEnabled(); |
| } |
| }; |
| |
| @Override |
| public INamedElementActions createActions() { |
| return actions; |
| } |
| |
| } |