Java tutorial
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). // All rights reserved. // This component and the accompanying materials are made available // under the terms of "Eclipse Public License v1.0" // which accompanies this distribution, and is available // at the URL "http://www.eclipse.org/legal/epl-v10.html". // // Initial Contributors: // Nokia Corporation - initial contribution. // // Contributors: // // Description: // package com.symbian.smt.gui.smtwidgets; import java.util.ArrayList; import java.util.Iterator; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ListViewer; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowData; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.eclipse.ui.actions.SelectionProviderAction; import com.symbian.smt.gui.Helper; /** * This widget contains all the functionality to handle assignment of generic * command line parameters. * <p> * It allows to add, remove and edit command line options, as well as changing * their order. * </p> * NB: This class is in need of refactoring using the common classes that are * also being utilised in the ResourcesWidget class. * * @author barbararosi-schwartz */ public class AdvancedOptionsWidget extends Composite { /** * This is the parent of all actions that act on the command line options * from the list of assigned options. * <p> * It caches the Button that is the presentation proxy for the action and * manages the enabled state of the Button to be consistent with its own * enablement state. * </p> * * @author barbararosi-schwartz * */ private abstract class AbstractOptionAction extends SelectionProviderAction { protected Button actionProxy; /** * The constructor sets the text on the Button that is the visual proxy * of this action and caches the button for later usage. * * @param text * the text that represents both the name of the action and * the label on the corresponding Button * @param button * the Button that acts as the visual proxy of this action. */ private AbstractOptionAction(String text, Button button) { super(viewer, text); this.actionProxy = button; actionProxy.setText(text); } /** * The default implementation of this method does nothing. */ @Override public void dispose() { super.dispose(); } /** * The default implementation of this method does nothing. */ @Override public void run() { super.run(); }; /** * The default implementation of this method does nothing. */ @Override public void selectionChanged(IStructuredSelection selection) { super.selectionChanged(selection); } /** * Sets the enablement state of the proxy Button to be the same as the * enablement state of the action, the latter being managed by a call to * super.setEnabled(). */ @Override public final void setEnabled(boolean enabled) { actionProxy.setEnabled(enabled); super.setEnabled(enabled); } } /** * This is the action that adds a new command line option to the list of * assigned options. * * @author barbararosi-schwartz * */ private class AddOptionAction extends AbstractOptionAction { /** * The option that has been entered by the user or null if the user * cancelled the operation. */ private String newOption = null; private AddOptionAction(Button button) { super("Add...", button); setEnabled(true); } /** * Returns the option that was entered by the user. * * @return the option that was entered by the user (or null if the user * cancelled the operation) */ String getNewOption() { return newOption; } /** * Creates and displays an InputDialogWithWarning that collects the new * option entered by the user. The dialog is equipped with a * DialogInputValidator object that automatically performs validation on * the user's input. * <p> * When the dialog is dismissed, the action changes the model to reflect * the new addition. * </p> */ @Override public void run() { InputDialogWithWarning dialog = new InputDialogWithWarning(viewer.getControl().getShell(), "Add Option", "Please enter the required command-line option", "", new DialogInputValidator()); int result = dialog.open(); if (result == Window.CANCEL) { newOption = null; return; } else { newOption = dialog.getValue().trim(); java.util.List<String> model = Helper.toListOfStrings((String[]) viewer.getInput()); model.add(newOption); setAdvancedOptions(Helper.toArrayOfStrings(model)); } } /** * This action is always enabled. */ @Override public void selectionChanged(IStructuredSelection selection) { } } /** * This is the content provider for the list of assigned command line * options. * * @author barbararosi-schwartz */ private class AdvancedOptionsContentProvider implements IStructuredContentProvider { public void dispose() { } /* (non-Javadoc) * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ public Object[] getElements(Object inputElement) { if (!(inputElement instanceof String[])) { throw new IllegalArgumentException("Argument is not of type String[]."); } String[] items = (String[]) inputElement; return items; } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } /** * This is the label provider for the list of assigned command line options. * * @author barbararosi-schwartz */ private class AdvancedOptionsLabelProvider implements ILabelProvider { public void addListener(ILabelProviderListener listener) { } public void dispose() { } public Image getImage(Object element) { return null; } public String getText(Object element) { return element.toString(); } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { } } /** * This is the validator that is utilised by the InputDialogWithWarning * presented by the AddOptionAction. * * @author barbararosi-schwartz * */ private class DialogInputValidator implements IInputValidatorWithWarning { private java.util.List<String> listElements = new ArrayList<String>(); private DialogInputValidator() { listElements = Helper.toListOfStrings((String[]) viewer.getInput()); } /** * User input is invalid if: * <ol> * <li>input is not empty</li> * <li>input is already present in the list</li> * </ol> * * @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String) */ public String isValid(String newText) { if (newText.trim().length() == 0) { return ""; } if (listElements.contains(newText.trim())) { return "Option [" + newText + "] is already in the list."; } return null; } /** * User input generates a warning if it is one of the options contained * in the dangerousOptions list. * * @see com.symbian.smt.gui.smtwidgets.IInputValidatorWithWarning#isWarning(java.lang.String) */ public String isWarning(String newText) { if (dangerousOptions.contains(newText)) { return "Warning: option [" + newText + "] may cause the model build process to fail."; } return null; } } /** * This is the action that edits a command line option that already exists * in the list of assigned options. * * @author barbararosi-schwartz */ private class EditOptionAction extends AbstractOptionAction { private EditOptionAction(Button button) { super("Edit...", button); setEnabled(false); } /** * Creates and displays an InputDialogWithWarning, initialised with the * currently selected option. The dialog is equipped with a * DialogInputValidator object that automatically performs validation on * the user's input. * <p> * When the dialog is dismissed, the action changes the model to reflect * the option modification. * </p> */ @Override public void run() { String initialValue = (String) ((StructuredSelection) getSelection()).getFirstElement(); InputDialogWithWarning dialog = new InputDialogWithWarning(viewer.getControl().getShell(), "Add Option", "Please enter the required command-line option", initialValue, new DialogInputValidator()); int result = dialog.open(); String editedOption = null; if (result == Window.CANCEL) { return; } else { editedOption = dialog.getValue().trim(); java.util.List<String> model = Helper.toListOfStrings((String[]) viewer.getInput()); int index = model.indexOf(initialValue); model.set(index, editedOption); setAdvancedOptions(Helper.toArrayOfStrings(model)); } } /** * Enabled if we have exactly one selection in the list. */ @Override public void selectionChanged(IStructuredSelection selection) { if (selection.size() != 1) { setEnabled(false); return; } setEnabled(true); } } /** * This is the action that moves a command line option down by one position * in the list of assigned options. * * @author barbararosi-schwartz */ private class MoveOptionDownAction extends AbstractOptionAction { /** * The option that has been moved by the user */ private String movedOption = null; private MoveOptionDownAction(Button button) { super("Move Down", button); setEnabled(false); } /** * Returns the option that was moved by the user. * * @return the option that was moved by the user */ String getMovedOption() { return movedOption; } /** * Moves the selected option down by one position in the model. */ @Override public void run() { movedOption = (String) ((StructuredSelection) getSelection()).getFirstElement(); java.util.List<String> model = Helper.toListOfStrings((String[]) viewer.getInput()); int oldIndex = model.indexOf(movedOption); model.remove(oldIndex); int newIndex = oldIndex + 1; model.add(newIndex, movedOption); setAdvancedOptions(Helper.toArrayOfStrings(model)); } /** * Enabled if the list has exactly one selection and if the selection is * not the last element in the list. */ @Override public void selectionChanged(IStructuredSelection selection) { if (selection.size() != 1) { setEnabled(false); return; } boolean enabled = true; String selectedElement = (String) selection.getFirstElement(); String lastElement = (String) viewer.getElementAt(viewer.getList().getItemCount() - 1); if (lastElement != null && selectedElement.equals(lastElement)) { enabled = false; } setEnabled(enabled); } } /** * This is the action that moves a command line option up by one position in * the list of assigned options. * * @author barbararosi-schwartz */ private class MoveOptionUpAction extends AbstractOptionAction { /** * The option that has been moved by the user */ private String movedOption = null; private MoveOptionUpAction(Button button) { super("Move Up", button); setEnabled(false); } /** * Returns the option that was moved by the user. * * @return the option that was moved by the user */ String getMovedOption() { return movedOption; } /** * Moves the selected option down by one position in the model. */ @Override public void run() { movedOption = (String) ((StructuredSelection) getSelection()).getFirstElement(); java.util.List<String> model = Helper.toListOfStrings((String[]) viewer.getInput()); int oldIndex = model.indexOf(movedOption); model.remove(oldIndex); int newIndex = oldIndex - 1; model.add(newIndex, movedOption); setAdvancedOptions(Helper.toArrayOfStrings(model)); } /** * Enabled if the list has exactly one selection and if the selection is * not the first element in the list. */ @Override public void selectionChanged(IStructuredSelection selection) { if (selection.size() != 1) { setEnabled(false); return; } boolean enabled = true; String selectedElement = (String) selection.getFirstElement(); String firstElement = (String) viewer.getElementAt(0); if (firstElement != null && selectedElement.equals(firstElement)) { enabled = false; } setEnabled(enabled); } } /** * This is the action that removes a command line option from the list of * assigned options. * * @author barbararosi-schwartz */ private class RemoveOptionAction extends AbstractOptionAction { private RemoveOptionAction(Button button) { super("Remove", button); setEnabled(false); } /** * Removes the selected options from the model. */ @Override public void run() { StructuredSelection ssel = (StructuredSelection) getSelection(); java.util.List<String> model = Helper.toListOfStrings((String[]) viewer.getInput()); @SuppressWarnings("unchecked") Iterator<String> iter = ssel.iterator(); while (iter.hasNext()) { String to_be_removed = (String) iter.next(); model.remove(to_be_removed); } setAdvancedOptions(Helper.toArrayOfStrings(model)); } /** * Enabled if we have at least one selection in the list. */ @Override public void selectionChanged(IStructuredSelection selection) { if (selection.isEmpty()) { setEnabled(false); return; } setEnabled(true); } } /** * The List of all command line options that may override values entered * elsewhere. */ private static final ArrayList<String> dangerousOptions = new ArrayList<String>(); static { dangerousOptions.add("clean"); dangerousOptions.add("compress"); dangerousOptions.add("log"); dangerousOptions.add("model"); dangerousOptions.add("output"); dangerousOptions.add("tempdir"); } /** * The viewer associated with the List widget. */ private ListViewer viewer; /** * Creates an AdvancedOptionsWidget composite object * * @return void */ public AdvancedOptionsWidget(final Composite parent, int style) { super(parent, style); this.setLayout(new FillLayout()); // The Composite that contains all widgets final Composite gridLayoutComposite = new Composite(this, SWT.NONE); final GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; gridLayoutComposite.setLayout(gridLayout); final Label label = new Label(gridLayoutComposite, SWT.NONE); GridData gd = new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false, 2, 1); label.setText("Additional Command-Line Parameters"); label.setLayoutData(gd); // The List that contains all assigned command line options final List list = new List(gridLayoutComposite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI); gd = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1); gd.widthHint = 200; list.setLayoutData(gd); viewer = new ListViewer(list); viewer.setContentProvider(new AdvancedOptionsContentProvider()); viewer.setLabelProvider(new AdvancedOptionsLabelProvider()); // The Composite that contains all buttons in a vertical stack final Composite buttonsComposite = new Composite(gridLayoutComposite, SWT.NONE); final RowLayout rowLayout = new RowLayout(SWT.VERTICAL); rowLayout.spacing = 5; rowLayout.wrap = false; rowLayout.fill = true; buttonsComposite.setLayout(rowLayout); gd = new GridData(SWT.RIGHT, SWT.BEGINNING, false, true, 1, 1); buttonsComposite.setLayoutData(gd); // The "Add" button final Button addOptionButton = new Button(buttonsComposite, SWT.NONE); RowData rd = new RowData(); rd.width = 75; addOptionButton.setLayoutData(rd); // The action that backs the "Add" button final AddOptionAction addOptionAction = new AddOptionAction(addOptionButton); // When button is pressed, listener invokes the action's run() method, // then refresh // the List of assigned options and set the selection appropriately addOptionButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { addOptionAction.run(); StructuredSelection oldSel = (StructuredSelection) viewer.getSelection(); viewer.refresh(); String newOption = addOptionAction.getNewOption(); StructuredSelection newSel = (newOption == null) ? oldSel : new StructuredSelection(newOption); viewer.setSelection(newSel); } }); // The "Edit" button final Button editOptionButton = new Button(buttonsComposite, SWT.NONE); rd = new RowData(); rd.width = 75; editOptionButton.setLayoutData(rd); // The action that backs the "Edit" button final EditOptionAction editOptionAction = new EditOptionAction(editOptionButton); // When button is pressed, listener invokes the action's run() method, // then refresh // the List of assigned options and set the selection appropriately editOptionButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { editOptionAction.run(); StructuredSelection oldSel = (StructuredSelection) viewer.getSelection(); viewer.refresh(); viewer.setSelection(oldSel); } }); // The "Remove" button final Button removeOptionButton = new Button(buttonsComposite, SWT.NONE); rd = new RowData(); rd.width = 75; removeOptionButton.setLayoutData(rd); // The action that backs the "Remove" button final RemoveOptionAction removeOptionAction = new RemoveOptionAction(removeOptionButton); // When button is pressed, listener invokes the action's run() method, // then refreshes the List of assigned options and set the selection // appropriately removeOptionButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { removeOptionAction.run(); viewer.refresh(); // If the viewer has at least one element, we set the current // selection to that element. Object firstElement = viewer.getElementAt(0); StructuredSelection ssel = (firstElement == null) ? new StructuredSelection(StructuredSelection.EMPTY) : new StructuredSelection(firstElement); viewer.setSelection(ssel); } }); // The "Move Up" button final Button moveOptionUpButton = new Button(buttonsComposite, SWT.NONE); rd = new RowData(); rd.width = 75; moveOptionUpButton.setLayoutData(rd); // The action that backs the "Move Up" button final MoveOptionUpAction moveOptionUpAction = new MoveOptionUpAction(moveOptionUpButton); // When button is pressed, listener invokes the action's run() method, // then refreshes the List of assigned options and set the selection // appropriately moveOptionUpButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { moveOptionUpAction.run(); viewer.refresh(); StructuredSelection newSel = new StructuredSelection(moveOptionUpAction.getMovedOption()); viewer.setSelection(newSel); } }); // The "Move Down" button final Button moveOptionDownButton = new Button(buttonsComposite, SWT.NONE); rd = new RowData(); rd.width = 75; moveOptionDownButton.setLayoutData(rd); // The action that backs the "Move Down" button final MoveOptionDownAction moveOptionDownAction = new MoveOptionDownAction(moveOptionDownButton); // When button is pressed, listener invokes the action's run() method, // then refreshes the List of assigned options and set the selection // appropriately moveOptionDownButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { moveOptionDownAction.run(); viewer.refresh(); StructuredSelection newSel = new StructuredSelection(moveOptionDownAction.getMovedOption()); viewer.setSelection(newSel); } }); } /** * Returns the advanced options * * @return String[] */ public String[] getAdvancedOptions() { return (String[]) viewer.getInput(); } /** * Sets the advanced options * * @param options * A list containing advanced options. * @return void */ public void setAdvancedOptions(String[] options) { if (options != null) { viewer.setInput(options); } } }