diff --git a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZCompileDialog.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZCompileDialog.java index 498a59dc7..129584daf 100644 --- a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZCompileDialog.java +++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZCompileDialog.java @@ -98,4 +98,9 @@ public class MicaZCompileDialog extends AbstractCompileDialog { public void writeSettingsToMoteType() { /* Nothing to do */ } + + protected String getTargetName() { + return "micaz"; + } + } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/ESBMoteType.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/ESBMoteType.java index 286805ec3..2f24f0327 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/ESBMoteType.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/ESBMoteType.java @@ -210,4 +210,9 @@ public class ESBMoteType extends MspMoteType { return new File(parentDir, sourceNoExtension + ".esb"); } + + protected String getTargetName() { + return "esb"; + } + } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspCompileDialog.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspCompileDialog.java index 782b8148b..fabab57b3 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspCompileDialog.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/MspCompileDialog.java @@ -34,6 +34,10 @@ package se.sics.cooja.mspmote; import java.awt.Container; import java.io.File; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; +import javax.swing.JTextArea; + import se.sics.cooja.GUI; import se.sics.cooja.MoteInterface; import se.sics.cooja.Simulation; @@ -41,7 +45,7 @@ import se.sics.cooja.dialogs.AbstractCompileDialog; public class MspCompileDialog extends AbstractCompileDialog { private static final long serialVersionUID = -7273193946433145019L; - private String target; + private static String target; public static boolean showDialog( Container parent, @@ -49,6 +53,7 @@ public class MspCompileDialog extends AbstractCompileDialog { MspMoteType moteType, String target) { + MspCompileDialog.target = target; final AbstractCompileDialog dialog = new MspCompileDialog(parent, simulation, moteType, target); /* Show dialog and wait for user */ @@ -63,9 +68,8 @@ public class MspCompileDialog extends AbstractCompileDialog { private MspCompileDialog(Container parent, Simulation simulation, MspMoteType moteType, String target) { super(parent, simulation, moteType); + setTitle("Create Mote Type: Compile Contiki for " + target); - this.target = target; - /* Select all mote interfaces */ boolean selected = true; if (moteIntfBox.getComponentCount() > 0) { @@ -74,8 +78,21 @@ public class MspCompileDialog extends AbstractCompileDialog { for (Class intfClass: moteType.getAllMoteInterfaceClasses()) { addMoteInterface(intfClass, selected); } + + addCompilationTipsTab(tabbedPane); } + private void addCompilationTipsTab(JTabbedPane parent) { + JTextArea textArea = new JTextArea(); + textArea.setEditable(false); + textArea.append("# Without low-power radio:\n" + + "DEFINES=NETSTACK_MAC=nullmac_driver,NETSTACK_RDC=nullrdc_noframer_driver,CC2420_CONF_AUTOACK=0\n" + + "# (remember to \"make clean\" after changing compilation flags)" + ); + + parent.addTab("Tips", null, new JScrollPane(textArea), "Compilation tips"); + } + public boolean canLoadFirmware(File file) { if (file.getName().endsWith("." + target)) { return true; @@ -100,4 +117,10 @@ public class MspCompileDialog extends AbstractCompileDialog { public void writeSettingsToMoteType() { /* Nothing to do */ } + + protected String getTargetName() { + /* Override me */ + return target; + } + } diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/SkyMoteType.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/SkyMoteType.java index 1812dae5c..47823214b 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/SkyMoteType.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/SkyMoteType.java @@ -230,4 +230,9 @@ public class SkyMoteType extends MspMoteType { return new File(parentDir, sourceNoExtension + ".sky"); } + + protected String getTargetName() { + return "sky"; + } + } diff --git a/tools/cooja/java/se/sics/cooja/dialogs/AbstractCompileDialog.java b/tools/cooja/java/se/sics/cooja/dialogs/AbstractCompileDialog.java index b79449e0a..736044e8c 100644 --- a/tools/cooja/java/se/sics/cooja/dialogs/AbstractCompileDialog.java +++ b/tools/cooja/java/se/sics/cooja/dialogs/AbstractCompileDialog.java @@ -86,7 +86,9 @@ public abstract class AbstractCompileDialog extends JDialog { protected JTextField contikiField; private JTextField descriptionField; private JTextArea commandsArea; - private JButton nextButton; + private JButton cleanButton; + private JButton compileButton; + private JButton createButton; private Component currentCompilationOutput = null; private Process currentCompilationProcess = null; @@ -136,13 +138,13 @@ public abstract class AbstractCompileDialog extends JDialog { }; DocumentListener contikiFieldListener = new DocumentListener() { public void changedUpdate(DocumentEvent e) { - SwingUtilities.invokeLater(selectedContikiFile); + selectedContikiFile.run(); } public void insertUpdate(DocumentEvent e) { - SwingUtilities.invokeLater(selectedContikiFile); + selectedContikiFile.run(); } public void removeUpdate(DocumentEvent e) { - SwingUtilities.invokeLater(selectedContikiFile); + selectedContikiFile.run(); } }; sourcePanel.add(contikiField); @@ -219,38 +221,70 @@ public abstract class AbstractCompileDialog extends JDialog { topPanel.add(sourcePanel); - nextButton = new JButton("NEXT"); - nextButton.addActionListener(new ActionListener() { + Action compileAction = new AbstractAction("Compile") { + private static final long serialVersionUID = 1L; + public void actionPerformed(ActionEvent e) { + if (!compileButton.isEnabled()) { + return; + } + try { + setDialogState(DialogState.AWAITING_COMPILATION); + compileContiki(); + } catch (Exception e1) { + logger.fatal("Error while compiling Contiki: " + e1.getMessage()); + } + } + }; + cleanButton = new JButton("Clean"); + cleanButton.setToolTipText("make clean TARGET=" + getTargetName()); + cleanButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + currentCompilationProcess = CompileContiki.compile( + "make clean TARGET=" + getTargetName(), + compilationEnvironment, + null /* Do not observe output firmware file */, + new File(contikiField.getText()).getParentFile(), + null, + null, + null, + true + ); + } catch (Exception e1) { + logger.fatal("Clean failed: " + e1.getMessage(), e1); + } + } + }); + + compileButton = new JButton(compileAction); + getRootPane().setDefaultButton(compileButton); + + + createButton = new JButton("Create"); + createButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - if (nextButton.getText().equals("Compile")) { - try { - compileContiki(); - } catch (Exception e1) { - logger.fatal("Error while compiling Contiki: " + e1.getMessage()); - } - } 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 (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(); + /* Write mote type settings (mote type specific) */ + writeSettingsToMoteType(); - AbstractCompileDialog.this.dispose(); - } + 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(cleanButton); buttonPanel.add(Box.createHorizontalStrut(5)); - buttonPanel.add(nextButton); + buttonPanel.add(compileButton); + buttonPanel.add(Box.createHorizontalStrut(5)); + buttonPanel.add(createButton); buttonPanel.setAlignmentX(LEFT_ALIGNMENT); topPanel.add(buttonPanel); @@ -267,25 +301,7 @@ public abstract class AbstractCompileDialog extends JDialog { 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) { - } - + addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { abortAnyCompilation(); contikiSource = null; @@ -322,8 +338,8 @@ public abstract class AbstractCompileDialog extends JDialog { /* Restore compile commands */ if (moteType.getCompileCommands() != null) { - setCompileCommands(moteType.getCompileCommands()); - setDialogState(DialogState.AWAITING_COMPILATION); + setCompileCommands(moteType.getCompileCommands()); + setDialogState(DialogState.AWAITING_COMPILATION); restoredDialogState = true; } } @@ -349,21 +365,9 @@ public abstract class AbstractCompileDialog extends JDialog { } /* Recompile at Ctrl+R */ - Action recompileAction = new AbstractAction() { - public void actionPerformed(ActionEvent e) { - try { - setDialogState(DialogState.AWAITING_COMPILATION); - if (nextButton.getText().equals("Compile")) { - compileContiki(); - } - } catch (Exception e1) { - e1.printStackTrace(); - } - } - }; InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, KeyEvent.CTRL_DOWN_MASK, false), "recompile"); - getRootPane().getActionMap().put("recompile", recompileAction); + getRootPane().getActionMap().put("recompile", compileAction); pack(); setLocationRelativeTo(parent); @@ -395,8 +399,7 @@ public abstract class AbstractCompileDialog extends JDialog { public abstract boolean canLoadFirmware(File file); protected String[] compilationEnvironment = null; /* Default environment: inherit from current process */ - public void compileContiki() - throws Exception { + public void compileContiki() throws Exception { final MessageList taskOutput = new MessageList(); if (contikiFirmware.exists()) { @@ -417,7 +420,11 @@ public abstract class AbstractCompileDialog extends JDialog { throw new Exception("No compile commands specified"); } - setDialogState(DialogState.IS_COMPILING); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + setDialogState(DialogState.IS_COMPILING); + } + }); createNewCompilationTab(taskOutput); /* Add abort compilation menu item */ @@ -432,7 +439,8 @@ public abstract class AbstractCompileDialog extends JDialog { /* Called when last command has finished (success only) */ final Action compilationSuccessAction = new AbstractAction() { - public void actionPerformed(ActionEvent e) { + private static final long serialVersionUID = -3815068126197234346L; + public void actionPerformed(ActionEvent e) { abortMenuItem.setEnabled(false); /* Make sure firmware exists */ @@ -447,7 +455,8 @@ public abstract class AbstractCompileDialog extends JDialog { /* Called immediately if any command fails */ final Action compilationFailureAction = new AbstractAction() { - public void actionPerformed(ActionEvent e) { + private static final long serialVersionUID = -800799353242963993L; + public void actionPerformed(ActionEvent e) { abortMenuItem.setEnabled(false); setDialogState(DialogState.AWAITING_COMPILATION); } @@ -455,7 +464,8 @@ public abstract class AbstractCompileDialog extends JDialog { /* Called once per command */ final Action nextCommandAction = new AbstractAction() { - public void actionPerformed(ActionEvent e) { + private static final long serialVersionUID = -4525372566302330762L; + public void actionPerformed(ActionEvent e) { Action nextSuccessAction; if (commands.size() == 1) { nextSuccessAction = compilationSuccessAction; @@ -515,19 +525,18 @@ public abstract class AbstractCompileDialog extends JDialog { * @see DialogState * @param dialogState New dialog state */ - public void setDialogState(DialogState dialogState) { + protected void setDialogState(DialogState dialogState) { File sourceFile = new File(contikiField.getText()); + compileButton.setText("Compile"); + getRootPane().setDefaultButton(compileButton); switch (dialogState) { case NO_SELECTION: - nextButton.setText("Compile"); - nextButton.setEnabled(false); - commandsArea.setEnabled(false); - SwingUtilities.invokeLater(new Runnable() { - public void run() { - commandsArea.setText(""); - } - }); + cleanButton.setEnabled(false); + compileButton.setEnabled(false); + createButton.setEnabled(false); + commandsArea.setEnabled(false); + setCompileCommands(""); break; case SELECTED_SOURCE: @@ -540,9 +549,10 @@ public abstract class AbstractCompileDialog extends JDialog { return; } - nextButton.setText("Compile"); - nextButton.setEnabled(true); - commandsArea.setEnabled(true); + cleanButton.setEnabled(true); + compileButton.setEnabled(true); + createButton.setEnabled(false); + commandsArea.setEnabled(true); setCompileCommands(getDefaultCompileCommands(sourceFile)); contikiFirmware = getExpectedFirmwareFile(sourceFile); contikiSource = sourceFile; @@ -559,21 +569,26 @@ public abstract class AbstractCompileDialog extends JDialog { return; } - nextButton.setText("Compile"); - nextButton.setEnabled(true); - commandsArea.setEnabled(true); + cleanButton.setEnabled(true); + compileButton.setEnabled(true); + createButton.setEnabled(false); + commandsArea.setEnabled(true); break; case IS_COMPILING: - nextButton.setText("Compiling"); - nextButton.setEnabled(false); - commandsArea.setEnabled(false); + cleanButton.setEnabled(false); + compileButton.setEnabled(false); + compileButton.setText("Compiling"); + createButton.setEnabled(false); + commandsArea.setEnabled(false); break; case COMPILED_FIRMWARE: - nextButton.setText("Create"); - nextButton.setEnabled(true); - commandsArea.setEnabled(true); + cleanButton.setEnabled(true); + compileButton.setEnabled(true); + createButton.setEnabled(true); + commandsArea.setEnabled(true); + getRootPane().setDefaultButton(createButton); break; case SELECTED_FIRMWARE: @@ -583,16 +598,17 @@ public abstract class AbstractCompileDialog extends JDialog { setDialogState(DialogState.NO_SELECTION); return; } - if (!canLoadFirmware(contikiFirmware)) { setDialogState(DialogState.NO_SELECTION); return; } - nextButton.setText("Create"); - nextButton.setEnabled(true); - commandsArea.setEnabled(false); - setCompileCommands(""); + cleanButton.setEnabled(true); + compileButton.setEnabled(false); + createButton.setEnabled(true); + commandsArea.setEnabled(false); + setCompileCommands(""); + getRootPane().setDefaultButton(createButton); break; default: @@ -690,7 +706,6 @@ public abstract class AbstractCompileDialog extends JDialog { intfCheckBox.setToolTipText(intfClass.getName()); intfCheckBox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - if (contikiSource == null && contikiFirmware != null) { setDialogState(DialogState.SELECTED_FIRMWARE); @@ -760,4 +775,5 @@ public abstract class AbstractCompileDialog extends JDialog { return true; } + protected abstract String getTargetName(); } diff --git a/tools/cooja/java/se/sics/cooja/dialogs/CompileContiki.java b/tools/cooja/java/se/sics/cooja/dialogs/CompileContiki.java index 128ba1c82..3234a6cdc 100644 --- a/tools/cooja/java/se/sics/cooja/dialogs/CompileContiki.java +++ b/tools/cooja/java/se/sics/cooja/dialogs/CompileContiki.java @@ -100,7 +100,7 @@ public class CompileContiki { * @param directory Directory in which to execute command * @param onSuccess Action called if compilation succeeds * @param onFailure Action called if compilation fails - * @param compilationOutput Is written both std and err process output + * @param messageDialog Is written both std and err process output * @param synchronous If true, method blocks until process completes * @return Sub-process if called asynchronously * @throws Exception If process returns error, or outputFile does not exist @@ -115,15 +115,22 @@ public class CompileContiki { final MessageList compilationOutput, boolean synchronous) throws Exception { - + /* TODO Fix me */ + final MessageList messageDialog; + if (compilationOutput == null) { + messageDialog = new MessageList(); + } else { + messageDialog = compilationOutput; + } + { String cmd = ""; for (String c: command) { cmd += c + " "; } logger.info("> " + cmd); - compilationOutput.addMessage("", MessageList.NORMAL); - compilationOutput.addMessage("> " + cmd, MessageList.NORMAL); + messageDialog.addMessage("", MessageList.NORMAL); + messageDialog.addMessage("> " + cmd, MessageList.NORMAL); } final Process compileProcess; @@ -140,7 +147,7 @@ public class CompileContiki { outputFile.delete(); } if (outputFile.exists()) { - compilationOutput.addMessage("Error when deleting old " + outputFile.getName(), MessageList.ERROR); + messageDialog.addMessage("Error when deleting old " + outputFile.getName(), MessageList.ERROR); if (onFailure != null) { onFailure.actionPerformed(null); } @@ -153,8 +160,8 @@ public class CompileContiki { try { String readLine; while ((readLine = processNormal.readLine()) != null) { - if (compilationOutput != null) { - compilationOutput.addMessage(readLine, MessageList.NORMAL); + if (messageDialog != null) { + messageDialog.addMessage(readLine, MessageList.NORMAL); } } } catch (IOException e) { @@ -168,8 +175,8 @@ public class CompileContiki { try { String readLine; while ((readLine = processError.readLine()) != null) { - if (compilationOutput != null) { - compilationOutput.addMessage(readLine, MessageList.ERROR); + if (messageDialog != null) { + messageDialog.addMessage(readLine, MessageList.ERROR); } } } catch (IOException e) { @@ -186,7 +193,7 @@ public class CompileContiki { try { compileProcess.waitFor(); } catch (Exception e) { - compilationOutput.addMessage(e.getMessage(), MessageList.ERROR); + messageDialog.addMessage(e.getMessage(), MessageList.ERROR); syncException.setCompilationOutput(new MessageList()); syncException.fillInStackTrace(); return; @@ -194,7 +201,7 @@ public class CompileContiki { /* Check return value */ if (compileProcess.exitValue() != 0) { - compilationOutput.addMessage("Process returned error code " + compileProcess.exitValue(), MessageList.ERROR); + messageDialog.addMessage("Process returned error code " + compileProcess.exitValue(), MessageList.ERROR); if (onFailure != null) { onFailure.actionPerformed(null); } @@ -212,7 +219,7 @@ public class CompileContiki { } if (!outputFile.exists()) { - compilationOutput.addMessage("No firmware file: " + outputFile, MessageList.ERROR); + messageDialog.addMessage("No firmware file: " + outputFile, MessageList.ERROR); if (onFailure != null) { onFailure.actionPerformed(null); } @@ -221,8 +228,8 @@ public class CompileContiki { return; } - compilationOutput.addMessage("", MessageList.NORMAL); - compilationOutput.addMessage("Compilation succeded", MessageList.NORMAL); + messageDialog.addMessage("", MessageList.NORMAL); + messageDialog.addMessage("Compilation succeded", MessageList.NORMAL); if (onSuccess != null) { onSuccess.actionPerformed(null); } diff --git a/tools/cooja/java/se/sics/cooja/dialogs/ContikiMoteCompileDialog.java b/tools/cooja/java/se/sics/cooja/dialogs/ContikiMoteCompileDialog.java index d382e121e..6d9d40cdd 100644 --- a/tools/cooja/java/se/sics/cooja/dialogs/ContikiMoteCompileDialog.java +++ b/tools/cooja/java/se/sics/cooja/dialogs/ContikiMoteCompileDialog.java @@ -381,4 +381,9 @@ public class ContikiMoteCompileDialog extends AbstractCompileDialog { /* Start compiling */ super.compileContiki(); } + + protected String getTargetName() { + return "cooja"; + } + }