mirror of https://github.com/noisymime/Arduino.git
Merged master
This commit is contained in:
commit
06c0928192
|
@ -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/
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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(
|
||||
_("Couldn’t 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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) { }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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/,
|
||||
|
|
|
@ -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.
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
Loading…
Reference in New Issue