/******************************************************************************* * Copyright (c) 2008, 2011 Thomas Holland (thomas@innot.de) 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: * Thomas Holland - initial API and implementation *******************************************************************************/ package de.innot.avreclipse.ui.editors.targets; import java.util.Arrays; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; 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.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.forms.widgets.TableWrapData; import org.eclipse.ui.forms.widgets.TableWrapLayout; import de.innot.avreclipse.core.avrdude.AVRDudeException; import de.innot.avreclipse.core.targets.ITargetConfiguration; import de.innot.avreclipse.core.targets.ITargetConfigurationTool; import de.innot.avreclipse.core.targets.ITargetConfiguration.ValidationResult; import de.innot.avreclipse.core.targets.tools.AvrdudeTool; /** * @author Thomas Holland * @since * */ public class SectionAvrdude extends AbstractTCSectionPart { private Text fCommandText; private Label fVersionLabel; private Combo fVerbosityCombo; private final static String[] VERBOSITY_NAMES = new String[] { "normal", "verbose", "very verbose", "extremly verbose" }; private final static String[] PART_ATTRS = new String[] { AvrdudeTool.ATTR_CMD_NAME, AvrdudeTool.ATTR_USE_CONSOLE, AvrdudeTool.ATTR_VERBOSITY }; private final static String[] PART_DEPENDS = new String[] {}; /* * (non-Javadoc) * @see de.innot.avreclipse.ui.editors.targets.AbstractTargetConfigurationEditorPart#getTitle() */ @Override protected String getTitle() { return "AVRDude Settings"; } /* * (non-Javadoc) * @see * de.innot.avreclipse.ui.editors.targets.AbstractTargetConfigurationEditorPart#getDescription() */ @Override protected String getDescription() { return null; } /* * (non-Javadoc) * @see * de.innot.avreclipse.ui.editors.targets.AbstractTargetConfigurationEditorPart#getPartAttributes * () */ @Override public String[] getPartAttributes() { return Arrays.copyOf(PART_ATTRS, PART_ATTRS.length); } /* * (non-Javadoc) * @seede.innot.avreclipse.ui.editors.targets.AbstractTargetConfigurationEditorPart# * getDependentAttributes() */ @Override protected String[] getDependentAttributes() { return Arrays.copyOf(PART_DEPENDS, PART_DEPENDS.length); } /* * (non-Javadoc) * @see * de.innot.avreclipse.ui.editors.targets.AbstractTCSectionPart#createSectionContent(org.eclipse * .swt.widgets.Composite, org.eclipse.ui.forms.widgets.FormToolkit) */ protected void createSectionContent(Composite parent, FormToolkit toolkit) { // Call the subclass to have it create its user interface stuff. TableWrapLayout layout = new TableWrapLayout(); layout.horizontalSpacing = 12; layout.numColumns = 3; parent.setLayout(layout); addCommandText(parent, toolkit); addVerbosityCombo(parent, toolkit); addAdvancedSection(parent, toolkit); } /* * (non-Javadoc) * @see de.innot.avreclipse.ui.editors.targets.AbstractTCSectionPart#refreshSectionContent() */ @Override protected void refreshSectionContent() { String command = getTargetConfiguration().getAttribute(AvrdudeTool.ATTR_CMD_NAME); fCommandText.setText(command); validateCommand(); int verbosity = getTargetConfiguration().getIntegerAttribute(AvrdudeTool.ATTR_VERBOSITY); fVerbosityCombo.select(verbosity); } /** * Add the port name settings controls to the parent. * <p> * This consists of a Label and a Text control. After creation the control is set to the current * port name. * </p> * <p> * The parent is expected to have a <code>TableWrapLayout</code> with 3 columns. * </p> * * @param parent * Composite to which the port name settings controls are added. * @param toolkit * FormToolkit to use for the new controls. */ private void addCommandText(Composite parent, FormToolkit toolkit) { // // The Label // Label label = toolkit.createLabel(parent, "Command:"); label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE)); // // The Text control // fCommandText = toolkit.createText(parent, ""); fCommandText .setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE)); fCommandText .setToolTipText("The command to start avrdude.\nIf the avrdude executable is not on the system path,\nthen the full path to the executable must be provided."); fCommandText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { String command = fCommandText.getText(); getTargetConfiguration().setAttribute(AvrdudeTool.ATTR_CMD_NAME, command); getManagedForm().dirtyStateChanged(); validateCommand(); } }); // // Browse file system button // Button filesystembutton = createFilesystemButton(toolkit, parent, fCommandText, new String[] { "", "exe" }); filesystembutton.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE)); // Placeholder to "eat" the column Label dummy = toolkit.createLabel(parent, ""); dummy.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP)); // // The Label for the discovered version // fVersionLabel = toolkit.createLabel(parent, "avrdude version"); fVersionLabel.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP, 1, 2)); } /** * Add the verbosity settings controls to the parent. * <p> * This consists of a Label and a Combo control. The combo has 5 levels from 'very quiet' to * 'very verbose'. After creation the control is set to the current verbosity level. * </p> * <p> * The parent is expected to have a <code>GridLayout</code> with 2 columns. * </p> * * @param parent * Composite to which the port name settings controls are added. * @param toolkit * FormToolkit to use for the new controls. */ private void addVerbosityCombo(Composite parent, FormToolkit toolkit) { // // The Label // Label label = toolkit.createLabel(parent, "Verbosity level:"); label.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE)); // // The Text control // fVerbosityCombo = new Combo(parent, SWT.READ_ONLY); toolkit.adapt(fVerbosityCombo); fVerbosityCombo.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE, 1, 2)); fVerbosityCombo.setItems(VERBOSITY_NAMES); fVerbosityCombo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { int newindex = fVerbosityCombo.getSelectionIndex(); getTargetConfiguration().setIntegerAttribute(AvrdudeTool.ATTR_VERBOSITY, newindex); getManagedForm().dirtyStateChanged(); } }); } /** * @param parent * @param toolkit */ private void addAdvancedSection(Composite parent, FormToolkit toolkit) { Section section = toolkit.createSection(parent, Section.SHORT_TITLE_BAR | Section.TWISTIE | Section.COMPACT); section.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.TOP, 1, 3)); section.setText("Advanced AVRDude settings"); } /** * Open a FileSystem Dialog and return the selected file as a <code>String</code>. * * @param shell * Shell in which to open the Dialog * @param text * Root file name * @param exts * <code>String[]</code> with all valid file extensions. Files with other extensions * will be filtered. * @return <code>String</code> with the selected filename or <cod>null</code> if the user has * canceled or an error occurred. */ public static String getFileSystemFileDialog(Shell shell, String text, String[] exts) { FileDialog dialog = new FileDialog(shell); dialog.setFilterPath(text); dialog.setFilterExtensions(exts); dialog.setText(""); return dialog.open(); } /** * Create and return a "Filesystem" browse Button. * <p> * Clicking the Button will open a file selector Dialog and the result is copied to the supplied * <code>Text</code> Control. * </p> * * @param toolkit * The form toolkit to use for creating the button. * @param parent * Parent <code>Composite</code>, which needs to have <code>GridLayout</code> * @param text * Target <code>Text</code> Control * @param exts * <code>String[]</code> with all valid file extensions. Files with other extensions * will be filtered. * @return <code>Button</code> Control with the created Button. */ protected Button createFilesystemButton(FormToolkit toolkit, Composite parent, final Text text, String[] exts) { Button button = toolkit.createButton(parent, "Browse...", SWT.PUSH); button.setData(exts); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { String[] exts = (String[]) event.widget.getData(); String lastlocation = text.getText(); IPath lastlocpath = new Path(lastlocation); String location = getFileSystemFileDialog(text.getShell(), lastlocpath.isAbsolute() ? lastlocation : Path.ROOT.toOSString(), exts); if (location != null) { text.setText(location); } } }); return button; } /** * Create and return a "Search" Button. * <p> * Clicking the Button will search the file system for avrdude and the result is copied to the * supplied <code>Text</code> Control. * </p> * * @param toolkit * The form toolkit to use for creating the button. * @param parent * Parent <code>Composite</code>, which needs to have <code>GridLayout</code> * @param text * Target <code>Text</code> Control * @return <code>Button</code> Control with the created Button. */ protected Button createSearchButton(FormToolkit toolkit, Composite parent, final Text text) { Button button = toolkit.createButton(parent, "Search", SWT.PUSH); button.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { // TODO: Implement search for avrdude } }); return button; } /** * Check if the given command name is valid by fetching its version. */ private void validateCommand() { validate(AvrdudeTool.ATTR_CMD_NAME, fCommandText, fCVL); } private final CommandValidationListener fCVL = new SectionAvrdude.CommandValidationListener(); private class CommandValidationListener implements IValidationListener { public void result(ValidationResult result) { switch (result.result) { case OK: try { ITargetConfiguration tc = getTargetConfiguration(); ITargetConfigurationTool tool = tc.getProgrammerTool(); String version = tool.getVersion(); fVersionLabel.setText(" Version: " + version); } catch (AVRDudeException e) { // This should not happen because the command has been validated 'OK' fVersionLabel.setText(""); } break; default: fVersionLabel.setText(""); } } } }