/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.motorola.studio.android.wizards.monkey; import java.util.List; import org.eclipse.core.runtime.Status; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Text; import com.motorola.studio.android.i18n.AndroidNLS; import com.motorola.studio.android.monkey.options.IMonkeyOptionsConstants; import com.motorola.studio.android.monkey.options.MonkeyOption; import com.motorola.studio.android.monkey.options.MonkeyOptionsGroup; import com.motorola.studio.android.monkey.options.MonkeyOptionsMgt; /** * DESCRIPTION: * <br> * This class implements the UI for showing all monkey options information. * <br> * It extends the AbstractPropertiesComposite so as to use its common functionalities. * <br> * RESPONSIBILITY: * <br> * - Show monkey information on the UI * <br> * COLABORATORS: * <br> * AbstractPropertiesComposite: extends this class * <br> * USAGE: * <br> * This class should be added as a regular composite whenever monkey options information is necessary to be shown and edited on the UI. */ public class MonkeyOptionsComposite extends AbstractPropertiesComposite implements IMonkeyOptionsConstants { // The widget which displays the current command line used to pass the monkey options private Text commandLine; private final int TABFOLDER_HEIGHT_HINT = 290; /** * Creates a MonkeyOptionsComposite object. * * @param parent the parent composite */ public MonkeyOptionsComposite(Composite parent, String monkeyOptions) { super(parent); MonkeyOptionsMgt.loadFromCommandLine(monkeyOptions); createUI(); // Set context Help // PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, // IAndroidDeviceConstants.STARTUP_OPTIONS_HELP); } /** * Create widgets for monkey options */ private void createUI() { Composite mainComposite = this; Layout mainLayout = new GridLayout(); mainComposite.setLayout(mainLayout); // list of monkey options groups List<MonkeyOptionsGroup> monkeyOptionsGroupsList = MonkeyOptionsMgt.getMonkeyOptionsGroupsList(); // list of monkey options in each group List<MonkeyOption> monkeyOptions = null; // Create Tab Folder final TabFolder tabFolder = new TabFolder(mainComposite, SWT.NULL); GridData data = new GridData(SWT.FILL, SWT.FILL, true, false); data.heightHint = TABFOLDER_HEIGHT_HINT; tabFolder.setLayoutData(data); /* * Iterate through Monkey Groups */ for (MonkeyOptionsGroup monkeyOptionGroup : monkeyOptionsGroupsList) { // Create Tab Item TabItem tabItem = new TabItem(tabFolder, SWT.NULL); tabItem.setText(monkeyOptionGroup.getTitle()); Composite group = new Composite(tabFolder, SWT.NULL); group.setLayout(new GridLayout(3, false)); group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); tabItem.setControl(group); // get monkey options in this group monkeyOptions = monkeyOptionGroup.getMonkeyOptions(); /* * Iterate through Monkey Options in this group */ for (final MonkeyOption monkeyOption : monkeyOptions) { // create a checkbox for each monkey option Button checkbox = new Button(group, SWT.CHECK); checkbox.setSelection(monkeyOption.isChecked()); checkbox.setText(monkeyOption.getUserFriendlyName()); checkbox.setToolTipText(monkeyOption.getName() + ": " + monkeyOption.getDescription()); monkeyOption.setCheckedWidget(checkbox); checkbox.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { boolean checkedStatus = ((Button) e.widget).getSelection(); monkeyOption.setChecked(checkedStatus); notifyCompositeChangeListeners(); } }); GridData checkboxData = new GridData(SWT.NULL, SWT.FILL, false, false); checkbox.setLayoutData(checkboxData); // Create input fields depending on the monkey option type switch (monkeyOption.getType()) { case TYPE_NONE: // extend checkbox area along the line checkboxData.widthHint = SWT.DEFAULT; checkboxData.horizontalSpan = 3; checkbox.setLayoutData(checkboxData); break; case TYPE_TEXT: case TYPE_NUMBER: createWidgetsForTextOrNumberType(group, monkeyOption); break; case TYPE_PATH: createWidgetsForPathType(group, monkeyOption); break; default: // none } } } /* * Command Line area */ Composite commandLineArea = new Composite(mainComposite, SWT.NONE); // composite commandLineArea.setLayout(new GridLayout(2, false)); data = new GridData(SWT.FILL, SWT.FILL, true, true); commandLineArea.setLayoutData(data); Label commandLineLabel = new Label(commandLineArea, SWT.NONE); // label commandLineLabel.setText(AndroidNLS.UI_MonkeyOptions_CommandLine); data = new GridData(SWT.FILL, SWT.FILL, false, true); commandLineLabel.setLayoutData(data); commandLine = new Text(commandLineArea, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL); // text data = new GridData(SWT.FILL, SWT.FILL, true, true); commandLineArea.pack(); data.widthHint = commandLineArea.getBounds().width - commandLineLabel.getBounds().width; data.heightHint = commandLineArea.getBounds().height; commandLine.setLayoutData(data); commandLine.setText(MonkeyOptionsMgt.getParamList()); commandLine.setEditable(false); } /** * Create widgets to enable user to input data for fields of text or number type * * @param parent composite where the widgets will be attached to * @param monkeyOption the corresponding monkey option */ private void createWidgetsForTextOrNumberType(final Composite parent, final MonkeyOption monkeyOption) { // create input text if ((monkeyOption.getPreDefinedValues() == null) || (monkeyOption.getPreDefinedValues().size() == 0)) { final Text inputText = new Text(parent, SWT.SINGLE | SWT.BORDER); inputText.setText(monkeyOption.getValue()); monkeyOption.setValueWidget(inputText); inputText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); inputText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { monkeyOption.setValue(inputText.getText()); notifyCompositeChangeListeners(); } }); } // create combobox else { final Combo combo = new Combo(parent, SWT.READ_ONLY); monkeyOption.setValueWidget(combo); int selectedIndex = 0; for (String preDefinedValue : monkeyOption.getPreDefinedValues()) { combo.add(preDefinedValue); if (monkeyOption.getValue().equals(preDefinedValue)) { combo.select(selectedIndex); } else { selectedIndex++; } } combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); combo.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { monkeyOption.setValue(combo.getText()); notifyCompositeChangeListeners(); } }); } } /** * Create widgets to enable user to input data for fields of path type * * @param parent composite where the widgets will be attached to * @param monkeyOption the corresponding monkey option */ private void createWidgetsForPathType(final Composite parent, final MonkeyOption monkeyOption) { // create input text final Text pathText = new Text(parent, SWT.SINGLE | SWT.BORDER); pathText.setText(monkeyOption.getValue()); monkeyOption.setValueWidget(pathText); pathText.setLayoutData(new GridData(SWT.FILL, SWT.NULL, true, false)); pathText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { monkeyOption.setValue(pathText.getText()); notifyCompositeChangeListeners(); } }); // create browse button Button pathBrowseButton = new Button(parent, SWT.PUSH); pathBrowseButton.setText(AndroidNLS.UI_General_BrowseButtonLabel); GridData data = new GridData(SWT.NULL, SWT.NULL, false, false); pathBrowseButton.setLayoutData(data); pathBrowseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String selectedPath = null; if (monkeyOption.getTypeDetails().equals(TYPE_PATH_DIR)) { DirectoryDialog directoryDialog = new DirectoryDialog(getShell(), SWT.OPEN); selectedPath = directoryDialog.open(); } else { FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN); String[] filterExtensions = { "*" + monkeyOption.getTypeDetails() }; fileDialog.setFilterExtensions(filterExtensions); selectedPath = fileDialog.open(); } if (selectedPath != null) { pathText.setText(selectedPath); } } }); } /** * Update command line value * * @see com.motorola.studio.android.emulator.device.ui.AbstractPropertiesComposite#notifyCompositeChangeListeners() */ @Override protected void notifyCompositeChangeListeners() { commandLine.setText(MonkeyOptionsMgt.getParamList()); super.notifyCompositeChangeListeners(); } /** * Retrieves the error message associated to this composites current state. * The order of precedence of error is the same as the fields displayed on the * UI, which means errors on fields drawn first are shown with a higher precedence * than the errors of fields drawn last. * The instance description field is the only non required field. * * @return the error message, or <code>null</code> if there are no errors */ @Override public String getErrorMessage() { String errMsg = null; Status status = MonkeyOptionsMgt.validate(); if (status.getSeverity() == Status.ERROR) { errMsg = status.getMessage(); } return errMsg; } /** * Reload the values being displayed in the UI as well as the ones * in the model. * * @param monkeyOptions commandLine the command line used to start the emulator */ public void reloadValues(String commandLine) { MonkeyOptionsMgt.loadFromCommandLine(commandLine); } }