/*******************************************************************************
* 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 java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
import de.innot.avreclipse.core.targets.HostInterface;
import de.innot.avreclipse.core.targets.IProgrammer;
import de.innot.avreclipse.core.targets.ITargetConfigConstants;
import de.innot.avreclipse.core.targets.ITargetConfigurationWorkingCopy;
/**
* @author Thomas Holland
* @since 2.4
*
*/
public class SectionProgrammer extends AbstractTCSectionPart implements ITargetConfigConstants {
private Combo fProgrammersCombo;
private Combo fHostPortCombo;
/** Reverse mapping of programmer description to id. */
final private Map<String, String> fMapDescToId = new HashMap<String, String>();
/** Reverse mapping of host interface description to host interface. */
final private Map<String, HostInterface> fMapDescToHostPort = new HashMap<String, HostInterface>();
private final static String[] PART_ATTRS = new String[] {
ATTR_PROGRAMMER_ID, ATTR_HOSTINTERFACE };
private final static String[] PART_DEPENDS = new String[] {
ATTR_PROGRAMMER_TOOL_ID, ATTR_GDBSERVER_ID };
/*
* (non-Javadoc)
* @see de.innot.avreclipse.ui.editors.targets.AbstractTargetConfigurationEditorPart#getTitle()
*/
@Override
protected String getTitle() {
return "Programmer Hardware / Interface";
}
/*
* (non-Javadoc)
* @see
* de.innot.avreclipse.ui.editors.targets.AbstractTargetConfigurationEditorPart#getDescription()
*/
@Override
protected String getDescription() {
return null; // TODO: add a description
}
/*
* (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 org.eclipse.ui.forms.AbstractFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
*/
@Override
public void createSectionContent(Composite parent, FormToolkit toolkit) {
TableWrapLayout layout = new TableWrapLayout();
layout.numColumns = 2;
layout.horizontalSpacing = 12;
parent.setLayout(layout);
//
// The Programmers Combo
//
Label label = toolkit.createLabel(parent, "Programmer:");
label.setLayoutData(new TableWrapData(TableWrapData.FILL, TableWrapData.MIDDLE));
fProgrammersCombo = new Combo(parent, SWT.READ_ONLY);
toolkit.adapt(fProgrammersCombo, true, true);
fProgrammersCombo.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP));
fProgrammersCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
ITargetConfigurationWorkingCopy tcwc = getTargetConfiguration();
String description = fProgrammersCombo.getText();
String id = fMapDescToId.get(description);
IProgrammer programmer = tcwc.getProgrammer(id);
tcwc.setAttribute(ATTR_PROGRAMMER_ID, id);
fProgrammersCombo.setToolTipText(programmer.getAdditionalInfo());
updateHostInterfaceCombo(programmer);
getManagedForm().dirtyStateChanged();
}
});
//
// The host port selector combo
//
label = toolkit.createLabel(parent, "Host interface:");
label.setLayoutData(new TableWrapData(TableWrapData.FILL, TableWrapData.MIDDLE));
fHostPortCombo = new Combo(parent, SWT.READ_ONLY);
toolkit.adapt(fHostPortCombo, true, true);
fHostPortCombo.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.TOP));
fHostPortCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
String description = fHostPortCombo.getText();
HostInterface hi = fMapDescToHostPort.get(description);
getTargetConfiguration().setAttribute(ATTR_HOSTINTERFACE, hi.name());
// Ensure that the HostPortCombo is still visible after the layout reflow caused
// by the new layout
IManagedForm form = getManagedForm();
form.getForm().showControl(fProgrammersCombo);
form.dirtyStateChanged();
}
});
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.forms.AbstractFormPart#refresh()
*/
@Override
public void refreshSectionContent() {
// Get the list of valid Programmers and fill the description -> id map
fMapDescToId.clear();
Set<String> allprogrammers = getTargetConfiguration().getAllProgrammers(true);
for (String id : allprogrammers) {
IProgrammer progger = getTargetConfiguration().getProgrammer(id);
String description = progger.getDescription();
fMapDescToId.put(description, id);
}
// Check if the currently selected programmer is still in the list
String currentprogrammerid = getTargetConfiguration().getAttribute(ATTR_PROGRAMMER_ID);
if (!fMapDescToId.containsValue(currentprogrammerid)) {
// No -- The Programmer is not supported by the current config.
// Add the current programmer back to the list.
// This prevents the combo from becoming empty at the cost of one
// 'invalid' programmer in the list
IProgrammer currentprogrammer = getTargetConfiguration().getProgrammer(
currentprogrammerid);
fMapDescToId.put(currentprogrammer.getDescription(), currentprogrammerid);
}
// Get all descriptions and sort them alphabetically
Set<String> descset = fMapDescToId.keySet();
String[] alldescs = descset.toArray(new String[descset.size()]);
Arrays.sort(alldescs, new Comparator<String>() {
// Custom Comparator to ignore upper/lower case
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);
}
});
// Tell the fProgrammersCombo about the new list but keep the previously selected
// Programmer
fProgrammersCombo.setItems(alldescs);
fProgrammersCombo.setVisibleItemCount(Math.min(alldescs.length, 25));
IProgrammer currentprogrammer = getTargetConfiguration().getProgrammer(currentprogrammerid);
fProgrammersCombo.setText(currentprogrammer.getDescription());
fProgrammersCombo.setToolTipText(currentprogrammer.getAdditionalInfo());
// Now set the host interface
updateHostInterfaceCombo(currentprogrammer);
// Finally show an error if the Programmer is not supported by either tool.
refreshMessages();
}
/*
* (non-Javadoc)
* @see de.innot.avreclipse.ui.editors.targets.AbstractTCSectionPart#refreshMessages()
*/
@Override
protected void refreshMessages() {
validate(ATTR_PROGRAMMER_ID, fProgrammersCombo);
}
/**
* @param programmer
*/
private void updateHostInterfaceCombo(IProgrammer programmer) {
HostInterface[] availableHIs = programmer.getHostInterfaces();
// update the combo to only show available interfaces
fMapDescToHostPort.clear();
for (HostInterface hi : availableHIs) {
fMapDescToHostPort.put(hi.toString(), hi);
}
String[] allhostinterfaces = fMapDescToHostPort.keySet().toArray(
new String[fMapDescToHostPort.size()]);
fHostPortCombo.setItems(allhostinterfaces);
fHostPortCombo.setEnabled(allhostinterfaces.length > 1);
// Check if the currently selected port is still valid
String currentHI = getTargetConfiguration().getAttribute(ATTR_HOSTINTERFACE);
for (HostInterface hi : availableHIs) {
if (hi.name().equals(currentHI)) {
// The set port is valid. Just set the name and be done
fHostPortCombo.setText(hi.toString());
return;
}
}
// The selected programmer uses a different host interface.
// Update the combo and the target configuration
HostInterface newHI = availableHIs[0];
fHostPortCombo.setText(newHI.toString());
getTargetConfiguration().setAttribute(ATTR_HOSTINTERFACE, newHI.name());
}
}