sysmodelmgr/com.symbian.smt.gui/src/com/symbian/smt/gui/smtwidgets/AdvancedOptionsWidget.java
changeset 0 522a326673b6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysmodelmgr/com.symbian.smt.gui/src/com/symbian/smt/gui/smtwidgets/AdvancedOptionsWidget.java	Thu Mar 11 19:08:43 2010 +0200
@@ -0,0 +1,783 @@
+// 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);
+		}
+	}
+
+}
\ No newline at end of file