mirror of
https://github.com/oliverschmidt/contiki.git
synced 2024-11-08 23:08:29 +00:00
abstract contiki compile dialog using compile library.
to be implemented by msp mote type
This commit is contained in:
parent
37586984f6
commit
217d8cf0b3
@ -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 New Issue
Block a user