diff --git a/app/src/processing/app/AbstractTextMonitor.java b/app/src/processing/app/AbstractTextMonitor.java index 1602e869a72..72b5c4dee9f 100644 --- a/app/src/processing/app/AbstractTextMonitor.java +++ b/app/src/processing/app/AbstractTextMonitor.java @@ -10,6 +10,8 @@ import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.text.SimpleDateFormat; +import java.util.Date; import javax.swing.Box; import javax.swing.BoxLayout; @@ -22,7 +24,9 @@ import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; +import javax.swing.text.BadLocationException; import javax.swing.text.DefaultCaret; +import javax.swing.text.Document; import cc.arduino.packages.BoardPort; @@ -36,11 +40,15 @@ public abstract class AbstractTextMonitor extends AbstractMonitor { protected JButton sendButton; protected JButton clearButton; protected JCheckBox autoscrollBox; + protected JCheckBox addTimeStampBox; protected JComboBox lineEndings; protected JComboBox serialRates; + private SimpleDateFormat logDateFormat; + public AbstractTextMonitor(BoardPort boardPort) { super(boardPort); + logDateFormat = new SimpleDateFormat("HH:mm:ss.SSS"); } protected void onCreateWindow(Container mainPane) { @@ -90,6 +98,7 @@ public void windowGainedFocus(WindowEvent e) { pane.setBorder(new EmptyBorder(4, 4, 4, 4)); autoscrollBox = new JCheckBox(tr("Autoscroll"), true); + addTimeStampBox = new JCheckBox(tr("Show timestamp"), false); noLineEndingAlert = new JLabel(I18n.format(tr("You've pressed {0} but nothing was sent. Should you select a line ending?"), tr("Send"))); noLineEndingAlert.setToolTipText(noLineEndingAlert.getText()); @@ -108,6 +117,15 @@ public void actionPerformed(ActionEvent event) { if (PreferencesData.get("serial.line_ending") != null) { lineEndings.setSelectedIndex(PreferencesData.getInteger("serial.line_ending")); } + if (PreferencesData.get("serial.show_timestamp") != null) { + addTimeStampBox.setSelected(PreferencesData.getBoolean("serial.show_timestamp")); + } + addTimeStampBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PreferencesData.setBoolean("serial.show_timestamp", addTimeStampBox.isSelected()); + } + }); + lineEndings.setMaximumSize(lineEndings.getMinimumSize()); serialRates = new JComboBox(); @@ -118,6 +136,7 @@ public void actionPerformed(ActionEvent event) { serialRates.setMaximumSize(serialRates.getMinimumSize()); pane.add(autoscrollBox); + pane.add(addTimeStampBox); pane.add(Box.createHorizontalGlue()); pane.add(noLineEndingAlert); pane.add(Box.createRigidArea(new Dimension(8, 0))); @@ -138,6 +157,7 @@ protected void onEnableWindow(boolean enable) textField.setEnabled(enable); sendButton.setEnabled(enable); autoscrollBox.setEnabled(enable); + addTimeStampBox.setEnabled(enable); lineEndings.setEnabled(enable); serialRates.setEnabled(enable); } @@ -158,7 +178,24 @@ public void onSerialRateChange(ActionListener listener) { public void message(final String s) { SwingUtilities.invokeLater(new Runnable() { public void run() { - textArea.append(s); + if (addTimeStampBox.isSelected()) { + String[] lines = s.split("(?<=\\n)"); + Document doc = textArea.getDocument(); + for (String currentLine : lines) { + try { + if (doc.getLength() == 0 || ((int) doc.getText(doc.getLength() - 1, 1).charAt(0) == 10)) { + textArea.append(logDateFormat.format(new Date()) + " -> " + currentLine); + } else { + textArea.append(currentLine); + } + } catch (BadLocationException e) { + e.printStackTrace(); + } + } + } else { + textArea.append(s); + } + if (autoscrollBox.isSelected()) { textArea.setCaretPosition(textArea.getDocument().getLength()); } diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index e68ca47783b..522167f517c 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -198,6 +198,8 @@ public boolean test(SketchController sketch) { private Runnable exportAppHandler; private Runnable timeoutUploadHandler; + private Map internalToolCache = new HashMap(); + public Editor(Base ibase, File file, int[] storedLocation, int[] defaultLocation, Platform platform) throws Exception { super("Arduino"); this.base = ibase; @@ -962,8 +964,7 @@ public void updateKeywords(PdeKeywords keywords) { JMenuItem createToolMenuItem(String className) { try { - Class toolClass = Class.forName(className); - final Tool tool = (Tool) toolClass.newInstance(); + final Tool tool = getOrCreateToolInstance(className); JMenuItem item = new JMenuItem(tool.getMenuTitle()); @@ -982,6 +983,20 @@ public void actionPerformed(ActionEvent e) { } } + private Tool getOrCreateToolInstance(String className) { + Tool internalTool = internalToolCache.get(className); + if (internalTool == null) { + try { + Class toolClass = Class.forName(className); + internalTool = (Tool) toolClass.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + internalToolCache.put(className, internalTool); + } + return internalTool; + } private void addInternalTools(JMenu menu) { JMenuItem item; @@ -1996,6 +2011,11 @@ private boolean handleSave2() { statusNotice(tr("Saving...")); boolean saved = false; try { + if (PreferencesData.getBoolean("editor.autoformat_currentfile_before_saving")) { + Tool formatTool = getOrCreateToolInstance("cc.arduino.packages.formatter.AStyle"); + formatTool.run(); + } + boolean wasReadOnly = sketchController.isReadOnly(BaseNoGui.librariesIndexer.getInstalledLibraries(), BaseNoGui.getExamplesPath()); String previousMainFilePath = sketch.getMainFilePath(); saved = sketchController.save();