Merged master

This commit is contained in:
Cristian Maglie 2012-06-27 13:51:16 +02:00
commit 06c0928192
326 changed files with 99701 additions and 4756 deletions

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
app/bin/
app/pde.jar
build/macosx/work/
core/bin/
core/core.jar
hardware/arduino/bootloaders/caterina_LUFA/Descriptors.o
hardware/arduino/bootloaders/caterina_LUFA/Descriptors.lst
hardware/arduino/bootloaders/caterina_LUFA/Caterina.sym
hardware/arduino/bootloaders/caterina_LUFA/Caterina.o
hardware/arduino/bootloaders/caterina_LUFA/Caterina.map
hardware/arduino/bootloaders/caterina_LUFA/Caterina.lst
hardware/arduino/bootloaders/caterina_LUFA/Caterina.lss
hardware/arduino/bootloaders/caterina_LUFA/Caterina.elf
hardware/arduino/bootloaders/caterina_LUFA/Caterina.eep
hardware/arduino/bootloaders/caterina_LUFA/.dep/
.gitignore
build/windows/work/

View File

@ -32,6 +32,7 @@ import javax.swing.*;
import processing.app.debug.TargetPackage;
import processing.app.debug.TargetPlatform;
import processing.app.helpers.FileUtils;
import processing.app.helpers.PreferencesMap;
import processing.app.helpers.filefilters.OnlyDirs;
import processing.app.helpers.filefilters.OnlyFilesWithExtension;
@ -46,9 +47,9 @@ import static processing.app.I18n._;
* files and images, etc) that comes from that.
*/
public class Base {
public static final int REVISION = 100;
public static final int REVISION = 101;
/** This might be replaced by main() if there's a lib/version.txt file. */
static String VERSION_NAME = "0100";
static String VERSION_NAME = "0101";
/** Set true if this a proper release rather than a numbered revision. */
static public boolean RELEASE = false;
@ -171,6 +172,9 @@ public class Base {
// run static initialization that grabs all the prefs
Preferences.init(null);
// load the I18n module for internationalization
I18n.init(Preferences.get("editor.languages.current"));
// setup the theme coloring fun
Theme.init();
@ -934,6 +938,21 @@ public class Base {
public void rebuildImportMenu(JMenu importMenu) {
importMenu.removeAll();
// Split between user supplied libraries and IDE libraries
Map<String, File> ideLibs = new HashMap<String, File>(libraries);
Map<String, File> userLibs = new HashMap<String, File>(libraries);
for (String lib : libraries.keySet()) {
try {
if (FileUtils.isSubDirectory(getSketchbookFolder(), libraries.get(lib)))
ideLibs.remove(lib);
else
userLibs.remove(lib);
} catch (IOException e) {
ideLibs.remove(lib);
userLibs.remove(lib);
}
}
try {
// Find the current target. Get the platform, and then select the
// correct name and core path.
@ -944,7 +963,9 @@ public class Base {
platformItem.setEnabled(false);
importMenu.add(platformItem);
importMenu.addSeparator();
addLibraries(importMenu, libraries);
addLibraries(importMenu, ideLibs);
importMenu.addSeparator();
addLibraries(importMenu, userLibs);
} catch (IOException e) {
e.printStackTrace();
}
@ -1014,7 +1035,7 @@ public class Base {
// Scan for libraries in each library folder.
// Libraries located in the latest folders on the list can override
// other libraries with the same.
// other libraries with the same name.
libraries = scanLibraries(librariesFolders);
// Populate importToLibraryTable
@ -1206,7 +1227,7 @@ public class Base {
return found;
}
protected boolean addLibraries(JMenu menu, Map<String, File> libs) throws IOException {
protected void addLibraries(JMenu menu, Map<String, File> libs) throws IOException {
List<String> list = new ArrayList<String>(libs.keySet());
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
@ -1217,8 +1238,6 @@ public class Base {
}
};
boolean found = false;
for (String name : list) {
File folder = libs.get(name);
@ -1227,11 +1246,9 @@ public class Base {
item.addActionListener(listener);
item.setActionCommand(folder.getAbsolutePath());
menu.add(item);
found = true;
// XXX: DAM: should recurse here so that library folders can be nested
}
return found;
}
/**
@ -1535,12 +1552,12 @@ public class Base {
static public String getAvrBasePath() {
if(Base.isLinux()) {
return ""; // avr tools are installed system-wide and in the path
} else {
return getHardwarePath() + File.separator + "tools" +
File.separator + "avr" + File.separator + "bin" + File.separator;
}
String path = getHardwarePath() + File.separator + "tools" +
File.separator + "avr" + File.separator + "bin" + File.separator;
if (Base.isLinux() && !(new File(path)).exists()) {
return ""; // use distribution provided avr tools if bundled tools missing
}
return path;
}

View File

@ -264,7 +264,9 @@ public class Editor extends JFrame implements RunnerListener {
splitPane.setDividerSize(dividerSize);
}
splitPane.setMinimumSize(new Dimension(600, 400));
// the following changed from 600, 400 for netbooks
// http://code.google.com/p/arduino/issues/detail?id=52
splitPane.setMinimumSize(new Dimension(600, 100));
box.add(splitPane);
// hopefully these are no longer needed w/ swing
@ -288,19 +290,9 @@ public class Editor extends JFrame implements RunnerListener {
setPlacement(location);
// If the window is resized too small this will resize it again to the
// minimums. Adapted by Chris Lonnen from comments here:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4320050
// as a fix for http://dev.processing.org/bugs/show_bug.cgi?id=25
final int minW = Preferences.getInteger("editor.window.width.min");
final int minH = Preferences.getInteger("editor.window.height.min");
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(ComponentEvent event) {
setSize((getWidth() < minW) ? minW : getWidth(),
(getHeight() < minH) ? minH : getHeight());
}
});
// Set the minimum size for the editor window
setMinimumSize(new Dimension(Preferences.getInteger("editor.window.width.min"),
Preferences.getInteger("editor.window.height.min")));
// System.out.println("t3");
// Bring back the general options for the editor
@ -1135,7 +1127,11 @@ public class Editor extends JFrame implements RunnerListener {
undoItem.addActionListener(undoAction = new UndoAction());
menu.add(undoItem);
redoItem = newJMenuItem(_("Redo"), 'Y');
if (!Base.isMacOS()) {
redoItem = newJMenuItem(_("Redo"), 'Y');
} else {
redoItem = newJMenuItemShift(_("Redo"), 'Z');
}
redoItem.addActionListener(redoAction = new RedoAction());
menu.add(redoItem);
@ -1247,14 +1243,33 @@ public class Editor extends JFrame implements RunnerListener {
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (find != null) {
//find.find(true);
//FindReplace find = new FindReplace(Editor.this); //.show();
find.find(true);
find.findNext();
}
}
});
menu.add(item);
item = newJMenuItemShift(_("Find Previous"), 'G');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (find != null) {
find.findPrevious();
}
}
});
menu.add(item);
item = newJMenuItem(_("Use Selection For Find"), 'E');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (find == null) {
find = new FindReplace(Editor.this);
}
find.setFindText( getSelectedText() );
}
});
menu.add(item);
return menu;
}

View File

@ -122,6 +122,14 @@ public class EditorListener {
}
}
if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
// Consume ctrl-m(carriage return) keypresses
if (code == KeyEvent.VK_M) {
event.consume(); // does nothing
return false;
}
}
if ((event.getModifiers() & KeyEvent.META_MASK) != 0) {
//event.consume(); // does nothing
return false;

View File

@ -46,8 +46,9 @@ import javax.swing.*;
*/
public class FindReplace extends JFrame implements ActionListener {
static final int BIG = 13;
static final int EDGE = Base.isMacOS() ? 20 : 13;
static final int SMALL = 6;
static final int BUTTONGAP = 12; // 12 is correct for Mac, other numbers may be required for other platofrms
Editor editor;
@ -59,14 +60,14 @@ public class FindReplace extends JFrame implements ActionListener {
JButton replaceButton;
JButton replaceAllButton;
JButton replaceFindButton;
JButton previousButton;
JButton findButton;
JCheckBox ignoreCaseBox;
static boolean ignoreCase = true;
/// true when there's something selected in the editor
boolean found;
JCheckBox wrapAroundBox;
static boolean wrapAround = true;
public FindReplace(Editor editor) {
super("Find");
@ -77,23 +78,66 @@ public class FindReplace extends JFrame implements ActionListener {
pain.setLayout(null);
JLabel findLabel = new JLabel(_("Find:"));
Dimension d0 = findLabel.getPreferredSize();
JLabel replaceLabel = new JLabel(_("Replace with:"));
Dimension d1 = replaceLabel.getPreferredSize();
Dimension labelDimension = replaceLabel.getPreferredSize();
pain.add(findLabel);
pain.add(replaceLabel);
pain.add(findField = new JTextField(20));
pain.add(replaceField = new JTextField(20));
Dimension d2 = findField.getPreferredSize();
int fieldHeight = findField.getPreferredSize().height;
if (findString != null) findField.setText(findString);
if (replaceString != null) replaceField.setText(replaceString);
//System.out.println("setting find str to " + findString);
//findField.requestFocusInWindow();
//pain.setDefault
ignoreCaseBox = new JCheckBox(_("Ignore Case"));
ignoreCaseBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ignoreCase = ignoreCaseBox.isSelected();
}
});
ignoreCaseBox.setSelected(ignoreCase);
pain.add(ignoreCaseBox);
wrapAroundBox = new JCheckBox(_("Wrap Around"));
wrapAroundBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
wrapAround = wrapAroundBox.isSelected();
}
});
wrapAroundBox.setSelected(wrapAround);
pain.add(wrapAroundBox);
JPanel buttons = new JPanel();
buttons.setLayout(new FlowLayout(FlowLayout.CENTER,BUTTONGAP,0));
// ordering is different on mac versus pc
if (Base.isMacOS()) {
buttons.add(replaceAllButton = new JButton(_("Replace All")));
buttons.add(replaceButton = new JButton(_("Replace")));
buttons.add(replaceFindButton = new JButton(_("Replace & Find")));
buttons.add(previousButton = new JButton(_("Previous")));
buttons.add(findButton = new JButton(_("Find")));
} else {
buttons.add(findButton = new JButton(_("Find")));
buttons.add(previousButton = new JButton(_("Previous"))); // is this the right position for non-Mac?
buttons.add(replaceFindButton = new JButton(_("Replace & Find")));
buttons.add(replaceButton = new JButton(_("Replace")));
buttons.add(replaceAllButton = new JButton(_("Replace All")));
}
pain.add(buttons);
// to fix ugliness.. normally macosx java 1.3 puts an
// ugly white border around this object, so turn it off.
if (Base.isMacOS()) {
buttons.setBorder(null);
}
/*
findField.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
@ -109,92 +153,74 @@ public class FindReplace extends JFrame implements ActionListener {
});
*/
// +1 since it's better to tend downwards
int yoff = (1 + d2.height - d1.height) / 2;
Dimension buttonsDimension = buttons.getPreferredSize();
int visibleButtonWidth = buttonsDimension.width - 2 * BUTTONGAP;
int fieldWidth = visibleButtonWidth - (labelDimension.width + SMALL);
findLabel.setBounds(BIG + (d1.width-d0.width) + yoff, BIG,
d1.width, d1.height);
replaceLabel.setBounds(BIG, BIG + d2.height + SMALL + yoff,
d1.width, d1.height);
// +1 since it's better to tend downwards
int yoff = (1 + fieldHeight - labelDimension.height) / 2;
//ignoreCase = true;
ignoreCaseBox = new JCheckBox(_("Ignore Case"));
ignoreCaseBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ignoreCase = ignoreCaseBox.isSelected();
}
});
ignoreCaseBox.setSelected(ignoreCase);
pain.add(ignoreCaseBox);
int ypos = EDGE;
int labelWidth = findLabel.getPreferredSize().width;
findLabel.setBounds(EDGE + (labelDimension.width-labelWidth), ypos + yoff, // + yoff was added to the wrong field
labelWidth, labelDimension.height);
findField.setBounds(EDGE + labelDimension.width + SMALL, ypos,
fieldWidth, fieldHeight);
ypos += fieldHeight + SMALL;
labelWidth = replaceLabel.getPreferredSize().width;
replaceLabel.setBounds(EDGE + (labelDimension.width-labelWidth), ypos + yoff,
labelWidth, labelDimension.height);
replaceField.setBounds(EDGE + labelDimension.width + SMALL, ypos,
fieldWidth, fieldHeight);
//
ypos += fieldHeight + SMALL;
JPanel buttons = new JPanel();
buttons.setLayout(new FlowLayout());
ignoreCaseBox.setBounds(EDGE + labelDimension.width + SMALL,
ypos,
(fieldWidth-SMALL)/2, fieldHeight);
// ordering is different on mac versus pc
if (Base.isMacOS()) {
buttons.add(replaceAllButton = new JButton(_("Replace All")));
buttons.add(replaceButton = new JButton(_("Replace")));
buttons.add(replaceFindButton = new JButton(_("Replace & Find")));
buttons.add(findButton = new JButton(_("Find")));
wrapAroundBox.setBounds(EDGE + labelDimension.width + SMALL + (fieldWidth-SMALL)/2 + SMALL,
ypos,
(fieldWidth-SMALL)/2, fieldHeight);
} else {
buttons.add(findButton = new JButton(_("Find")));
buttons.add(replaceFindButton = new JButton(_("Replace & Find")));
buttons.add(replaceButton = new JButton(_("Replace")));
buttons.add(replaceAllButton = new JButton(_("Replace All")));
}
pain.add(buttons);
ypos += fieldHeight + SMALL;
// to fix ugliness.. normally macosx java 1.3 puts an
// ugly white border around this object, so turn it off.
if (Base.isMacOS()) {
buttons.setBorder(null);
}
buttons.setBounds(EDGE-BUTTONGAP, ypos,
buttonsDimension.width, buttonsDimension.height);
Dimension d3 = buttons.getPreferredSize();
//buttons.setBounds(BIG, BIG + d2.height*2 + SMALL + BIG,
buttons.setBounds(BIG, BIG + d2.height*3 + SMALL*2 + BIG,
d3.width, d3.height);
ypos += buttonsDimension.height + EDGE;
//
// Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
findField.setBounds(BIG + d1.width + SMALL, BIG,
d3.width - (d1.width + SMALL), d2.height);
replaceField.setBounds(BIG + d1.width + SMALL, BIG + d2.height + SMALL,
d3.width - (d1.width + SMALL), d2.height);
int wide = visibleButtonWidth + EDGE*2;
int high = ypos; // butt.y + butt.height + EDGE*2 + SMALL;
ignoreCaseBox.setBounds(BIG + d1.width + SMALL,
BIG + d2.height*2 + SMALL*2,
d3.width, d2.height);
pack();
Insets insets = getInsets();
//System.out.println("Insets = " + insets);
setSize(wide + insets.left + insets.right,high + insets.top + insets.bottom);
//
setLocationRelativeTo( null ); // center
// setBounds((screen.width - wide) / 2, (screen.height - high) / 2, wide, high);
replaceButton.addActionListener(this);
replaceAllButton.addActionListener(this);
replaceFindButton.addActionListener(this);
findButton.addActionListener(this);
previousButton.addActionListener(this);
// you mustn't replace what you haven't found, my son
replaceButton.setEnabled(false);
replaceFindButton.setEnabled(false);
// so that typing will go straight to this field
//findField.requestFocus();
// semantics of replace are "replace the current selection with the replace field"
// so whether we have found before or not is irrelevent
// replaceButton.setEnabled(false);
// replaceFindButton.setEnabled(false);
// make the find button the blinky default
getRootPane().setDefaultButton(findButton);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
int wide = d3.width + BIG*2;
Rectangle butt = buttons.getBounds(); // how big is your butt?
int high = butt.y + butt.height + BIG*2 + SMALL;
setBounds((screen.width - wide) / 2,
(screen.height - high) / 2, wide, high);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
@ -245,11 +271,13 @@ public class FindReplace extends JFrame implements ActionListener {
Object source = e.getSource();
if (source == findButton) {
find(true);
findNext();
} else if (source == previousButton) {
findPrevious();
} else if (source == replaceFindButton) {
replace();
find(true);
replaceAndFindNext();
} else if (source == replaceButton) {
replace();
@ -260,50 +288,54 @@ public class FindReplace extends JFrame implements ActionListener {
}
// look for the next instance of the find string
// to be found later than the current caret selection
// look for the next instance of the find string to be found
// once found, select it (and go to that line)
public void find(boolean wrap) {
// in case search len is zero,
// otherwise replace all will go into an infinite loop
found = false;
private boolean find(boolean wrap,boolean backwards ) {
String search = findField.getText();
//System.out.println("finding for " + search + " " + findString);
// this will catch "find next" being called when no search yet
if (search.length() == 0) return;
if (search.length() == 0) return false;
String text = editor.getText();
if (ignoreCase) {
search = search.toLowerCase();
search = search.toLowerCase();
text = text.toLowerCase();
}
//int selectionStart = editor.textarea.getSelectionStart();
int selectionEnd = editor.getSelectionStop();
int nextIndex;
if (!backwards) {
//int selectionStart = editor.textarea.getSelectionStart();
int selectionEnd = editor.getSelectionStop();
int nextIndex = text.indexOf(search, selectionEnd);
if (nextIndex == -1) {
if (wrap) {
nextIndex = text.indexOf(search, selectionEnd);
if (wrap && nextIndex == -1) {
// if wrapping, a second chance is ok, start from beginning
nextIndex = text.indexOf(search, 0);
}
} else {
//int selectionStart = editor.textarea.getSelectionStart();
int selectionStart = editor.getSelectionStart()-1;
if (nextIndex == -1) {
found = false;
replaceButton.setEnabled(false);
replaceFindButton.setEnabled(false);
//Toolkit.getDefaultToolkit().beep();
return;
if ( selectionStart >= 0 ) {
nextIndex = text.lastIndexOf(search, selectionStart);
} else {
nextIndex = -1;
}
if (wrap && nextIndex == -1) {
// if wrapping, a second chance is ok, start from the end
nextIndex = text.lastIndexOf(search);
}
}
found = true;
replaceButton.setEnabled(true);
replaceFindButton.setEnabled(true);
editor.setSelection(nextIndex, nextIndex + search.length());
if (nextIndex != -1) {
editor.setSelection(nextIndex, nextIndex + search.length());
} else {
//Toolkit.getDefaultToolkit().beep();
}
return nextIndex != -1;
}
@ -312,28 +344,18 @@ public class FindReplace extends JFrame implements ActionListener {
* replacement text field.
*/
public void replace() {
if (!found) return; // don't replace if nothing found
// check to see if the document has wrapped around
// otherwise this will cause an infinite loop
String sel = editor.getSelectedText();
if (sel.equals(replaceField.getText())) {
found = false;
replaceButton.setEnabled(false);
replaceFindButton.setEnabled(false);
return;
}
editor.setSelectedText(replaceField.getText());
//editor.setSketchModified(true);
//editor.sketch.setCurrentModified(true);
editor.getSketch().setModified(true); // TODO is this necessary?
// don't allow a double replace
replaceButton.setEnabled(false);
replaceFindButton.setEnabled(false);
}
/**
* Replace the current selection with whatever's in the
* replacement text field, and then find the next match
*/
public void replaceAndFindNext() {
replace();
findNext();
}
/**
* Replace everything that matches by doing find and replace
@ -343,9 +365,35 @@ public class FindReplace extends JFrame implements ActionListener {
// move to the beginning
editor.setSelection(0, 0);
do {
find(false);
replace();
} while (found);
boolean foundAtLeastOne = false;
while ( true ) {
if ( find(false,false) ) {
foundAtLeastOne = true;
replace();
} else {
break;
}
}
if ( !foundAtLeastOne ) {
Toolkit.getDefaultToolkit().beep();
}
}
public void setFindText( String t ) {
findField.setText( t );
findString = t;
}
public void findNext() {
if ( !find( wrapAround, false ) ) {
Toolkit.getDefaultToolkit().beep();
}
}
public void findPrevious() {
if ( !find( wrapAround, true ) ) {
Toolkit.getDefaultToolkit().beep();
}
}
}

View File

@ -12,11 +12,25 @@
*/
package processing.app;
import java.util.*;
import java.util.Locale.*;
import java.text.MessageFormat;
public class I18n {
// start using current locale but still allow using the dropdown list later
private static ResourceBundle i18n = ResourceBundle.getBundle("processing.app.Resources");
public static Locale locale;
static protected void init (String language) {
// there might be a null pointer exception ... most likely will never happen but the jvm gets mad
try {
if (language == null || language.trim().length() == 0) locale = Locale.getDefault();
else locale = new Locale(language);
i18n = ResourceBundle.getBundle("processing.app.Resources", locale);
} catch (java.lang.NullPointerException e) {
}
}
public static String _(String s) {
try {

View File

@ -80,6 +80,75 @@ public class Preferences {
static final String PROMPT_OK = _("OK");
static final String PROMPT_BROWSE = _("Browse");
String[] languages = {
_("System Default"),
"العربية" + " (" + _("Arabic") + ")",
"Aragonés" + " (" + _("Aragonese") + ")",
"Català" + " (" + _("Catalan") + ")",
"简体中文" + " (" + _("Chinese Simplified") + ")",
"繁體中文" + " (" + _("Chinese Traditional") + ")",
"Dansk" + " (" + _("Danish") + ")",
"Nederlands" + " (" + _("Dutch") + ")",
"English" + " (" + _("English") + ")",
"Eesti" + " (" + _("Estonian") + ")",
"Pilipino" + " (" + _("Filipino") + ")",
"Français" + " (" + _("French") + ")",
"Galego" + " (" + _("Galician") + ")",
"Deutsch" + " (" + _("German") + ")",
"ελληνικά" + " (" + _("Greek") + ")",
"Magyar" + " (" + _("Hindi") + ")",
"Magyar" + " (" + _("Hungarian") + ")",
"Bahasa Indonesia" + " (" + _("Indonesian") + ")",
"Italiano" + " (" + _("Italian") + ")",
"日本語" + " (" + _("Japanese") + ")",
"한국어" + " (" + _("Korean") + ")",
"Latviešu" + " (" + _("Latvian") + ")",
"Lietuvių Kalba" + " (" + _("Lithuaninan") + ")",
"मराठी" + " (" + _("Marathi") + ")",
"Norsk" + " (" + _("Norwegian") + ")",
"فارسی" + " (" + _("Persian") + ")",
"Język Polski" + " (" + _("Polish") + ")",
"Português" + " (" + _("Portuguese") + " - Brazil)",
"Português" + " (" + _("Portuguese") + " - Portugal)",
"Română" + " (" + _("Romanian") + ")",
"Русский" + " (" + _("Russian") + ")",
"Español" + " (" + _("Spanish") + ")",
"தமிழ்" + " (" + _("Tamil") + ")"};
String[] languagesISO = {
"",
"ar",
"an",
"ca",
"zh_cn",
"zh_tw",
"da",
"nl",
"en",
"et",
"tl",
"fr",
"gl",
"de",
"el",
"hi",
"hu",
"id",
"it",
"ja",
"ko",
"lv",
"lt",
"mr",
"no_nb",
"fa",
"pl",
"pt_br",
"pt_pt",
"ro",
"ru",
"es",
"ta"};
/**
* Standardized width for buttons. Mac OS X 10.3 wants 70 as its default,
* Windows XP needs 66, and my Ubuntu machine needs 80+, so 80 seems proper.
@ -117,6 +186,7 @@ public class Preferences {
JCheckBox exportSeparateBox;
JCheckBox verboseCompilationBox;
JCheckBox verboseUploadBox;
JCheckBox verifyUploadBox;
JCheckBox externalEditorBox;
JCheckBox memoryOverrideBox;
JTextField memoryField;
@ -124,6 +194,7 @@ public class Preferences {
JTextField fontSizeField;
JCheckBox updateExtensionBox;
JCheckBox autoAssociateBox;
JComboBox comboLanguage;
// the calling editor, so updates can be applied
@ -151,10 +222,9 @@ public class Preferences {
// set some runtime constants (not saved on preferences file)
table.put("runtime.os", PConstants.platformNames[PApplet.platform]);
String idePath = System.getProperty("user.dir");
if (Base.isMacOS())
idePath += "/Arduino.app/Contents/Resources/Java";
table.put("runtime.ide.path", idePath);
File hardwareFolder = Base.getHardwareFolder();
table.put("runtime.hardware.path", hardwareFolder.getAbsolutePath());
table.put("runtime.ide.path", hardwareFolder.getParentFile().getAbsolutePath());
table.put("runtime.ide.version", "" + Base.REVISION);
// check for platform-specific properties in the defaults
@ -278,9 +348,25 @@ public class Preferences {
top += vmax + GUI_BETWEEN;
// Preferred language: [ ] (requires restart of Arduino)
Container box = Box.createHorizontalBox();
label = new JLabel(_("Editor language: "));
box.add(label);
comboLanguage = new JComboBox(languages);
comboLanguage.setSelectedIndex((Arrays.asList(languagesISO)).indexOf(Preferences.get("editor.languages.current")));
box.add(comboLanguage);
label = new JLabel(_(" (requires restart of Arduino)"));
box.add(label);
pain.add(box);
d = box.getPreferredSize();
box.setForeground(Color.gray);
box.setBounds(left, top, d.width, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// Editor font size [ ]
Container box = Box.createHorizontalBox();
box = Box.createHorizontalBox();
label = new JLabel(_("Editor font size: "));
box.add(label);
fontSizeField = new JTextField(4);
@ -308,8 +394,16 @@ public class Preferences {
d = box.getPreferredSize();
box.setBounds(left, top, d.width, d.height);
top += d.height + GUI_BETWEEN;
// [ ] Verify code after upload
verifyUploadBox = new JCheckBox(_("Verify code after upload"));
pain.add(verifyUploadBox);
d = verifyUploadBox.getPreferredSize();
verifyUploadBox.setBounds(left, top, d.width + 10, d.height);
right = Math.max(right, left + d.width);
top += d.height + GUI_BETWEEN;
// [ ] Use external editor
externalEditorBox = new JCheckBox(_("Use external editor"));
@ -350,7 +444,6 @@ public class Preferences {
top += d.height + GUI_BETWEEN;
}
// More preferences are in the ...
label = new JLabel(_("More preferences can be edited directly in the file"));
@ -491,7 +584,8 @@ public class Preferences {
// put each of the settings into the table
setBoolean("build.verbose", verboseCompilationBox.isSelected());
setBoolean("upload.verbose", verboseUploadBox.isSelected());
setBoolean("upload.verify", verifyUploadBox.isSelected());
// setBoolean("sketchbook.closing_last_window_quits",
// closingLastQuitsBox.isSelected());
//setBoolean("sketchbook.prompt", sketchPromptBox.isSelected());
@ -538,6 +632,11 @@ public class Preferences {
setBoolean("editor.update_extension", updateExtensionBox.isSelected());
// adds the selected language to the preferences file
Object newItem = comboLanguage.getSelectedItem();
int pos = (Arrays.asList(languages)).indexOf(newItem.toString()); // position in the languages array
set("editor.languages.current",(Arrays.asList(languagesISO)).get(pos));
editor.applyPreferences();
}
@ -548,6 +647,7 @@ public class Preferences {
// set all settings entry boxes to their actual status
verboseCompilationBox.setSelected(getBoolean("build.verbose"));
verboseUploadBox.setSelected(getBoolean("upload.verbose"));
verifyUploadBox.setSelected(getBoolean("upload.verify"));
//closingLastQuitsBox.
// setSelected(getBoolean("sketchbook.closing_last_window_quits"));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -101,6 +101,32 @@ public class Serial implements SerialPortEventListener {
new Float(Preferences.get("serial.stopbits")).floatValue());
}
public static boolean touchPort(String iname, int irate) throws SerialException {
SerialPort port;
boolean result = false;
try {
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
CommPortIdentifier portId = (CommPortIdentifier) portList.nextElement();
if ((CommPortIdentifier.PORT_SERIAL == portId.getPortType()) && (portId.getName().equals(iname))) {
port = (SerialPort) portId.open("tap", 2000);
port.setSerialPortParams(irate, 8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
port.close();
result = true;
}
}
} catch (PortInUseException e) {
throw new SerialException(
I18n.format(_("Serial port ''{0}'' already in use. Try quitting any programs that may be using it."), iname)
);
} catch (Exception e) {
throw new SerialException(
I18n.format(_("Error touching serial port ''{0}''."), iname), e
);
}
return result;
}
public Serial(String iname, int irate,
char iparity, int idatabits, float istopbits)
throws SerialException {
@ -527,10 +553,11 @@ public class Serial implements SerialPortEventListener {
* it may be because the DLL doesn't have its exec bit set.
* Why the hell that'd be the case, who knows.
*/
static public String[] list() {
Vector list = new Vector();
static public List<String> list() {
List<String> list = new ArrayList<String>();
try {
//System.err.println("trying");
@SuppressWarnings("unchecked")
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
//System.err.println("got port list");
while (portList.hasMoreElements()) {
@ -540,7 +567,7 @@ public class Serial implements SerialPortEventListener {
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
String name = portId.getName();
list.addElement(name);
list.add(name);
}
}
@ -553,9 +580,7 @@ public class Serial implements SerialPortEventListener {
errorMessage("ports", e);
}
//System.err.println("move out");
String outgoing[] = new String[list.size()];
list.copyInto(outgoing);
return outgoing;
return list;
}

View File

@ -127,10 +127,10 @@ public class SerialMonitor extends JFrame implements MessageConsumer {
serialRates = new JComboBox();
for (int i = 0; i < serialRateStrings.length; i++)
serialRates.addItem(serialRateStrings[i] + _(" baud"));
serialRates.addItem(serialRateStrings[i] + " " + _("baud"));
serialRate = Preferences.getInteger("serial.debug_rate");
serialRates.setSelectedItem(serialRate + _(" baud"));
serialRates.setSelectedItem(serialRate + " " + _("baud"));
serialRates.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String wholeString = (String) serialRates.getSelectedItem();

View File

@ -1369,6 +1369,9 @@ public class Sketch {
for (SketchCode sc : code) {
if (sc.isExtension("ino") || sc.isExtension("pde")) {
sc.setPreprocOffset(bigCount);
// These #line directives help the compiler report errors with
// correct the filename and line number (issue 281 & 907)
bigCode.append("#line 1 \"" + sc.getFileName() + "\"\n");
bigCode.append(sc.getProgram());
bigCode.append('\n');
bigCount += sc.getLineCount();
@ -1541,54 +1544,16 @@ public class Sketch {
public RunnerException placeException(String message,
String dotJavaFilename,
int dotJavaLine) {
int codeIndex = 0; //-1;
int codeLine = -1;
// System.out.println("placing " + dotJavaFilename + " " + dotJavaLine);
// System.out.println("code count is " + getCodeCount());
// first check to see if it's a .java file
for (int i = 0; i < getCodeCount(); i++) {
SketchCode code = getCode(i);
if (!code.isExtension(getDefaultExtension())) {
if (dotJavaFilename.equals(code.getFileName())) {
codeIndex = i;
codeLine = dotJavaLine;
return new RunnerException(message, codeIndex, codeLine);
}
}
}
// If not the preprocessed file at this point, then need to get out
if (!dotJavaFilename.equals(name + ".cpp")) {
return null;
}
// if it's not a .java file, codeIndex will still be 0
// this section searches through the list of .pde files
codeIndex = 0;
for (int i = 0; i < getCodeCount(); i++) {
SketchCode code = getCode(i);
if (code.isExtension(getDefaultExtension())) {
// System.out.println("preproc offset is " + code.getPreprocOffset());
// System.out.println("looking for line " + dotJavaLine);
if (code.getPreprocOffset() <= dotJavaLine) {
codeIndex = i;
// System.out.println("i'm thinkin file " + i);
codeLine = dotJavaLine - code.getPreprocOffset();
}
}
}
// could not find a proper line number, so deal with this differently.
// but if it was in fact the .java file we're looking for, though,
// send the error message through.
// this is necessary because 'import' statements will be at a line
// that has a lower number than the preproc offset, for instance.
// if (codeLine == -1 && !dotJavaFilename.equals(name + ".java")) {
// return null;
// }
return new RunnerException(message, codeIndex, codeLine);
// Placing errors is simple, because we inserted #line directives
// into the preprocessed source. The compiler gives us correct
// the file name and line number. :-)
for (int codeIndex = 0; codeIndex < getCodeCount(); codeIndex++) {
SketchCode code = getCode(codeIndex);
if (dotJavaFilename.equals(code.getFileName())) {
return new RunnerException(message, codeIndex, dotJavaLine);
}
}
return null;
}

View File

@ -28,12 +28,18 @@
package processing.app.debug;
import java.util.ArrayList;
import java.util.List;
import processing.app.Base;
import processing.app.Preferences;
import processing.app.Serial;
import processing.app.SerialException;
import processing.app.helpers.PreferencesMap;
import processing.app.helpers.StringReplacer;
import static processing.app.I18n._;
public class BasicUploader extends Uploader {
public boolean uploadUsingPreferences(String buildPath, String className,
@ -50,7 +56,93 @@ public class BasicUploader extends Uploader {
if (usingProgrammer || prefs.get("upload.protocol") == null) {
return uploadUsingProgrammer(buildPath, className);
}
// need to do a little dance for Leonardo and derivatives:
// open then close the port at the magic baudrate (usually 1200 bps) first
// to signal to the sketch that it should reset into bootloader. after doing
// this wait a moment for the bootloader to enumerate. On Windows, also must
// deal with the fact that the COM port number changes from bootloader to
// sketch.
String use1200bpsTouch = prefs.get("upload.use_1200bps_touch");
boolean doTouch = use1200bpsTouch != null && use1200bpsTouch.equals("true");
if (doTouch) {
String uploadPort = prefs.get("serial.port");
String caterinaUploadPort = null;
try {
// Toggle 1200 bps on selected serial port to force board reset.
List<String> before = Serial.list();
if (before.contains(uploadPort)) {
if (verbose || Preferences.getBoolean("upload.verbose"))
System.out
.println(_("Forcing reset using 1200bps open/close on port ") +
uploadPort);
Serial.touchPort(uploadPort, 1200);
// Scanning for available ports seems to open the port or
// otherwise assert DTR, which would cancel the WDT reset if
// it happened within 250 ms. So we wait until the reset should
// have already occured before we start scanning.
if (!Base.isMacOS())
Thread.sleep(300);
}
// Wait for a port to appear on the list
int elapsed = 0;
while (elapsed < 10000) {
List<String> now = Serial.list();
List<String> diff = new ArrayList<String>(now);
diff.removeAll(before);
if (verbose || Preferences.getBoolean("upload.verbose")) {
System.out.print("PORTS {");
for (String p : before)
System.out.print(p + ", ");
System.out.print("} / {");
for (String p : now)
System.out.print(p + ", ");
System.out.print("} => {");
for (String p : diff)
System.out.print(p + ", ");
System.out.println("}");
}
if (diff.size() > 0) {
caterinaUploadPort = diff.get(0);
if (verbose || Preferences.getBoolean("upload.verbose"))
System.out.println("Found Leonardo upload port: " +
caterinaUploadPort);
break;
}
// Keep track of port that disappears
before = now;
Thread.sleep(250);
elapsed += 250;
// On Windows, it can take a long time for the port to disappear and
// come back, so use a longer time out before assuming that the
// selected
// port is the bootloader (not the sketch).
if (((!Base.isWindows() && elapsed >= 500) || elapsed >= 5000) &&
now.contains(uploadPort)) {
if (verbose || Preferences.getBoolean("upload.verbose"))
System.out
.println("Uploading using selected port: " + uploadPort);
caterinaUploadPort = uploadPort;
break;
}
}
if (caterinaUploadPort == null)
// Something happened while detecting port
throw new RunnerException(
_("Couldnt find a Leonardo on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initiating the upload."));
uploadPort = caterinaUploadPort;
} catch (SerialException e) {
throw new RunnerException(e.getMessage());
} catch (InterruptedException e) {
throw new RunnerException(e.getMessage());
}
prefs.put("serial.port", uploadPort);
}
prefs.put("build.path", buildPath);
prefs.put("build.project_name", className);
if (verbose)
@ -58,6 +150,7 @@ public class BasicUploader extends Uploader {
else
prefs.put("upload.verbose", prefs.get("upload.params.quiet"));
boolean uploadResult;
try {
// if (prefs.get("upload.disable_flushing") == null
// || prefs.get("upload.disable_flushing").toLowerCase().equals("false")) {
@ -66,10 +159,29 @@ public class BasicUploader extends Uploader {
String pattern = prefs.get("upload.pattern");
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
return executeUploadCommand(cmd);
uploadResult = executeUploadCommand(cmd);
} catch (Exception e) {
throw new RunnerException(e);
}
// For Leonardo wait until the bootloader serial port disconnects and the
// sketch serial port reconnects (or timeout after a few seconds if the
// sketch port never comes back). Doing this saves users from accidentally
// opening Serial Monitor on the soon-to-be-orphaned bootloader port.
try {
if (uploadResult && doTouch) {
Thread.sleep(500);
long timeout = System.currentTimeMillis() + 2000;
while (timeout > System.currentTimeMillis()) {
List<String> portList = Serial.list();
if (portList.contains(Preferences.get("serial.port")))
break;
Thread.sleep(100);
}
}
} catch (InterruptedException ex) {
}
return uploadResult;
}
public boolean uploadUsingProgrammer(String buildPath, String className)
@ -124,11 +236,14 @@ public class BasicUploader extends Uploader {
prefs.putAll(Base.getBoardPreferences());
prefs.putAll(targetPlatform.getProgrammer(programmer));
prefs.putAll(targetPlatform.getTool(prefs.get("bootloader.tool")));
if (verbose)
if (verbose) {
prefs.put("erase.verbose", prefs.get("erase.params.verbose"));
prefs.put("bootloader.verbose", prefs.get("bootloader.params.verbose"));
else
} else {
prefs.put("erase.verbose", prefs.get("erase.params.quiet"));
prefs.put("bootloader.verbose", prefs.get("bootloader.params.quiet"));
}
try {
// if (prefs.get("program.disable_flushing") == null
// || prefs.get("program.disable_flushing").toLowerCase().equals("false"))
@ -136,13 +251,11 @@ public class BasicUploader extends Uploader {
// flushSerialBuffer();
// }
prefs.put("bootloader.params", prefs.get("bootloader.erase.params"));
String pattern = prefs.get("bootloader.pattern");
String pattern = prefs.get("erase.pattern");
String[] cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
if (!executeUploadCommand(cmd))
return false;
prefs.put("bootloader.params", prefs.get("bootloader.write.params"));
pattern = prefs.get("bootloader.pattern");
cmd = StringReplacer.formatAndSplit(pattern, prefs, true);
return executeUploadCommand(cmd);

View File

@ -54,6 +54,7 @@ public class Compiler implements MessageConsumer {
private PreferencesMap prefs;
private boolean verbose;
private boolean sketchIsCompiled;
private RunnerException exception;
@ -71,6 +72,7 @@ public class Compiler implements MessageConsumer {
throws RunnerException {
sketch = _sketch;
verbose = _verbose;
sketchIsCompiled = false;
objectFiles = new ArrayList<File>();
prefs = createBuildPreferences(_buildPath, _primaryClassName);
@ -79,7 +81,7 @@ public class Compiler implements MessageConsumer {
sketch.setCompilingProgress(20);
List<String> includePaths = new ArrayList<String>();
includePaths.add(prefs.get("build.core.path"));
if (!prefs.get("build.variant.path").isEmpty())
if (prefs.get("build.variant.path").length() != 0)
includePaths.add(prefs.get("build.variant.path"));
for (File file : sketch.getImportedLibraries())
includePaths.add(file.getPath());
@ -87,6 +89,7 @@ public class Compiler implements MessageConsumer {
// 1. compile the sketch (already in the buildPath)
sketch.setCompilingProgress(30);
compileSketch(includePaths);
sketchIsCompiled = true;
// 2. compile the libraries, outputting .o files to: <buildPath>/<library>/
// Doesn't really use configPreferences
@ -117,6 +120,14 @@ public class Compiler implements MessageConsumer {
private PreferencesMap createBuildPreferences(String _buildPath,
String _primaryClassName)
throws RunnerException {
if (Base.getBoardPreferences() == null) {
RunnerException re = new RunnerException(
_("No board selected; please choose a board from the Tools > Board menu."));
re.hideStackTrace();
throw re;
}
TargetPlatform targetPlatform = Base.getTargetPlatform();
// Merge all the global preference configuration in order of priority
@ -137,12 +148,6 @@ public class Compiler implements MessageConsumer {
// Core folder
String core = p.get("build.core");
if (core == null) {
RunnerException re = new RunnerException(
_("No board selected; please choose a board from the Tools > Board menu."));
re.hideStackTrace();
throw re;
}
TargetPlatform tp;
if (!core.contains(":")) {
tp = targetPlatform;
@ -302,7 +307,7 @@ public class Compiler implements MessageConsumer {
List<String> stringList = new ArrayList<String>();
for (String string : command) {
string = string.trim();
if (!string.isEmpty())
if (string.length() != 0)
stringList.add(string);
}
command = stringList.toArray(new String[stringList.size()]);
@ -337,10 +342,8 @@ public class Compiler implements MessageConsumer {
boolean compiling = true;
while (compiling) {
try {
if (in.thread != null)
in.thread.join();
if (err.thread != null)
err.thread.join();
in.join();
err.join();
result = process.waitFor();
//System.out.println("result is " + result);
compiling = false;
@ -428,7 +431,7 @@ public class Compiler implements MessageConsumer {
if (pieces[3].trim().equals("'Udp' was not declared in this scope")) {
error = _("The Udp class has been renamed EthernetUdp.");
msg = _("\nAs of Arduino 1.0, the Udp class in the Ethernet library " +
"has been renamed to EthernetClient.\n\n");
"has been renamed to EthernetUdp.\n\n");
}
if (pieces[3].trim().equals("'class TwoWire' has no member named 'send'")) {
@ -443,14 +446,30 @@ public class Compiler implements MessageConsumer {
"to Wire.read() for consistency with other libraries.\n\n");
}
RunnerException e = sketch.placeException(error, pieces[1], PApplet.parseInt(pieces[2]) - 1);
if (pieces[3].trim().equals("'Mouse' was not declared in this scope")) {
error = _("'Mouse' only supported on the Arduino Leonardo");
//msg = _("\nThe 'Mouse' class is only supported on the Arduino Leonardo.\n\n");
}
if (pieces[3].trim().equals("'Keyboard' was not declared in this scope")) {
error = _("'Keyboard' only supported on the Arduino Leonardo");
//msg = _("\nThe 'Keyboard' class is only supported on the Arduino Leonardo.\n\n");
}
RunnerException e = null;
if (!sketchIsCompiled) {
// Place errors when compiling the sketch, but never while compiling libraries
// or the core. The user's sketch might contain the same filename!
e = sketch.placeException(error, pieces[1], PApplet.parseInt(pieces[2]) - 1);
}
// replace full file path with the name of the sketch tab (unless we're
// in verbose mode, in which case don't modify the compiler output)
if (e != null && !verbose) {
SketchCode code = sketch.getCode(e.getCodeIndex());
String fileName = code.isExtension(sketch.getDefaultExtension()) ? code.getPrettyName() : code.getFileName();
s = fileName + ":" + e.getCodeLine() + ": error: " + pieces[3] + msg;
String fileName = (code.isExtension("ino") || code.isExtension("pde")) ? code.getPrettyName() : code.getFileName();
int lineNum = e.getCodeLine() + 1;
s = fileName + ":" + lineNum + ": error: " + pieces[3] + msg;
}
if (exception == null && e != null) {
@ -590,12 +609,12 @@ public class Compiler implements MessageConsumer {
List<String> includePaths = new ArrayList<String>();
includePaths.add(corePath); // include core path only
if (!variantPath.isEmpty())
if (variantPath.length() != 0)
includePaths.add(variantPath);
List<File> coreObjectFiles = compileFiles(buildPath, new File(corePath),
true, includePaths);
if (!variantPath.isEmpty())
if (variantPath.length() != 0)
coreObjectFiles.addAll(compileFiles(buildPath, new File(variantPath),
true, includePaths));

View File

@ -85,8 +85,15 @@ public class MessageSiphon implements Runnable {
}
}
// Wait until the MessageSiphon thread is complete.
public void join() throws java.lang.InterruptedException {
// Grab a temp copy in case another thread nulls the "thread"
// member variable
Thread t = thread;
if (t != null) t.join();
}
public Thread getThread() {
return thread;
}
}
}

View File

@ -60,10 +60,8 @@ public class Sizer implements MessageConsumer {
boolean running = true;
while(running) {
try {
if (in.thread != null)
in.thread.join();
if (err.thread != null)
err.thread.join();
in.join();
err.join();
r = process.waitFor();
running = false;
} catch (InterruptedException intExc) { }

View File

@ -170,7 +170,17 @@ public abstract class Uploader implements MessageConsumer {
boolean notFoundError;
public void message(String s) {
//System.err.println("MSG: " + s);
// selectively suppress a bunch of avrdude output for AVR109/Caterina that should already be quelled but isn't
if (!Preferences.getBoolean("upload.verbose") && (
s.indexOf("Connecting to programmer:") != -1 ||
s.indexOf("Found programmer: Id = \"CATERIN\"; type = S") != -1 ||
s.indexOf("Software Version = 1.0; No Hardware Version given.") != -1 ||
s.indexOf("Programmer supports auto addr increment.") != -1 ||
s.indexOf("Programmer supports buffered memory access with buffersize=128 bytes.") != -1 ||
s.indexOf("Programmer supports the following devices:") != -1 ||
s.indexOf("Device code: 0x44") != -1))
s = "";
System.err.print(s);
// ignore cautions
@ -191,7 +201,11 @@ public abstract class Uploader implements MessageConsumer {
}
if (s.indexOf("Programmer is not responding") != -1 ||
s.indexOf("programmer is not responding") != -1 ||
s.indexOf("protocol error") != -1) {
s.indexOf("protocol error") != -1 ||
s.indexOf("avrdude: ser_open(): can't open device") != -1 ||
s.indexOf("avrdude: ser_drain(): read error") != -1 ||
s.indexOf("avrdude: ser_send(): write error") != -1 ||
s.indexOf("avrdude: error: buffered memory access not supported.") != -1) {
exception = new RunnerException(_("Problem uploading to board. See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions."));
return;
}

View File

@ -0,0 +1,33 @@
package processing.app.helpers;
import java.io.File;
import java.io.IOException;
public class FileUtils {
/**
* Checks, whether the child directory is a subdirectory of the base
* directory.
*
* @param base
* the base directory.
* @param child
* the suspected child directory.
* @return true, if the child is a subdirectory of the base directory.
* @throws IOException
* if an IOError occured during the test.
*/
public static boolean isSubDirectory(File base, File child) throws IOException {
base = base.getCanonicalFile();
child = child.getCanonicalFile();
File parentFile = child;
while (parentFile != null) {
if (base.equals(parentFile)) {
return true;
}
parentFile = parentFile.getParentFile();
}
return false;
}
}

View File

@ -29,9 +29,12 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import processing.app.Base;
import processing.core.PApplet;
public class PreferencesMap extends HashMap<String, String> {
@ -78,6 +81,25 @@ public class PreferencesMap extends HashMap<String, String> {
put(key.trim(), value.trim());
}
}
// This is needed to avoid ConcurrentAccessExceptions
Set<String> keys = new HashSet<String>(keySet());
// Override keys that have OS specific versions
for (String k : keys) {
boolean replace = false;
if (Base.isLinux() && k.endsWith(".linux"))
replace = true;
if (Base.isWindows() && k.endsWith(".windows"))
replace = true;
if (Base.isMacOS() && k.endsWith(".macos"))
replace = true;
if (replace) {
int dot = k.lastIndexOf('.');
String overridenKey = k.substring(0, dot);
put(overridenKey, get(k));
}
}
}
/**

View File

@ -58,7 +58,7 @@ public class StringReplacer {
for (String i : src.split(" ")) {
if (!escaping) {
if (!i.startsWith(quote)) {
if (!i.trim().isEmpty() || acceptEmptyArguments)
if (i.trim().length() != 0 || acceptEmptyArguments)
res.add(i);
continue;
}
@ -74,7 +74,7 @@ public class StringReplacer {
}
escapedArg += i.substring(0, i.length() - 1);
if (!escapedArg.trim().isEmpty() || acceptEmptyArguments)
if (escapedArg.trim().length() != 0 || acceptEmptyArguments)
res.add(escapedArg);
escaping = false;
}

View File

@ -205,7 +205,7 @@ public class PdePreprocessor {
for (int i = 0; i < prototypes.size(); i++) {
out.print(prototypes.get(i) + "\n");
}
out.println("#line 1");
out.print(program.substring(prototypeInsertionPoint));
}

View File

@ -834,6 +834,17 @@ public class JEditTextArea extends JComponent
return lineElement.getEndOffset();
}
/**
* Returns the end offset of the specified line, but not past the end of the text
* @param line The line
* @return The end offset of the specified line, safe to use for a selection, or -1 if the line is
* invalid.
*/
public int getSafeLineStopOffset(int line)
{
return Math.min(getLineStopOffset(line),getDocumentLength());
}
/**
* Returns the length of the specified line.
* @param line The line
@ -1144,7 +1155,7 @@ public class JEditTextArea extends JComponent
{
throw new IllegalArgumentException("Bounds out of"
+ " range: " + newStart + "," +
newEnd);
newEnd + " [" + getDocumentLength() + "]");
}
// If the new position is the same as the old, we don't
@ -1201,6 +1212,86 @@ public class JEditTextArea extends JComponent
// getLineOfOffset(end));
}
}
private boolean isWordCharacter( char ch, String noWordSep )
{
return Character.isLetterOrDigit(ch) || ch=='_' || noWordSep.indexOf(ch) != -1;
}
protected void setNewSelectionWord( int line, int offset )
{
if (getLineLength(line) == 0) {
newSelectionStart = getLineStartOffset(line);
newSelectionEnd = newSelectionStart;
return;
}
String noWordSep = (String)document.getProperty("noWordSep");
if(noWordSep == null)
noWordSep = "";
String lineText = getLineText(line);
int wordStart = 0;
int wordEnd = lineText.length();
char ch = lineText.charAt(Math.max(0,offset - 1));
// special case for whitespace (fry 0122, bug #348)
// this is really nasty.. turns out that double-clicking any non-letter
// or digit char gets lumped together.. sooo, this quickly gets messy,
// because really it needs to check whether the chars are of the same
// type.. so a double space or double - might be grouped together,
// but what about a +=1? do + and - get grouped but not the 1? blech,
// coming back to this later. it's not a difficult fix, just a
// time-consuming one to track down all the proper cases.
/*
if (ch == ' ') {
//System.out.println("yeehaa");
for(int i = offset - 1; i >= 0; i--) {
if (lineText.charAt(i) == ' ') {
wordStart = i;
} else {
break;
}
}
for(int i = offset; i < lineText.length(); i++) {
if (lineText.charAt(i) == ' ') {
wordEnd = i + 1;
} else {
break;
}
}
} else {
*/
// If the user clicked on a non-letter char,
// we select the surrounding non-letters
boolean selectNoLetter = !isWordCharacter(ch,noWordSep);
for(int i = offset - 1; i >= 0; i--) {
ch = lineText.charAt(i);
if (selectNoLetter ^ !isWordCharacter(ch,noWordSep)) {
wordStart = i + 1;
break;
}
}
for(int i = offset; i < lineText.length(); i++) {
ch = lineText.charAt(i);
if(selectNoLetter ^ !isWordCharacter(ch,noWordSep)) {
wordEnd = i;
break;
}
}
//}
int lineStart = getLineStartOffset(line);
newSelectionStart = lineStart + wordStart;
newSelectionEnd = lineStart + wordEnd;
}
/**
@ -1684,6 +1775,14 @@ public class JEditTextArea extends JComponent
protected int selectionEnd;
protected int selectionEndLine;
protected boolean biasLeft;
protected int newSelectionStart; // hack to get around lack of multiple returns in Java
protected int newSelectionEnd;
protected boolean selectWord;
protected boolean selectLine;
protected int selectionAncorStart;
protected int selectionAncorEnd;
protected int bracketPosition;
protected int bracketLine;
@ -2021,9 +2120,26 @@ public class JEditTextArea extends JComponent
{
if (popup != null && popup.isVisible()) return;
setSelectionRectangular((evt.getModifiers()
& InputEvent.CTRL_MASK) != 0);
select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY()));
if ( !selectWord && !selectLine ) {
setSelectionRectangular((evt.getModifiers()
& InputEvent.CTRL_MASK) != 0);
select(getMarkPosition(),xyToOffset(evt.getX(),evt.getY()));
} else {
int line = yToLine(evt.getY());
if ( selectWord ) {
setNewSelectionWord( line, xToOffset(line,evt.getX()) );
} else {
newSelectionStart = getLineStartOffset(line);
newSelectionEnd = getSafeLineStopOffset(line);
}
if ( newSelectionStart < selectionAncorStart ) {
select(newSelectionStart,selectionAncorEnd);
} else if ( newSelectionEnd > selectionAncorEnd ) {
select(selectionAncorStart,newSelectionEnd);
} else {
select(newSelectionStart,newSelectionEnd);
}
}
}
final Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
@ -2094,6 +2210,9 @@ public class JEditTextArea extends JComponent
int offset = xToOffset(line,evt.getX());
int dot = getLineStartOffset(line) + offset;
selectLine = false;
selectWord = false;
switch(evt.getClickCount()) {
case 1:
@ -2159,74 +2278,11 @@ public class JEditTextArea extends JComponent
bl.printStackTrace();
}
String noWordSep = (String)document.getProperty("noWordSep");
if(noWordSep == null)
noWordSep = "";
// Ok, it's not a bracket... select the word
String lineText = getLineText(line);
int wordStart = 0;
int wordEnd = lineText.length();
char ch = lineText.charAt(Math.max(0,offset - 1));
// special case for whitespace (fry 0122, bug #348)
// this is really nasty.. turns out that double-clicking any non-letter
// or digit char gets lumped together.. sooo, this quickly gets messy,
// because really it needs to check whether the chars are of the same
// type.. so a double space or double - might be grouped together,
// but what about a +=1? do + and - get grouped but not the 1? blech,
// coming back to this later. it's not a difficult fix, just a
// time-consuming one to track down all the proper cases.
/*
if (ch == ' ') {
//System.out.println("yeehaa");
for(int i = offset - 1; i >= 0; i--) {
if (lineText.charAt(i) == ' ') {
wordStart = i;
} else {
break;
}
}
for(int i = offset; i < lineText.length(); i++) {
if (lineText.charAt(i) == ' ') {
wordEnd = i + 1;
} else {
break;
}
}
} else {
*/
// If the user clicked on a non-letter char,
// we select the surrounding non-letters
boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
&& noWordSep.indexOf(ch) == -1);
for(int i = offset - 1; i >= 0; i--) {
ch = lineText.charAt(i);
if (selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
noWordSep.indexOf(ch) == -1)) {
wordStart = i + 1;
break;
}
}
for(int i = offset; i < lineText.length(); i++) {
ch = lineText.charAt(i);
if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
noWordSep.indexOf(ch) == -1)) {
wordEnd = i;
break;
}
}
//}
int lineStart = getLineStartOffset(line);
select(lineStart + wordStart,lineStart + wordEnd);
setNewSelectionWord( line, offset );
select(newSelectionStart,newSelectionEnd);
selectWord = true;
selectionAncorStart = selectionStart;
selectionAncorEnd = selectionEnd;
/*
String lineText = getLineText(line);
@ -2242,7 +2298,10 @@ public class JEditTextArea extends JComponent
private void doTripleClick(MouseEvent evt, int line,
int offset, int dot)
{
select(getLineStartOffset(line),getLineStopOffset(line)-1);
selectLine = true;
select(getLineStartOffset(line),getSafeLineStopOffset(line));
selectionAncorStart = selectionStart;
selectionAncorEnd = selectionEnd;
}
}

View File

@ -515,7 +515,10 @@ implements TabExpander, Printable
*/
public Dimension getMinimumSize()
{
return getPreferredSize();
Dimension dim = new Dimension();
dim.width = fm.charWidth('w') * 10;
dim.height = fm.getHeight() * 4;
return dim;
}
// package-private members

View File

@ -56,7 +56,7 @@ public class Archiver implements Tool {
numberFormat.setGroupingUsed(false); // no commas
numberFormat.setMinimumIntegerDigits(digits);
dateFormat = new SimpleDateFormat(_("yyMMdd"));
dateFormat = new SimpleDateFormat("yyMMdd");
}

View File

@ -8,6 +8,7 @@
<condition property="macosx"><os family="mac" /></condition>
<condition property="windows"><os family="windows" /></condition>
<condition property="linux"><os family="unix" /></condition>
<condition property="linux32"><os family="unix" arch="i386" /></condition>
<condition property="linux64"><os family="unix" arch="amd64" /></condition>
<condition property="platform"
@ -15,7 +16,7 @@
<condition property="platform"
value="windows"><os family="windows" /></condition>
<condition property="platform"
value="linux"><os family="unix" arch="i386" /></condition>
value="linux32"><os family="unix" arch="i386" /></condition>
<condition property="platform"
value="linux64"><os family="unix" arch="amd64" /></condition>
@ -281,9 +282,12 @@
<replace file="macosx/work/Arduino.app/Contents/Info.plist"
token="REVISION" value="${revision}" />
<exec executable="ditto" dir="macosx/work">
<arg line="-c -k -rsrc . ../arduino-${version}-macosx.zip" />
<exec executable="zip" dir="macosx/work">
<arg line="-q -r ../arduino-${version}-macosx.zip ." />
</exec>
<!-- <exec executable="ditto" dir="macosx/work">
<arg line="-c -k -rsrc . ../arduino-${version}-macosx.zip" />
</exec> -->
<echo>
=======================================================
@ -388,6 +392,9 @@
<param name="target.path" value="linux/work" />
</antcall>
<copy todir="linux/work" file="linux/dist/arduino" />
<chmod perm="755" file="linux/work/arduino" />
<copy todir="linux/work/hardware">
<fileset dir="linux/dist" includes="tools/**" />
</copy>
@ -404,12 +411,28 @@
<antcall target="linux-unzip-arm-toolchain" />
</target>
<target name="linux32-build" depends="linux-build" description="Build linux (32-bit) version">
<!-- Unzip AVR tools -->
<exec executable="tar" dir="linux/work/hardware">
<arg value="-xjf"/>
<arg value="../../avr_tools_linux32.tar.bz2"/>
</exec>
</target>
<target name="linux64-build" depends="linux-build" description="Build linux (64-bit) version">
<copy tofile="linux/work/hardware/tools/avrdude" file="linux/dist/tools/avrdude64" overwrite="true" />
<copy tofile="linux/work/lib/librxtxSerial.so" file="linux/dist/lib/librxtxSerial64.so" overwrite="true" />
<chmod perm="755" file="linux/work/hardware/tools/avrdude" />
<!-- Unzip AVR tools -->
<exec executable="tar" dir="linux/work/hardware">
<arg value="-xjf"/>
<arg value="../../avr_tools_linux64.tar.bz2"/>
</exec>
</target>
<target name="linux-run" depends="linux-build"
<target name="linux32-run" depends="linux32-build"
description="Run Linux (32-bit) version">
<exec executable="./linux/work/arduino" spawn="false"/>
</target>
@ -477,7 +500,7 @@
<!--
<tar compression="gzip" basedir="linux/work"
destfile="linux/arduino-${version}.tgz" />
-->
<tar compression="gzip" destfile="linux/arduino-${version}-linux.tgz">
<tarfileset dir="linux/work"
prefix="arduino-${version}"
@ -489,6 +512,18 @@
<tarfileset file="linux/work/hardware/tools/avrdude" filemode="755"
prefix="arduino-${version}/hardware/tools" />
</tar>
-->
<move file="linux/work" tofile="linux/arduino-${version}" />
<exec executable="tar" dir="linux">
<arg value="-z"/>
<arg value="-c"/>
<arg value="-f"/>
<arg value="arduino-${version}-linux.tgz"/>
<arg value="arduino-${version}"/>
</exec>
<move file="linux/arduino-${version}" tofile="linux/work" />
<echo>
=======================================================
@ -499,6 +534,8 @@
</echo>
</target>
<target name="linux32-dist" depends="linux-dist"
description="Build .tar.gz of linux version" />
<target name="linux64-dist" depends="linux-dist"
description="Build .tar.gz of linux version" />
@ -685,6 +722,7 @@
<tarfileset dir="../"
prefix="arduino-${version}"
excludes="**/*.tgz,
**/*.bz2,
**/macosx/,
**/windows/,
**/work/,

View File

@ -34,6 +34,7 @@ my $wire = create_page('Wire.html', "$ARDUINO/Reference/Wire");
my $sd = create_page('SD.html', "$ARDUINO/Reference/SD");
my $servo = create_page('Servo.html', "$ARDUINO/Reference/Servo");
my $spi = create_page('SPI.html', "$ARDUINO/Reference/SPI");
my $mousekeyboard = create_page('MouseKeyboard.html', "$ARDUINO/Reference/MouseKeyboard");
my $lcd = create_page('LiquidCrystal.html', "$ARDUINO/Reference/LiquidCrystal");
my $ethernet = create_page('Ethernet.html', "$ARDUINO/Reference/Ethernet");
my $serial = create_page('Serial.html', "$ARDUINO/Reference/Serial");
@ -48,6 +49,8 @@ create_linked_pages($servo, qr!$ARDUINO/Reference/(Servo\w+)!, '%%.html')
create_linked_pages($sd, qr!$ARDUINO/Reference/(SD\w+)!, '%%.html');
create_linked_pages($sd, qr!$ARDUINO/Reference/(File\w+)!, '%%.html');
create_linked_pages($spi, qr!$ARDUINO/Reference/(SPI\w+)!, '%%.html');
create_linked_pages($mousekeyboard, qr!$ARDUINO/Reference/(Mouse\w+)!, '%%.html');
create_linked_pages($mousekeyboard, qr!$ARDUINO/Reference/(Keyboard\w+)!, '%%.html');
create_linked_pages($lcd, qr!$ARDUINO/Reference/(LiquidCrystal\w+)!, '%%.html');
create_linked_pages($ethernet, qr!$ARDUINO/Reference/(Ethernet\w+)!, '%%.html');
create_linked_pages($ethernet, qr!$ARDUINO/Reference/(Server\w+)!, '%%.html');

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,22 @@
/*
AnalogReadSerial
Reads an analog input on pin 0, prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(sensorValue);
delay(1); // delay in between reads for stability
}

View File

@ -0,0 +1,24 @@
/*
Blink
Turns on an LED on for one second, then off for one second, repeatedly.
This example code is in the public domain.
*/
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(led, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}

View File

@ -0,0 +1,29 @@
/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial monitor
This example code is in the public domain.
*/
// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// make the pushbutton's pin an input:
pinMode(pushButton, INPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input pin:
int buttonState = digitalRead(pushButton);
// print out the state of the button:
Serial.println(buttonState);
delay(1); // delay in between reads for stability
}

View File

@ -5,19 +5,22 @@
using the analogWrite() function.
This example code is in the public domain.
*/
int led = 9; // the pin that the LED is attached to
int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by
// the setup routine runs once when you press reset:
void setup() {
// declare pin 9 to be an output:
pinMode(9, OUTPUT);
pinMode(led, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
// set the brightness of pin 9:
analogWrite(9, brightness);
analogWrite(led, brightness);
// change the brightness for next time through the loop:
brightness = brightness + fadeAmount;
@ -29,3 +32,4 @@ void loop() {
// wait for 30 milliseconds to see the dimming effect
delay(30);
}

View File

@ -0,0 +1,23 @@
/*
ReadAnalogVoltage
Reads an analog input on pin 0, converts it to voltage, and prints the result to the serial monitor.
Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
This example code is in the public domain.
*/
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float voltage = sensorValue * (5.0 / 1023.0);
// print out the value you read:
Serial.println(voltage);
}

Some files were not shown because too many files have changed in this diff Show More