abstract contiki compile dialog using compile library.
to be implemented by msp mote type
This commit is contained in:
parent
37586984f6
commit
217d8cf0b3
1 changed files with 666 additions and 0 deletions
|
@ -0,0 +1,666 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: AbstractCompileDialog.java,v 1.1 2009/03/09 13:58:12 fros4943 Exp $
|
||||
*/
|
||||
|
||||
package se.sics.cooja.dialogs;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import se.sics.cooja.*;
|
||||
import se.sics.cooja.dialogs.MessageList;
|
||||
|
||||
/**
|
||||
* Abstract configure mote type dialog used by Contiki-based mote type implementations.
|
||||
*
|
||||
* The dialog uses tabs for configuring the mote type.
|
||||
* Three tabs are provided: compile commands, mote interfaces, and compilation output.
|
||||
*
|
||||
* In addition, the dialog implementation can provide additional tabs.
|
||||
*
|
||||
* @see #tabbedPane
|
||||
* @see ContikiMoteCompileDialog
|
||||
*
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
public abstract class AbstractCompileDialog extends JDialog {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static Logger logger = Logger.getLogger(AbstractCompileDialog.class);
|
||||
|
||||
protected final static Dimension LABEL_DIMENSION = new Dimension(170, 15);
|
||||
|
||||
private static File lastFile = null;
|
||||
|
||||
public static enum DialogState {
|
||||
NO_SELECTION,
|
||||
SELECTED_SOURCE, AWAITING_COMPILATION, IS_COMPILING, COMPILED_FIRMWARE,
|
||||
SELECTED_FIRMWARE,
|
||||
}
|
||||
|
||||
protected Simulation simulation;
|
||||
protected GUI gui;
|
||||
|
||||
protected JTabbedPane tabbedPane;
|
||||
protected Box moteIntfBox;
|
||||
|
||||
private JTextField contikiField;
|
||||
private JTextField descriptionField;
|
||||
private JTextArea commandsArea;
|
||||
private JButton nextButton;
|
||||
|
||||
private Component currentCompilationOutput = null;
|
||||
private Process currentCompilationProcess = null;
|
||||
|
||||
/* Accessible at Contiki compilation success */
|
||||
public File contikiSource = null;
|
||||
public File contikiFirmware = null;
|
||||
|
||||
public AbstractCompileDialog(Container parent, Simulation simulation, final MoteType moteType) {
|
||||
super(
|
||||
parent instanceof Dialog?(Dialog)parent:
|
||||
parent instanceof Window?(Window)parent:
|
||||
(Frame)parent, "Create Mote Type: Compile Contiki", ModalityType.APPLICATION_MODAL);
|
||||
|
||||
this.simulation = simulation;
|
||||
this.gui = simulation.getGUI();
|
||||
|
||||
JPanel mainPanel = new JPanel(new BorderLayout());
|
||||
JLabel label;
|
||||
|
||||
/* Top: Contiki source */
|
||||
JPanel topPanel = new JPanel();
|
||||
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
|
||||
topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
|
||||
Box descriptionBox = Box.createHorizontalBox();
|
||||
label = new JLabel("Description:");
|
||||
label.setPreferredSize(LABEL_DIMENSION);
|
||||
descriptionBox.add(label);
|
||||
descriptionField = new JTextField(40);
|
||||
descriptionField.setText("[enter mote type description]");
|
||||
descriptionBox.add(descriptionField);
|
||||
|
||||
topPanel.add(descriptionBox);
|
||||
|
||||
JPanel sourcePanel = new JPanel();
|
||||
sourcePanel.setLayout(new BoxLayout(sourcePanel, BoxLayout.X_AXIS));
|
||||
label = new JLabel("Contiki process / Firmware:");
|
||||
label.setPreferredSize(LABEL_DIMENSION);
|
||||
sourcePanel.add(label);
|
||||
contikiField = new JTextField(40);
|
||||
final Runnable selectedContikiFile = new Runnable() {
|
||||
public void run() {
|
||||
setContikiSelection(new File(contikiField.getText()));
|
||||
}
|
||||
};
|
||||
DocumentListener contikiFieldListener = new DocumentListener() {
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
SwingUtilities.invokeLater(selectedContikiFile);
|
||||
}
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
SwingUtilities.invokeLater(selectedContikiFile);
|
||||
}
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
SwingUtilities.invokeLater(selectedContikiFile);
|
||||
}
|
||||
};
|
||||
sourcePanel.add(contikiField);
|
||||
JButton browseButton = new JButton("Browse");
|
||||
browseButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
|
||||
/* Last file/directory */
|
||||
if (lastFile != null) {
|
||||
if (lastFile.isDirectory()) {
|
||||
fc.setCurrentDirectory(lastFile);
|
||||
} else if (lastFile.isFile() && lastFile.exists()) {
|
||||
fc.setCurrentDirectory(lastFile.getParentFile());
|
||||
fc.setSelectedFile(lastFile);
|
||||
} else if (lastFile.isFile() && !lastFile.exists()) {
|
||||
fc.setCurrentDirectory(lastFile.getParentFile());
|
||||
}
|
||||
} else {
|
||||
File helloworldSourceFile =
|
||||
new java.io.File(
|
||||
GUI.getExternalToolsSetting("PATH_CONTIKI"), "examples/hello-world/hello-world.c");
|
||||
try {
|
||||
helloworldSourceFile = helloworldSourceFile.getCanonicalFile();
|
||||
fc.setCurrentDirectory(helloworldSourceFile.getParentFile());
|
||||
fc.setSelectedFile(helloworldSourceFile);
|
||||
} catch (IOException e1) {
|
||||
}
|
||||
}
|
||||
|
||||
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
fc.addChoosableFileFilter(new FileFilter() {
|
||||
public boolean accept(File f) {
|
||||
if (f.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String filename = f.getName();
|
||||
if (filename == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filename.endsWith(".c")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (canLoadFirmware(f)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return "Contiki process source or Contiki firmware";
|
||||
}
|
||||
});
|
||||
fc.setDialogTitle("Select Contiki process source");
|
||||
|
||||
if (fc.showOpenDialog(AbstractCompileDialog.this) == JFileChooser.APPROVE_OPTION) {
|
||||
contikiField.setText(fc.getSelectedFile().getAbsolutePath());
|
||||
}
|
||||
}
|
||||
});
|
||||
sourcePanel.add(browseButton);
|
||||
|
||||
topPanel.add(sourcePanel);
|
||||
|
||||
nextButton = new JButton("NEXT");
|
||||
nextButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (nextButton.getText().equals("Compile")) {
|
||||
compileContiki();
|
||||
} else if (nextButton.getText().equals("Create")) {
|
||||
/* Write mote type settings (generic) */
|
||||
moteType.setDescription(descriptionField.getText());
|
||||
moteType.setContikiSourceFile(contikiSource);
|
||||
moteType.setContikiFirmwareFile(contikiFirmware);
|
||||
moteType.setMoteInterfaceClasses(getSelectedMoteInterfaceClasses());
|
||||
moteType.setCompileCommands(getCompileCommands());
|
||||
|
||||
/* Write mote type settings (mote type specific) */
|
||||
writeSettingsToMoteType();
|
||||
|
||||
AbstractCompileDialog.this.dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
getRootPane().setDefaultButton(nextButton);
|
||||
|
||||
Box buttonPanel = Box.createHorizontalBox();
|
||||
buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
|
||||
buttonPanel.add(Box.createHorizontalGlue());
|
||||
buttonPanel.add(new JLabel("Next:"));
|
||||
buttonPanel.add(Box.createHorizontalStrut(5));
|
||||
buttonPanel.add(nextButton);
|
||||
buttonPanel.setAlignmentX(LEFT_ALIGNMENT);
|
||||
|
||||
topPanel.add(buttonPanel);
|
||||
|
||||
/* Center: Tabs showing configuration, compilation output, ... */
|
||||
tabbedPane = new JTabbedPane();
|
||||
addCompileCommandTab(tabbedPane);
|
||||
addMoteInterfacesTab(tabbedPane);
|
||||
|
||||
/* Build panel */
|
||||
mainPanel.add(BorderLayout.NORTH, topPanel);
|
||||
mainPanel.add(BorderLayout.CENTER, tabbedPane);
|
||||
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
setContentPane(mainPanel);
|
||||
|
||||
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
|
||||
addWindowListener(new WindowListener() {
|
||||
public void windowDeactivated(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowIconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowDeiconified(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowOpened(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowClosed(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowActivated(WindowEvent e) {
|
||||
}
|
||||
|
||||
public void windowClosing(WindowEvent e) {
|
||||
abortAnyCompilation();
|
||||
contikiSource = null;
|
||||
contikiFirmware = null;
|
||||
AbstractCompileDialog.this.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
setDialogState(DialogState.NO_SELECTION);
|
||||
descriptionField.requestFocus();
|
||||
descriptionField.select(0, descriptionField.getText().length());
|
||||
|
||||
/* Restore old configuration if mote type is already configured */
|
||||
if (moteType != null) {
|
||||
/* Restore description */
|
||||
if (moteType.getDescription() != null) {
|
||||
descriptionField.setText(moteType.getDescription());
|
||||
}
|
||||
|
||||
/* Restore Contiki source or firmware */
|
||||
if (moteType.getContikiSourceFile() != null) {
|
||||
contikiField.setText(moteType.getContikiSourceFile().getAbsolutePath());
|
||||
setDialogState(DialogState.SELECTED_SOURCE);
|
||||
} else if (moteType.getContikiFirmwareFile() != null) {
|
||||
contikiField.setText(moteType.getContikiFirmwareFile().getAbsolutePath());
|
||||
setDialogState(DialogState.SELECTED_FIRMWARE);
|
||||
}
|
||||
|
||||
/* Restore mote interface classes */
|
||||
if (moteType.getMoteInterfaceClasses() != null) {
|
||||
for (Class<? extends MoteInterface> intf: moteType.getMoteInterfaceClasses()) {
|
||||
addMoteInterface(intf, true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore compile commands */
|
||||
if (moteType.getCompileCommands() != null) {
|
||||
setCompileCommands(moteType.getCompileCommands());
|
||||
setDialogState(DialogState.AWAITING_COMPILATION);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add listener only after restoring old config */
|
||||
contikiField.getDocument().addDocumentListener(contikiFieldListener);
|
||||
|
||||
/* Final touches: respect window size, focus on description etc */
|
||||
Rectangle maxSize = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
|
||||
if (maxSize != null &&
|
||||
(getSize().getWidth() > maxSize.getWidth() || getSize().getHeight() > maxSize.getHeight())) {
|
||||
Dimension newSize = new Dimension();
|
||||
newSize.height = Math.min((int) maxSize.getHeight(), (int) getSize().getHeight());
|
||||
newSize.width = Math.min((int) maxSize.getWidth(), (int) getSize().getWidth());
|
||||
/*logger.info("Resizing dialog: " + myDialog.getSize() + " -> " + newSize);*/
|
||||
setSize(newSize);
|
||||
}
|
||||
|
||||
pack();
|
||||
setLocationRelativeTo(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Mote type was created without errors
|
||||
*/
|
||||
public boolean createdOK() {
|
||||
if (contikiFirmware == null) {
|
||||
return false;
|
||||
}
|
||||
if (!contikiFirmware.exists()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when user is closing the dialog.
|
||||
* Should immediately write mote type specific settings
|
||||
* to the current mote type.
|
||||
*
|
||||
* Note that generic mote type settings are already written,
|
||||
* such as description, Contiki source, compile commands, and mote interfaces.
|
||||
*/
|
||||
public abstract void writeSettingsToMoteType();
|
||||
|
||||
public abstract boolean canLoadFirmware(File file);
|
||||
|
||||
private void compileContiki() {
|
||||
final MessageList taskOutput = new MessageList();
|
||||
|
||||
/* Handle multiple compilation commands one by one */
|
||||
final ArrayList<String> commands = new ArrayList<String>();
|
||||
String[] arr = getCompileCommands().split("\n");
|
||||
for (String cmd: arr) {
|
||||
commands.add(cmd);
|
||||
}
|
||||
|
||||
setDialogState(DialogState.IS_COMPILING);
|
||||
createNewCompilationTab(taskOutput);
|
||||
|
||||
/* Add abort compilation menu item */
|
||||
final JMenuItem abortMenuItem = new JMenuItem("Abort compilation");
|
||||
abortMenuItem.setEnabled(true);
|
||||
abortMenuItem.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
abortAnyCompilation();
|
||||
}
|
||||
});
|
||||
taskOutput.addPopupMenuItem(abortMenuItem, true);
|
||||
|
||||
/* Called when last command has finished (success only) */
|
||||
final Action compilationSuccessAction = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
abortMenuItem.setEnabled(false);
|
||||
setDialogState(DialogState.COMPILED_FIRMWARE);
|
||||
}
|
||||
};
|
||||
|
||||
/* Called immediately if any command fails */
|
||||
final Action compilationFailureAction = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
abortMenuItem.setEnabled(false);
|
||||
setDialogState(DialogState.AWAITING_COMPILATION);
|
||||
}
|
||||
};
|
||||
|
||||
/* Called once per command */
|
||||
final Action nextCommandAction = new AbstractAction() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Action nextSuccessAction;
|
||||
if (commands.size() == 1) {
|
||||
nextSuccessAction = compilationSuccessAction;
|
||||
} else {
|
||||
nextSuccessAction = this;
|
||||
}
|
||||
|
||||
String command = commands.remove(0);
|
||||
if (command.trim().isEmpty()) {
|
||||
nextSuccessAction.actionPerformed(null);
|
||||
} else {
|
||||
try {
|
||||
currentCompilationProcess = CompileContiki.compile(
|
||||
command,
|
||||
null,
|
||||
new File(contikiField.getText()).getParentFile(),
|
||||
nextSuccessAction,
|
||||
compilationFailureAction,
|
||||
taskOutput,
|
||||
false
|
||||
);
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("Exception when compiling: " + ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
compilationFailureAction.actionPerformed(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
nextCommandAction.actionPerformed(null); /* Recursive calls for all commands */
|
||||
}
|
||||
|
||||
private void setContikiSelection(File file) {
|
||||
if (!file.exists()) {
|
||||
setDialogState(DialogState.NO_SELECTION);
|
||||
return;
|
||||
}
|
||||
|
||||
lastFile = file;
|
||||
if (file.getName().endsWith(".c")) {
|
||||
setDialogState(DialogState.SELECTED_SOURCE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (canLoadFirmware(file)) {
|
||||
setDialogState(DialogState.SELECTED_FIRMWARE);
|
||||
return;
|
||||
}
|
||||
|
||||
setDialogState(DialogState.SELECTED_SOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DialogState
|
||||
* @param dialogState New dialog state
|
||||
*/
|
||||
public void setDialogState(DialogState dialogState) {
|
||||
switch (dialogState) {
|
||||
case NO_SELECTION:
|
||||
nextButton.setText("Compile");
|
||||
nextButton.setEnabled(false);
|
||||
commandsArea.setEnabled(false);
|
||||
commandsArea.setText("");
|
||||
break;
|
||||
|
||||
case SELECTED_SOURCE:
|
||||
File sourceFile = new File(contikiField.getText());
|
||||
if (!sourceFile.exists()) {
|
||||
setDialogState(DialogState.NO_SELECTION);
|
||||
return;
|
||||
}
|
||||
if (!sourceFile.getName().endsWith(".c")) {
|
||||
setDialogState(DialogState.NO_SELECTION);
|
||||
return;
|
||||
}
|
||||
|
||||
nextButton.setText("Compile");
|
||||
nextButton.setEnabled(true);
|
||||
commandsArea.setEnabled(true);
|
||||
setCompileCommands(getDefaultCompileCommands(sourceFile));
|
||||
contikiFirmware = getExpectedFirmwareFile(sourceFile);
|
||||
contikiSource = sourceFile;
|
||||
setDialogState(DialogState.AWAITING_COMPILATION);
|
||||
break;
|
||||
|
||||
case AWAITING_COMPILATION:
|
||||
nextButton.setText("Compile");
|
||||
nextButton.setEnabled(true);
|
||||
commandsArea.setEnabled(true);
|
||||
break;
|
||||
|
||||
case IS_COMPILING:
|
||||
nextButton.setText("Compiling");
|
||||
nextButton.setEnabled(false);
|
||||
commandsArea.setEnabled(false);
|
||||
break;
|
||||
|
||||
case COMPILED_FIRMWARE:
|
||||
nextButton.setText("Create");
|
||||
nextButton.setEnabled(true);
|
||||
commandsArea.setEnabled(true);
|
||||
break;
|
||||
|
||||
case SELECTED_FIRMWARE:
|
||||
contikiFirmware = new File(contikiField.getText());
|
||||
if (!contikiFirmware.exists()) {
|
||||
setDialogState(DialogState.NO_SELECTION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!canLoadFirmware(contikiFirmware)) {
|
||||
setDialogState(DialogState.NO_SELECTION);
|
||||
return;
|
||||
}
|
||||
|
||||
nextButton.setText("Create");
|
||||
nextButton.setEnabled(true);
|
||||
commandsArea.setEnabled(false);
|
||||
setCompileCommands("");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void addCompileCommandTab(JTabbedPane parent) {
|
||||
commandsArea = new JTextArea(10, 1);
|
||||
commandsArea.getDocument().addDocumentListener(new DocumentListener() {
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
setDialogState(DialogState.AWAITING_COMPILATION);
|
||||
}
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
setDialogState(DialogState.AWAITING_COMPILATION);
|
||||
}
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
setDialogState(DialogState.AWAITING_COMPILATION);
|
||||
}
|
||||
});
|
||||
parent.addTab("Compile commands", null, commandsArea, "Manually alter Contiki compilation commands");
|
||||
}
|
||||
|
||||
private void addMoteInterfacesTab(JTabbedPane parent) {
|
||||
moteIntfBox = Box.createVerticalBox();
|
||||
parent.addTab("Mote interfaces", null, new JScrollPane(moteIntfBox), "Mote interfaces");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Currently selected mote interface classes
|
||||
*/
|
||||
public Class<? extends MoteInterface>[] getSelectedMoteInterfaceClasses() {
|
||||
ArrayList<Class<? extends MoteInterface>> selected = new ArrayList();
|
||||
|
||||
for (Component c : moteIntfBox.getComponents()) {
|
||||
if (!(c instanceof JCheckBox)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!((JCheckBox) c).isSelected()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<? extends MoteInterface> intfClass =
|
||||
(Class<? extends MoteInterface>)
|
||||
((JCheckBox) c).getClientProperty("class");
|
||||
|
||||
if (intfClass == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
selected.add(intfClass);
|
||||
}
|
||||
|
||||
Class<? extends MoteInterface>[] arr = new Class[selected.size()];
|
||||
selected.toArray(arr);
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds given mote interface to mote interface list, represented by a checkbox.
|
||||
* If mote interface already exists, this method call is ignored.
|
||||
*
|
||||
* @param intfClass Mote interface class
|
||||
* @param selected If true, interface will initially be selected
|
||||
*/
|
||||
public void addMoteInterface(Class<? extends MoteInterface> intfClass, boolean selected) {
|
||||
/* If mote interface was already added, do nothing */
|
||||
for (Component c : moteIntfBox.getComponents()) {
|
||||
if (!(c instanceof JCheckBox)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Class<? extends MoteInterface> existingClass =
|
||||
(Class<? extends MoteInterface>)
|
||||
((JCheckBox) c).getClientProperty("class");
|
||||
|
||||
if (existingClass == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (existingClass == intfClass) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create new mote interface checkbox */
|
||||
JCheckBox intfCheckBox = new JCheckBox(GUI.getDescriptionOf(intfClass));
|
||||
intfCheckBox.setSelected(selected);
|
||||
intfCheckBox.putClientProperty("class", intfClass);
|
||||
intfCheckBox.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
intfCheckBox.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
setDialogState(DialogState.AWAITING_COMPILATION);
|
||||
}
|
||||
});
|
||||
moteIntfBox.add(intfCheckBox);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param commands User configured compile commands
|
||||
*/
|
||||
public void setCompileCommands(String commands) {
|
||||
/* TODO Merge from String[] */
|
||||
commandsArea.setText(commands);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User configured compile commands
|
||||
*/
|
||||
public String getCompileCommands() {
|
||||
/* TODO Split into String[] */
|
||||
return commandsArea.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param source Contiki source
|
||||
* @return Suggested compile commands for compiling source
|
||||
*/
|
||||
public abstract String getDefaultCompileCommands(File source);
|
||||
|
||||
/**
|
||||
* @param source Contiki source
|
||||
* @return Expected Contiki firmware compiled from source
|
||||
*/
|
||||
public abstract File getExpectedFirmwareFile(File source);
|
||||
|
||||
private void abortAnyCompilation() {
|
||||
if (currentCompilationProcess == null) {
|
||||
return;
|
||||
}
|
||||
currentCompilationProcess.destroy();
|
||||
currentCompilationProcess = null;
|
||||
}
|
||||
|
||||
private boolean createNewCompilationTab(MessageList output) {
|
||||
abortAnyCompilation();
|
||||
tabbedPane.remove(currentCompilationOutput);
|
||||
|
||||
JScrollPane scrollOutput = new JScrollPane(output);
|
||||
tabbedPane.addTab("Compilation output", null, scrollOutput, "Shows Contiki compilation output");
|
||||
|
||||
tabbedPane.setSelectedComponent(scrollOutput);
|
||||
currentCompilationOutput = scrollOutput;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue