librariesByName = indexer.getIndex().find(libraryToInstallParts[0]);
+ Collections.sort(librariesByName, new DownloadableContributionVersionComparator());
+ if (!librariesByName.isEmpty()) {
+ selected = librariesByName.get(librariesByName.size() - 1);
+ }
+ }
+ if (selected == null) {
+ System.out.println(_("Selected library is not available"));
System.exit(1);
-
- // No errors exit gracefully
- System.exit(0);
- }
- else if (parser.isGuiMode()) {
- // Check if there were previously opened sketches to be restored
- restoreSketches();
-
- // Create a new empty window (will be replaced with any files to be opened)
- if (editors.isEmpty()) {
- handleNew();
}
- // Check for updates
- if (Preferences.getBoolean("update.check")) {
- new UpdateCheck(this);
- }
- }
- else if (parser.isNoOpMode()) {
- // Do nothing (intended for only changing preferences)
- System.exit(0);
- }
- else if (parser.isGetPrefMode()) {
- String value = Preferences.get(parser.getGetPref(), null);
- if (value != null) {
- System.out.println(value);
- System.exit(0);
+ ContributedLibrary installed = indexer.getIndex().getInstalled(libraryToInstallParts[0]);
+ if (selected.isReadOnly()) {
+ installer.remove(installed);
} else {
- System.exit(4);
+ installer.install(selected, installed);
}
}
+
+ System.exit(0);
+
+ } else if (parser.isVerifyOrUploadMode()) {
+ splashScreenHelper.close();
+ // Set verbosity for command line build
+ PreferencesData.set("build.verbose", "" + parser.isDoVerboseBuild());
+ PreferencesData.set("upload.verbose", "" + parser.isDoVerboseUpload());
+ PreferencesData.set("runtime.preserve.temp.files", Boolean.toString(parser.isPreserveTempFiles()));
+
+ // Make sure these verbosity preferences are only for the
+ // current session
+ PreferencesData.setDoSave(false);
+
+ Editor editor = editors.get(0);
+
+ if (parser.isUploadMode()) {
+ splashScreenHelper.splashText(_("Verifying and uploading..."));
+ editor.exportHandler.run();
+ } else {
+ splashScreenHelper.splashText(_("Verifying..."));
+ editor.runHandler.run();
+ }
+
+ // Error during build or upload
+ int res = editor.status.mode;
+ if (res == EditorStatus.ERR)
+ System.exit(1);
+
+ // No errors exit gracefully
+ System.exit(0);
+ } else if (parser.isGuiMode()) {
+ splashScreenHelper.splashText(_("Starting..."));
+
+ installKeyboardInputMap();
+
+ // Check if there were previously opened sketches to be restored
+ restoreSketches();
+
+ // Create a new empty window (will be replaced with any files to be opened)
+ if (editors.isEmpty()) {
+ handleNew();
+ }
+
+ // Check for updates
+ if (PreferencesData.getBoolean("update.check")) {
+ new UpdateCheck(this);
+ }
+
+ new Thread(new BuiltInCoreIsNewerCheck(this)).start();
+
+ } else if (parser.isNoOpMode()) {
+ // Do nothing (intended for only changing preferences)
+ System.exit(0);
+ } else if (parser.isGetPrefMode()) {
+ String value = PreferencesData.get(parser.getGetPref(), null);
+ if (value != null) {
+ System.out.println(value);
+ System.exit(0);
+ } else {
+ System.exit(4);
+ }
+ }
+ }
+
+ private void installKeyboardInputMap() {
+ UIManager.put("RSyntaxTextAreaUI.inputMap", new SketchTextAreaDefaultInputMap());
}
/**
@@ -318,7 +514,8 @@ public class Base {
* sketch that was used (if any), and restores other Editor settings.
* The complement to "storePreferences", this is called when the
* application is first launched.
- * @throws Exception
+ *
+ * @throws Exception
*/
protected boolean restoreSketches() throws Exception {
// figure out window placement
@@ -326,11 +523,11 @@ public class Base {
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
boolean windowPositionValid = true;
- if (Preferences.get("last.screen.height") != null) {
+ if (PreferencesData.get("last.screen.height") != null) {
// if screen size has changed, the window coordinates no longer
// make sense, so don't use them unless they're identical
- int screenW = Preferences.getInteger("last.screen.width");
- int screenH = Preferences.getInteger("last.screen.height");
+ int screenW = PreferencesData.getInteger("last.screen.width");
+ int screenH = PreferencesData.getInteger("last.screen.height");
if ((screen.width != screenW) || (screen.height != screenH)) {
windowPositionValid = false;
@@ -351,10 +548,10 @@ public class Base {
// If !windowPositionValid, then ignore the coordinates found for each.
// Save the sketch path and window placement for each open sketch
- int count = Preferences.getInteger("last.sketch.count");
+ int count = PreferencesData.getInteger("last.sketch.count");
int opened = 0;
for (int i = 0; i < count; i++) {
- String path = Preferences.get("last.sketch" + i + ".path");
+ String path = PreferencesData.get("last.sketch" + i + ".path");
if (BaseNoGui.getPortableFolder() != null) {
File absolute = new File(BaseNoGui.getPortableFolder(), path);
try {
@@ -365,7 +562,7 @@ public class Base {
}
int[] location;
if (windowPositionValid) {
- String locationStr = Preferences.get("last.sketch" + i + ".location");
+ String locationStr = PreferencesData.get("last.sketch" + i + ".location");
location = PApplet.parseInt(PApplet.split(locationStr, ','));
} else {
location = nextEditorLocation();
@@ -386,8 +583,8 @@ public class Base {
protected void storeSketches() {
// Save the width and height of the screen
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- Preferences.setInteger("last.screen.width", screen.width);
- Preferences.setInteger("last.screen.height", screen.height);
+ PreferencesData.setInteger("last.screen.width", screen.width);
+ PreferencesData.setInteger("last.screen.height", screen.height);
String untitledPath = untitledFolder.getAbsolutePath();
@@ -398,7 +595,7 @@ public class Base {
// In case of a crash, save untitled sketches if they contain changes.
// (Added this for release 0158, may not be a good idea.)
if (path.startsWith(untitledPath) &&
- !editor.getSketch().isModified()) {
+ !editor.getSketch().isModified()) {
continue;
}
if (BaseNoGui.getPortableFolder() != null) {
@@ -406,14 +603,14 @@ public class Base {
if (path == null)
continue;
}
- Preferences.set("last.sketch" + index + ".path", path);
+ PreferencesData.set("last.sketch" + index + ".path", path);
int[] location = editor.getPlacement();
String locationStr = PApplet.join(PApplet.str(location), ",");
- Preferences.set("last.sketch" + index + ".location", locationStr);
+ PreferencesData.set("last.sketch" + index + ".location", locationStr);
index++;
}
- Preferences.setInteger("last.sketch.count", index);
+ PreferencesData.setInteger("last.sketch.count", index);
}
@@ -424,13 +621,12 @@ public class Base {
String untitledPath = untitledFolder.getAbsolutePath();
if (path.startsWith(untitledPath)) {
path = "";
- } else
- if (BaseNoGui.getPortableFolder() != null) {
+ } else if (BaseNoGui.getPortableFolder() != null) {
path = FileUtils.relativePath(BaseNoGui.getPortableFolder().toString(), path);
if (path == null)
path = "";
}
- Preferences.set("last.sketch" + index + ".path", path);
+ PreferencesData.set("last.sketch" + index + ".path", path);
}
@@ -469,16 +665,16 @@ public class Base {
protected int[] nextEditorLocation() {
- int defaultWidth = Preferences.getInteger("editor.window.width.default");
- int defaultHeight = Preferences.getInteger("editor.window.height.default");
+ int defaultWidth = PreferencesData.getInteger("editor.window.width.default");
+ int defaultHeight = PreferencesData.getInteger("editor.window.height.default");
if (activeEditor == null) {
Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getBounds();
// If no current active editor, use default placement
- return new int[] {
- (screen.width - defaultWidth) / 2,
- (screen.height - defaultHeight) / 2,
- defaultWidth, defaultHeight, 0
+ return new int[]{
+ (screen.width - defaultWidth) / 2,
+ (screen.height - defaultHeight) / 2,
+ defaultWidth, defaultHeight, 0
};
} else {
@@ -497,14 +693,14 @@ public class Base {
location[1] += OVER;
if (location[0] == OVER ||
- location[2] == OVER ||
- location[0] + location[2] > screen.width ||
- location[1] + location[3] > screen.height) {
+ location[2] == OVER ||
+ location[0] + location[2] > screen.width ||
+ location[1] + location[3] > screen.height) {
// Warp the next window to a randomish location on screen.
- return new int[] {
- (int) (Math.random() * (screen.width - defaultWidth)),
- (int) (Math.random() * (screen.height - defaultHeight)),
- defaultWidth, defaultHeight, 0
+ return new int[]{
+ (int) (Math.random() * (screen.width - defaultWidth)),
+ (int) (Math.random() * (screen.height - defaultHeight)),
+ defaultWidth, defaultHeight, 0
};
}
@@ -519,14 +715,15 @@ public class Base {
boolean breakTime = false;
String[] months = {
- "jan", "feb", "mar", "apr", "may", "jun",
- "jul", "aug", "sep", "oct", "nov", "dec"
+ "jan", "feb", "mar", "apr", "may", "jun",
+ "jul", "aug", "sep", "oct", "nov", "dec"
};
/**
* Handle creating a sketch folder, return its base .pde file
* or null if the operation was canceled.
- * @param shift whether shift is pressed, which will invert prompt setting
+ *
+ * @param shift whether shift is pressed, which will invert prompt setting
* @param noPrompt disable prompt, no matter the setting
*/
protected File createNewUntitled() throws IOException {
@@ -552,12 +749,12 @@ public class Base {
// In 0159, avoid running past z by sending people outdoors.
if (!breakTime) {
showWarning(_("Time for a Break"),
- _("You've reached the limit for auto naming of new sketches\n" +
- "for the day. How about going for a walk instead?"), null);
+ _("You've reached the limit for auto naming of new sketches\n" +
+ "for the day. How about going for a walk instead?"), null);
breakTime = true;
} else {
showWarning(_("Sunshine"),
- _("No really, time for some fresh air for you."), null);
+ _("No really, time for some fresh air for you."), null);
}
return null;
}
@@ -582,7 +779,8 @@ public class Base {
/**
* Create a new untitled document in a new sketch window.
- * @throws Exception
+ *
+ * @throws Exception
*/
public void handleNew() throws Exception {
try {
@@ -633,6 +831,7 @@ public class Base {
/**
* Open a sketch, replacing the sketch in the current window.
+ *
* @param path Location of the primary pde file for the sketch.
*/
public void handleOpenReplace(File file) {
@@ -652,12 +851,13 @@ public class Base {
/**
* Prompt for a sketch to open, and open it in a new window.
- * @throws Exception
+ *
+ * @throws Exception
*/
public void handleOpenPrompt() throws Exception {
// get the frontmost window frame for placing file dialog
FileDialog fd = new FileDialog(activeEditor, _("Open an Arduino sketch..."), FileDialog.LOAD);
- File lastFolder = new File(Preferences.get("last.folder", getSketchbookFolder().getAbsolutePath()));
+ File lastFolder = new File(PreferencesData.get("last.folder", getSketchbookFolder().getAbsolutePath()));
if (lastFolder.exists() && lastFolder.isFile()) {
lastFolder = lastFolder.getParentFile();
}
@@ -681,17 +881,18 @@ public class Base {
File inputFile = new File(directory, filename);
- Preferences.set("last.folder", inputFile.getAbsolutePath());
+ PreferencesData.set("last.folder", inputFile.getAbsolutePath());
handleOpen(inputFile);
}
/**
* Open a sketch in a new window.
+ *
* @param file File to open
* @return the Editor object, so that properties (like 'untitled')
- * can be set by the caller
- * @throws Exception
+ * can be set by the caller
+ * @throws Exception
*/
public Editor handleOpen(File file) throws Exception {
return handleOpen(file, nextEditorLocation(), true);
@@ -777,6 +978,7 @@ public class Base {
/**
* Close a sketch as specified by its editor window.
+ *
* @param editor Editor object of the sketch to be closed.
* @return true if succeeded in closing, false if canceled.
*/
@@ -796,26 +998,26 @@ public class Base {
// if (Preferences.getBoolean("sketchbook.closing_last_window_quits") ||
// (editor.untitled && !editor.getSketch().isModified())) {
if (OSUtils.isMacOS()) {
- Object[] options = { "OK", "Cancel" };
+ Object[] options = {"OK", "Cancel"};
String prompt =
- _(" " +
- " " +
- "Are you sure you want to Quit?" +
- "Closing the last open sketch will quit Arduino.");
+ _(" " +
+ "
" +
+ "Are you sure you want to Quit?" +
+ "Closing the last open sketch will quit Arduino.");
int result = JOptionPane.showOptionDialog(editor,
- prompt,
- _("Quit"),
- JOptionPane.YES_NO_OPTION,
- JOptionPane.QUESTION_MESSAGE,
- null,
- options,
- options[0]);
+ prompt,
+ _("Quit"),
+ JOptionPane.YES_NO_OPTION,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ options,
+ options[0]);
if (result == JOptionPane.NO_OPTION ||
- result == JOptionPane.CLOSED_OPTION) {
+ result == JOptionPane.CLOSED_OPTION) {
return false;
}
}
@@ -830,7 +1032,7 @@ public class Base {
storeSketches();
// Save out the current prefs state
- Preferences.save();
+ PreferencesData.save();
// Since this wasn't an actual Quit event, call System.exit()
System.exit(0);
@@ -858,6 +1060,7 @@ public class Base {
/**
* Handler for File → Quit.
+ *
* @return false if canceled, true otherwise.
*/
public boolean handleQuit() {
@@ -876,7 +1079,7 @@ public class Base {
editor.internalCloseRunner();
}
// Save out the current prefs state
- Preferences.save();
+ PreferencesData.save();
if (!OSUtils.isMacOS()) {
// If this was fired from the menu or an AppleEvent (the Finder),
@@ -891,6 +1094,7 @@ public class Base {
/**
* Attempt to close each open sketch in preparation for quitting.
+ *
* @return false if canceled along the way
*/
protected boolean handleQuitEach() {
@@ -916,7 +1120,7 @@ public class Base {
* Asynchronous version of menu rebuild to be used on save and rename
* to prevent the interface from locking up until the menus are done.
*/
- protected void rebuildSketchbookMenus() {
+ public void rebuildSketchbookMenus() {
//System.out.println("async enter");
//new Exception().printStackTrace();
SwingUtilities.invokeLater(new Runnable() {
@@ -938,14 +1142,14 @@ public class Base {
// Add the single "Open" item
item = Editor.newJMenuItem(_("Open..."), 'O');
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- try {
- handleOpenPrompt();
- } catch (Exception e1) {
- e1.printStackTrace();
- }
+ public void actionPerformed(ActionEvent e) {
+ try {
+ handleOpenPrompt();
+ } catch (Exception e1) {
+ e1.printStackTrace();
}
- });
+ }
+ });
menu.add(item);
menu.addSeparator();
@@ -971,7 +1175,7 @@ public class Base {
//System.out.println("rebuilding sketchbook menu");
//new Exception().printStackTrace();
try {
- menu.removeAll();
+ menu.removeAll();
addSketches(menu, getSketchbookFolder(), false);
//addSketches(menu, getSketchbookFolder());
} catch (IOException e) {
@@ -980,15 +1184,15 @@ public class Base {
}
public LibraryList getIDELibs() {
- if (getLibraries() == null)
- return new LibraryList();
- LibraryList res = new LibraryList(getLibraries());
- res.removeAll(getUserLibs());
- return res;
+ LibraryList installedLibraries = new LibraryList(BaseNoGui.librariesIndexer.getInstalledLibraries());
+ List libs = new LinkedList(Collections2.filter(new LinkedList(installedLibraries), Predicates.not(CONTRIBUTED)));
+ return new LibraryList(libs);
}
public LibraryList getUserLibs() {
- return BaseNoGui.getUserLibs();
+ LibraryList installedLibraries = new LibraryList(BaseNoGui.librariesIndexer.getInstalledLibraries());
+ List libs = new LinkedList(Collections2.filter(new LinkedList(installedLibraries), CONTRIBUTED));
+ return new LibraryList(libs);
}
public void rebuildImportMenu(JMenu importMenu) {
@@ -996,7 +1200,16 @@ public class Base {
return;
importMenu.removeAll();
- JMenuItem addLibraryMenuItem = new JMenuItem(_("Add Library..."));
+ JMenuItem menu = new JMenuItem(_("Manage Libraries..."));
+ menu.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ openManageLibrariesDialog();
+ }
+ });
+ importMenu.add(menu);
+ importMenu.addSeparator();
+
+ JMenuItem addLibraryMenuItem = new JMenuItem(_("Add .ZIP Library..."));
addLibraryMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Base.this.handleAddLibrary();
@@ -1007,31 +1220,34 @@ public class Base {
});
importMenu.add(addLibraryMenuItem);
importMenu.addSeparator();
-
+
// Split between user supplied libraries and IDE libraries
TargetPlatform targetPlatform = getTargetPlatform();
-
+
if (targetPlatform != null) {
LibraryList ideLibs = getIDELibs();
LibraryList userLibs = getUserLibs();
try {
// Find the current target. Get the platform, and then select the
// correct name and core path.
- PreferencesMap prefs = targetPlatform.getPreferences();
- if (prefs != null) {
- String platformName = prefs.get("name");
- if (platformName != null) {
- JMenuItem platformItem = new JMenuItem(_(platformName));
- platformItem.setEnabled(false);
- importMenu.add(platformItem);
- }
- }
+ String platformNameLabel;
+ platformNameLabel = StringUtils.capitalize(targetPlatform.getContainerPackage().getId()) + "/" + StringUtils.capitalize(targetPlatform.getId());
+ platformNameLabel = I18n.format(_("{0} libraries"), platformNameLabel);
+ JMenuItem platformItem = new JMenuItem(_(platformNameLabel));
+ platformItem.setEnabled(false);
+ importMenu.add(platformItem);
+
if (ideLibs.size() > 0) {
- importMenu.addSeparator();
addLibraries(importMenu, ideLibs);
}
+
if (userLibs.size() > 0) {
- importMenu.addSeparator();
+ if (ideLibs.size() > 0) {
+ importMenu.addSeparator();
+ }
+ JMenuItem contributedLibraryItem = new JMenuItem(_("Contributed libraries"));
+ contributedLibraryItem.setEnabled(false);
+ importMenu.add(contributedLibraryItem);
addLibraries(importMenu, userLibs);
}
} catch (IOException e) {
@@ -1053,14 +1269,14 @@ public class Base {
// Add examples from libraries
LibraryList ideLibs = getIDELibs();
ideLibs.sort();
- for (Library lib : ideLibs)
+ for (UserLibrary lib : ideLibs)
addSketchesSubmenu(menu, lib, false);
LibraryList userLibs = getUserLibs();
- if (userLibs.size()>0) {
+ if (userLibs.size() > 0) {
menu.addSeparator();
userLibs.sort();
- for (Library lib : userLibs)
+ for (UserLibrary lib : userLibs)
addSketchesSubmenu(menu, lib, false);
}
} catch (IOException e) {
@@ -1068,14 +1284,6 @@ public class Base {
}
}
- public LibraryList scanLibraries(List folders) throws IOException {
- return BaseNoGui.scanLibraries(folders);
- }
-
- public LibraryList scanLibraries(File folder) throws IOException {
- return BaseNoGui.scanLibraries(folder);
- }
-
public void onBoardOrPortChange() {
BaseNoGui.onBoardOrPortChange();
@@ -1084,60 +1292,136 @@ public class Base {
editor.onBoardOrPortChange();
}
- public void rebuildBoardsMenu(JMenu toolsMenu, Editor editor) throws Exception {
- // If there are no platforms installed skip menu creation
+ private void openManageLibrariesDialog() {
+ @SuppressWarnings("serial")
+ LibraryManagerUI managerUI = new LibraryManagerUI(activeEditor) {
+ @Override
+ protected void onIndexesUpdated() throws Exception {
+ BaseNoGui.initPackages();
+ rebuildBoardsMenu();
+ onBoardOrPortChange();
+ setIndexer(BaseNoGui.librariesIndexer);
+ }
+ };
+ managerUI.setLocationRelativeTo(activeEditor);
+ managerUI.setIndexer(BaseNoGui.librariesIndexer);
+ managerUI.setVisible(true);
+ // Manager dialog is modal, waits here until closed
+
+ //handleAddLibrary();
+ onBoardOrPortChange();
+ rebuildImportMenu(Editor.importMenu);
+ rebuildExamplesMenu(Editor.examplesMenu);
+ }
+
+ private void openInstallBoardDialog(final String filterText) throws Exception {
+ // Create dialog for contribution manager
+ @SuppressWarnings("serial")
+ ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor) {
+ @Override
+ protected void onIndexesUpdated() throws Exception {
+ BaseNoGui.initPackages();
+ rebuildBoardsMenu();
+ setIndexer(BaseNoGui.indexer);
+ if (StringUtils.isNotEmpty(filterText)) {
+ setFilterText(filterText);
+ }
+
+ }
+ };
+ managerUI.setLocationRelativeTo(activeEditor);
+ managerUI.setIndexer(BaseNoGui.indexer);
+ managerUI.setVisible(true);
+ // Installer dialog is modal, waits here until closed
+
+ // Reload all boards (that may have been installed/updated/removed)
+ BaseNoGui.initPackages();
+ rebuildBoardsMenu();
+ onBoardOrPortChange();
+ }
+
+ public void rebuildBoardsMenu() throws Exception {
+ boardsCustomMenus = new LinkedList();
+
+ // The first custom menu is the "Board" selection submenu
+ JMenu boardMenu = new JMenu(_("Board"));
+ boardMenu.putClientProperty("removeOnWindowDeactivation", true);
+ MenuScroller.setScrollerFor(boardMenu);
+
+ openBoardsManager = new AbstractAction(_("Boards Manager...")) {
+ public void actionPerformed(ActionEvent actionevent) {
+ String filterText = "";
+ if (actionevent instanceof cc.arduino.view.Event) {
+ filterText = ((Event) actionevent).getPayload().get("filterText").toString();
+ }
+ try {
+ openInstallBoardDialog(filterText);
+ } catch (Exception e) {
+ //TODO show error
+ e.printStackTrace();
+ }
+ }
+ };
+ boardMenu.add(new JMenuItem(openBoardsManager));
+ boardsCustomMenus.add(boardMenu);
+
+ // If there are no platforms installed we are done
if (BaseNoGui.packages.size() == 0)
return;
- JMenu boardsMenu = getBoardCustomMenu();
+ // Separate "Install boards..." command from installed boards
+ boardMenu.add(new JSeparator());
- boolean first = true;
+ // Generate custom menus for all platforms
+ Set customMenusTitles = new HashSet();
+ for (TargetPackage targetPackage : BaseNoGui.packages.values()) {
+ for (TargetPlatform targetPlatform : targetPackage.platforms()) {
+ customMenusTitles.addAll(targetPlatform.getCustomMenus().values());
+ }
+ }
+ for (String customMenuTitle : customMenusTitles) {
+ JMenu customMenu = new JMenu(_(customMenuTitle));
+ customMenu.putClientProperty("removeOnWindowDeactivation", true);
+ boardsCustomMenus.add(customMenu);
+ }
List menuItemsToClickAfterStartup = new LinkedList();
ButtonGroup boardsButtonGroup = new ButtonGroup();
Map buttonGroupsMap = new HashMap();
- // Generate custom menus for all platforms
- Set titles = new HashSet();
- for (TargetPackage targetPackage : BaseNoGui.packages.values()) {
- for (TargetPlatform targetPlatform : targetPackage.platforms())
- titles.addAll(targetPlatform.getCustomMenus().values());
- }
- for (String title : titles)
- makeBoardCustomMenu(toolsMenu, _(title));
-
// Cycle through all packages
+ boolean first = true;
for (TargetPackage targetPackage : BaseNoGui.packages.values()) {
// For every package cycle through all platform
for (TargetPlatform targetPlatform : targetPackage.platforms()) {
// Add a separator from the previous platform
if (!first)
- boardsMenu.add(new JSeparator());
+ boardMenu.add(new JSeparator());
first = false;
// Add a title for each platform
- String platformLabel = targetPlatform.getPreferences().get("name");
+ String platformLabel = targetPlatform.getPreferences().get("name");
if (platformLabel != null && !targetPlatform.getBoards().isEmpty()) {
JMenuItem menuLabel = new JMenuItem(_(platformLabel));
menuLabel.setEnabled(false);
- boardsMenu.add(menuLabel);
+ boardMenu.add(menuLabel);
}
// Cycle through all boards of this platform
for (TargetBoard board : targetPlatform.getBoards().values()) {
- JMenuItem item = createBoardMenusAndCustomMenus(menuItemsToClickAfterStartup,
- buttonGroupsMap,
- board, targetPlatform, targetPackage);
- boardsMenu.add(item);
+ JMenuItem item = createBoardMenusAndCustomMenus(boardsCustomMenus, menuItemsToClickAfterStartup,
+ buttonGroupsMap,
+ board, targetPlatform, targetPackage);
+ boardMenu.add(item);
boardsButtonGroup.add(item);
}
}
}
if (menuItemsToClickAfterStartup.isEmpty()) {
- menuItemsToClickAfterStartup.add(selectFirstEnabledMenuItem(boardsMenu));
+ menuItemsToClickAfterStartup.add(selectFirstEnabledMenuItem(boardMenu));
}
for (JMenuItem menuItemToClick : menuItemsToClickAfterStartup) {
@@ -1147,24 +1431,24 @@ public class Base {
}
private JRadioButtonMenuItem createBoardMenusAndCustomMenus(
- List menuItemsToClickAfterStartup,
+ final List boardsCustomMenus, List menuItemsToClickAfterStartup,
Map buttonGroupsMap,
TargetBoard board, TargetPlatform targetPlatform, TargetPackage targetPackage)
- throws Exception {
- String selPackage = Preferences.get("target_package");
- String selPlatform = Preferences.get("target_platform");
- String selBoard = Preferences.get("board");
+ throws Exception {
+ String selPackage = PreferencesData.get("target_package");
+ String selPlatform = PreferencesData.get("target_platform");
+ String selBoard = PreferencesData.get("board");
String boardId = board.getId();
String packageName = targetPackage.getId();
String platformName = targetPlatform.getId();
-
+
// Setup a menu item for the current board
@SuppressWarnings("serial")
Action action = new AbstractAction(board.getName()) {
public void actionPerformed(ActionEvent actionevent) {
- selectBoard((TargetBoard)getValue("b"));
- filterVisibilityOfSubsequentBoardMenus((TargetBoard)getValue("b"), 1);
+ selectBoard((TargetBoard) getValue("b"));
+ filterVisibilityOfSubsequentBoardMenus(boardsCustomMenus, (TargetBoard) getValue("b"), 1);
onBoardOrPortChange();
rebuildImportMenu(Editor.importMenu);
@@ -1176,7 +1460,7 @@ public class Base {
JRadioButtonMenuItem item = new JRadioButtonMenuItem(action);
if (selBoard.equals(boardId) && selPackage.equals(packageName)
- && selPlatform.equals(platformName)) {
+ && selPlatform.equals(platformName)) {
menuItemsToClickAfterStartup.add(item);
}
@@ -1184,14 +1468,14 @@ public class Base {
for (final String menuId : customMenus.keySet()) {
String title = customMenus.get(menuId);
JMenu menu = getBoardCustomMenu(_(title));
-
+
if (board.hasMenu(menuId)) {
PreferencesMap boardCustomMenu = board.getMenuLabels(menuId);
for (String customMenuOption : boardCustomMenu.keySet()) {
@SuppressWarnings("serial")
Action subAction = new AbstractAction(_(boardCustomMenu.get(customMenuOption))) {
public void actionPerformed(ActionEvent e) {
- Preferences.set("custom_" + menuId, ((TargetBoard)getValue("board")).getId() + "_" + getValue("custom_menu_option"));
+ PreferencesData.set("custom_" + menuId, ((TargetBoard) getValue("board")).getId() + "_" + getValue("custom_menu_option"));
onBoardOrPortChange();
}
};
@@ -1206,20 +1490,21 @@ public class Base {
menu.add(subItem);
buttonGroupsMap.get(menuId).add(subItem);
- String selectedCustomMenuEntry = Preferences.get("custom_" + menuId);
+ String selectedCustomMenuEntry = PreferencesData.get("custom_" + menuId);
if (selBoard.equals(boardId) && (boardId + "_" + customMenuOption).equals(selectedCustomMenuEntry)) {
menuItemsToClickAfterStartup.add(subItem);
}
}
}
}
-
+
return item;
}
- private static void filterVisibilityOfSubsequentBoardMenus(TargetBoard board, int fromIndex) {
- for (int i = fromIndex; i < Editor.boardsMenus.size(); i++) {
- JMenu menu = Editor.boardsMenus.get(i);
+ private void filterVisibilityOfSubsequentBoardMenus(List boardsCustomMenus, TargetBoard board,
+ int fromIndex) {
+ for (int i = fromIndex; i < boardsCustomMenus.size(); i++) {
+ JMenu menu = boardsCustomMenus.get(i);
for (int m = 0; m < menu.getItemCount(); m++) {
JMenuItem menuItem = menu.getItem(m);
menuItem.setVisible(menuItem.getAction().getValue("board").equals(board));
@@ -1245,21 +1530,12 @@ public class Base {
return false;
}
- private JMenu makeBoardCustomMenu(JMenu toolsMenu, String label) {
- JMenu menu = new JMenu(label);
- Editor.boardsMenus.add(menu);
- toolsMenu.add(menu);
- return menu;
- }
-
- private JMenu getBoardCustomMenu() throws Exception {
- return getBoardCustomMenu(_("Board"));
- }
-
private JMenu getBoardCustomMenu(String label) throws Exception {
- for (JMenu menu : Editor.boardsMenus)
- if (label.equals(menu.getText()))
+ for (JMenu menu : boardsCustomMenus) {
+ if (label.equals(menu.getText())) {
return menu;
+ }
+ }
throw new Exception("Custom menu not found!");
}
@@ -1285,7 +1561,7 @@ public class Base {
}
private static JMenuItem selectFirstEnabledMenuItem(JMenu menu) {
- for (int i = 0; i < menu.getItemCount(); i++) {
+ for (int i = 1; i < menu.getItemCount(); i++) {
JMenuItem item = menu.getItem(i);
if (item != null && item.isEnabled()) {
return item;
@@ -1313,14 +1589,14 @@ public class Base {
@SuppressWarnings("serial")
AbstractAction action = new AbstractAction(targetPlatform
- .getProgrammer(programmer).get("name")) {
+ .getProgrammer(programmer).get("name")) {
public void actionPerformed(ActionEvent actionevent) {
- Preferences.set("programmer", "" + getValue("id"));
+ PreferencesData.set("programmer", "" + getValue("id"));
}
};
action.putValue("id", id);
JMenuItem item = new JRadioButtonMenuItem(action);
- if (Preferences.get("programmer").equals(id))
+ if (PreferencesData.get("programmer").equals(id))
item.setSelected(true);
group.add(item);
menu.add(item);
@@ -1370,15 +1646,15 @@ public class Base {
return ifound;
}
- private boolean addSketchesSubmenu(JMenu menu, Library lib,
+ private boolean addSketchesSubmenu(JMenu menu, UserLibrary lib,
boolean replaceExisting)
- throws IOException {
- return addSketchesSubmenu(menu, lib.getName(), lib.getFolder(),
- replaceExisting);
+ throws IOException {
+ return addSketchesSubmenu(menu, lib.getName(), lib.getInstalledFolder(),
+ replaceExisting);
}
private boolean addSketchesSubmenu(JMenu menu, String name, File folder,
- final boolean replaceExisting) throws IOException {
+ final boolean replaceExisting) throws IOException {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -1400,7 +1676,7 @@ public class Base {
}
} else {
showWarning(_("Sketch Does Not Exist"),
- _("The selected sketch no longer exists.\n"
+ _("The selected sketch no longer exists.\n"
+ "You may need to restart Arduino to update\n"
+ "the sketchbook menu."), null);
}
@@ -1417,13 +1693,13 @@ public class Base {
if (!BaseNoGui.isSanitaryName(name)) {
if (!builtOnce) {
String complaining = I18n
- .format(
- _("The sketch \"{0}\" cannot be used.\n"
- + "Sketch names must contain only basic letters and numbers\n"
- + "(ASCII-only with no spaces, "
- + "and it cannot start with a number).\n"
- + "To get rid of this message, remove the sketch from\n"
- + "{1}"), name, entry.getAbsolutePath());
+ .format(
+ _("The sketch \"{0}\" cannot be used.\n"
+ + "Sketch names must contain only basic letters and numbers\n"
+ + "(ASCII-only with no spaces, "
+ + "and it cannot start with a number).\n"
+ + "To get rid of this message, remove the sketch from\n"
+ + "{1}"), name, entry.getAbsolutePath());
showMessage(_("Ignoring sketch with bad name"), complaining);
}
return false;
@@ -1455,11 +1731,11 @@ public class Base {
LibraryList list = new LibraryList(libs);
list.sort();
- for (Library lib : list) {
+ for (UserLibrary lib : list) {
@SuppressWarnings("serial")
AbstractAction action = new AbstractAction(lib.getName()) {
public void actionPerformed(ActionEvent event) {
- Library l = (Library) getValue("library");
+ UserLibrary l = (UserLibrary) getValue("library");
try {
activeEditor.getSketch().importLibrary(l);
} catch (IOException e) {
@@ -1504,29 +1780,30 @@ public class Base {
*/
@SuppressWarnings("serial")
public void handleAbout() {
- final Image image = getLibImage("about.jpg", activeEditor);
+ final Image image = getLibImage("about.png", activeEditor);
final Window window = new Window(activeEditor) {
- public void paint(Graphics g) {
- g.drawImage(image, 0, 0, null);
+ public void paint(Graphics g) {
+ g.drawImage(image, 0, 0, null);
- Graphics2D g2 = (Graphics2D) g;
- g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
- RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+ Graphics2D g2 = (Graphics2D) g;
+ g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
- g.setFont(new Font("SansSerif", Font.PLAIN, 11));
- g.setColor(Color.white);
- g.drawString(BaseNoGui.VERSION_NAME, 50, 30);
- }
- };
+ g.setFont(new Font("SansSerif", Font.PLAIN, 11));
+ g.setColor(Color.white);
+ g.drawString(BaseNoGui.VERSION_NAME_LONG, 33, 20);
+ }
+ };
window.addMouseListener(new MouseAdapter() {
- public void mousePressed(MouseEvent e) {
- window.dispose();
- }
- });
+ public void mousePressed(MouseEvent e) {
+ window.dispose();
+ }
+ });
int w = image.getWidth(activeEditor);
int h = image.getHeight(activeEditor);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- window.setBounds((screen.width-w)/2, (screen.height-h)/2, w, h);
+ window.setBounds((screen.width - w) / 2, (screen.height - h) / 2, w, h);
+ window.setLocationRelativeTo(activeEditor);
window.setVisible(true);
}
@@ -1535,8 +1812,13 @@ public class Base {
* Show the Preferences window.
*/
public void handlePrefs() {
- if (preferencesFrame == null) preferencesFrame = new Preferences();
- preferencesFrame.showFrame(activeEditor);
+ cc.arduino.view.preferences.Preferences dialog = new cc.arduino.view.preferences.Preferences(activeEditor, this);
+ if (activeEditor != null) {
+ dialog.setLocationRelativeTo(activeEditor);
+ }
+ dialog.pack();
+ dialog.setMinimumSize(dialog.getSize());
+ dialog.setVisible(true);
}
@@ -1567,8 +1849,6 @@ public class Base {
// return PConstants.OTHER;
// }
// }
-
-
static public Platform getPlatform() {
return BaseNoGui.getPlatform();
}
@@ -1604,6 +1884,7 @@ public class Base {
* Convenience method to get a File object for the specified filename inside
* the settings folder.
* For now, only used by Preferences to get the preferences.txt file.
+ *
* @param filename A file inside the settings folder.
* @return filename wrapped as a File object inside the settings folder
*/
@@ -1629,8 +1910,9 @@ public class Base {
}
+ // XXX: Remove this method and make librariesIndexer non-static
static public LibraryList getLibraries() {
- return BaseNoGui.getLibraries();
+ return BaseNoGui.librariesIndexer.getInstalledLibraries();
}
@@ -1660,7 +1942,7 @@ public class Base {
//Get the core libraries
static public File getCoreLibraries(String path) {
- return getContentFile(path);
+ return getContentFile(path);
}
static public String getHardwarePath() {
@@ -1711,6 +1993,10 @@ public class Base {
return BaseNoGui.getBoardPreferences();
}
+ public List getBoardsCustomMenus() {
+ return boardsCustomMenus;
+ }
+
static public File getPortableFolder() {
return BaseNoGui.getPortableFolder();
}
@@ -1741,7 +2027,7 @@ public class Base {
}
- protected File getDefaultSketchbookFolderOrPromptForIt() {
+ public File getDefaultSketchbookFolderOrPromptForIt() {
File sketchbookFolder = BaseNoGui.getDefaultSketchbookFolder();
@@ -1757,8 +2043,8 @@ public class Base {
if (!result) {
showError(_("You forgot your sketchbook"),
- _("Arduino cannot run because it could not\n" +
- "create a folder to store your sketchbook."), null);
+ _("Arduino cannot run because it could not\n" +
+ "create a folder to store your sketchbook."), null);
}
return sketchbookFolder;
@@ -1802,13 +2088,14 @@ public class Base {
} catch (Exception e) {
showWarning(_("Problem Opening URL"),
- I18n.format(_("Could not open the URL\n{0}"), url), e);
+ I18n.format(_("Could not open the URL\n{0}"), url), e);
}
}
/**
* Used to determine whether to disable the "Show Sketch Folder" option.
+ *
* @return true If a means of opening a folder is known to be available.
*/
static protected boolean openFolderAvailable() {
@@ -1826,7 +2113,7 @@ public class Base {
} catch (Exception e) {
showWarning(_("Problem Opening Folder"),
- I18n.format(_("Could not open the folder\n{0}"), file.getAbsolutePath()), e);
+ I18n.format(_("Could not open the folder\n{0}"), file.getAbsolutePath()), e);
}
}
@@ -1834,7 +2121,7 @@ public class Base {
// .................................................................
- static public File selectFolder(String prompt, File folder, Frame frame) {
+ static public File selectFolder(String prompt, File folder, Component parent) {
JFileChooser fc = new JFileChooser();
fc.setDialogTitle(prompt);
if (folder != null) {
@@ -1842,7 +2129,7 @@ public class Base {
}
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
- int returned = fc.showOpenDialog(new JDialog());
+ int returned = fc.showOpenDialog(parent);
if (returned == JFileChooser.APPROVE_OPTION) {
return fc.getSelectedFile();
}
@@ -1860,6 +2147,14 @@ public class Base {
// don't use the low-res icon on Mac OS X; the window should
// already have the right icon from the .app file.
if (OSUtils.isMacOS()) return;
+
+ // don't use the low-res icon on Linux
+ if (OSUtils.isLinux()){
+ String current = System.getProperty("user.dir");
+ Image image = Toolkit.getDefaultToolkit().createImage(current + "/lib/arduino.png");
+ frame.setIconImage(image);
+ return;
+ }
Image image = Toolkit.getDefaultToolkit().createImage(PApplet.ICON_IMAGE);
frame.setIconImage(image);
@@ -1893,12 +2188,12 @@ public class Base {
ActionListener disposer) {
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
root.registerKeyboardAction(disposer, stroke,
- JComponent.WHEN_IN_FOCUSED_WINDOW);
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
stroke = KeyStroke.getKeyStroke('W', modifiers);
root.registerKeyboardAction(disposer, stroke,
- JComponent.WHEN_IN_FOCUSED_WINDOW);
+ JComponent.WHEN_IN_FOCUSED_WINDOW);
}
@@ -1906,14 +2201,27 @@ public class Base {
static public void showReference(String filename) {
- File referenceFolder = getContentFile("reference/arduino.cc/en");
+ showReference("reference/arduino.cc/en", filename);
+ }
+
+ static public void showReference(String prefix, String filename) {
+ File referenceFolder = getContentFile(prefix);
File referenceFile = new File(referenceFolder, filename);
if (!referenceFile.exists())
referenceFile = new File(referenceFolder, filename + ".html");
- openURL(referenceFile.getAbsolutePath());
+
+ if(referenceFile.exists()){
+ openURL(referenceFile.getAbsolutePath());
+ }else{
+ showWarning(_("Problem Opening URL"), I18n.format(_("Could not open the URL\n{0}"), referenceFile), null);
+ }
}
- static public void showGettingStarted() {
+ public static void showEdisonGettingStarted() {
+ showReference("reference/Edison_help_files", "ArduinoIDE_guide_edison");
+ }
+
+ static public void showArduinoGettingStarted() {
if (OSUtils.isMacOS()) {
showReference("Guide/MacOSX");
} else if (OSUtils.isWindows()) {
@@ -1984,15 +2292,14 @@ public class Base {
// ...................................................................
-
// incomplete
static public int showYesNoCancelQuestion(Editor editor, String title,
String primary, String secondary) {
if (!OSUtils.isMacOS()) {
int result =
- JOptionPane.showConfirmDialog(null, primary + "\n" + secondary, title,
- JOptionPane.YES_NO_CANCEL_OPTION,
- JOptionPane.QUESTION_MESSAGE);
+ JOptionPane.showConfirmDialog(null, primary + "\n" + secondary, title,
+ JOptionPane.YES_NO_CANCEL_OPTION,
+ JOptionPane.QUESTION_MESSAGE);
return result;
// if (result == JOptionPane.YES_OPTION) {
//
@@ -2010,18 +2317,18 @@ public class Base {
// Pane formatting adapted from the Quaqua guide
// http://www.randelshofer.ch/quaqua/guide/joptionpane.html
JOptionPane pane =
- new JOptionPane(" " +
- " " +
- "Do you want to save changes to this sketch
" +
- " before closing?" +
- "If you don't save, your changes will be lost.",
- JOptionPane.QUESTION_MESSAGE);
+ new JOptionPane(" " +
+ "
" +
+ "Do you want to save changes to this sketch
" +
+ " before closing?" +
+ "If you don't save, your changes will be lost.",
+ JOptionPane.QUESTION_MESSAGE);
- String[] options = new String[] {
- "Save", "Cancel", "Don't Save"
+ String[] options = new String[]{
+ "Save", "Cancel", "Don't Save"
};
pane.setOptions(options);
@@ -2031,7 +2338,7 @@ public class Base {
// on macosx, setting the destructive property places this option
// away from the others at the lefthand side
pane.putClientProperty("Quaqua.OptionPane.destructiveOption",
- new Integer(2));
+ new Integer(2));
JDialog dialog = pane.createDialog(editor, null);
dialog.setVisible(true);
@@ -2063,29 +2370,29 @@ public class Base {
// }
static public int showYesNoQuestion(Frame editor, String title,
- String primary, String secondary) {
+ String primary, String secondary) {
if (!OSUtils.isMacOS()) {
return JOptionPane.showConfirmDialog(editor,
- "
" +
- "" + primary + "" +
- "
" + secondary, title,
- JOptionPane.YES_NO_OPTION,
- JOptionPane.QUESTION_MESSAGE);
+ "" +
+ "" + primary + "" +
+ "
" + secondary, title,
+ JOptionPane.YES_NO_OPTION,
+ JOptionPane.QUESTION_MESSAGE);
} else {
// Pane formatting adapted from the Quaqua guide
// http://www.randelshofer.ch/quaqua/guide/joptionpane.html
JOptionPane pane =
- new JOptionPane(" " +
- " " +
- "" + primary + "" +
- "" + secondary + "
",
- JOptionPane.QUESTION_MESSAGE);
+ new JOptionPane(" " +
+ " " +
+ "" + primary + "" +
+ "" + secondary + "
",
+ JOptionPane.QUESTION_MESSAGE);
- String[] options = new String[] {
- "Yes", "No"
+ String[] options = new String[]{
+ "Yes", "No"
};
pane.setOptions(options);
@@ -2143,7 +2450,6 @@ public class Base {
return null;
}
*/
-
static public File getContentFile(String name) {
return BaseNoGui.getContentFile(name);
}
@@ -2161,28 +2467,20 @@ public class Base {
* Return an Image object from inside the Processing lib folder.
*/
static public Image getLibImage(String name, Component who) {
- Image image = null;
Toolkit tk = Toolkit.getDefaultToolkit();
File imageLocation = new File(getContentFile("lib"), name);
- image = tk.getImage(imageLocation.getAbsolutePath());
+ Image image = tk.getImage(imageLocation.getAbsolutePath());
MediaTracker tracker = new MediaTracker(who);
tracker.addImage(image, 0);
try {
tracker.waitForAll();
- } catch (InterruptedException e) { }
+ } catch (InterruptedException e) {
+ }
return image;
}
- /**
- * Return an InputStream for a file inside the Processing lib folder.
- */
- static public InputStream getLibStream(String filename) throws IOException {
- return BaseNoGui.getLibStream(filename);
- }
-
-
// ...................................................................
@@ -2200,34 +2498,38 @@ public class Base {
*/
static public byte[] loadBytesRaw(File file) throws IOException {
int size = (int) file.length();
- FileInputStream input = new FileInputStream(file);
- byte buffer[] = new byte[size];
- int offset = 0;
- int bytesRead;
- while ((bytesRead = input.read(buffer, offset, size-offset)) != -1) {
- offset += bytesRead;
- if (bytesRead == 0) break;
+ FileInputStream input = null;
+ try {
+ input = new FileInputStream(file);
+ byte buffer[] = new byte[size];
+ int offset = 0;
+ int bytesRead;
+ while ((bytesRead = input.read(buffer, offset, size - offset)) != -1) {
+ offset += bytesRead;
+ if (bytesRead == 0) break;
+ }
+ return buffer;
+ } finally {
+ if (input != null) {
+ input.close();
+ }
}
- input.close(); // weren't properly being closed
- input = null;
- return buffer;
}
-
/**
* Read from a file with a bunch of attribute/value pairs
* that are separated by = and ignore comments with #.
*/
- static public HashMap readSettings(File inputFile) {
- HashMap outgoing = new HashMap();
+ static public HashMap readSettings(File inputFile) {
+ HashMap outgoing = new HashMap();
if (!inputFile.exists()) return outgoing; // return empty hash
String lines[] = PApplet.loadStrings(inputFile);
for (int i = 0; i < lines.length; i++) {
int hash = lines[i].indexOf('#');
String line = (hash == -1) ?
- lines[i].trim() : lines[i].substring(0, hash).trim();
+ lines[i].trim() : lines[i].substring(0, hash).trim();
if (line.length() == 0) continue;
int equals = line.indexOf('=');
@@ -2246,20 +2548,25 @@ public class Base {
static public void copyFile(File sourceFile,
File targetFile) throws IOException {
- InputStream from =
- new BufferedInputStream(new FileInputStream(sourceFile));
- OutputStream to =
- new BufferedOutputStream(new FileOutputStream(targetFile));
- byte[] buffer = new byte[16 * 1024];
- int bytesRead;
- while ((bytesRead = from.read(buffer)) != -1) {
- to.write(buffer, 0, bytesRead);
+ InputStream from = null;
+ OutputStream to = null;
+ try {
+ from = new BufferedInputStream(new FileInputStream(sourceFile));
+ to = new BufferedOutputStream(new FileOutputStream(targetFile));
+ byte[] buffer = new byte[16 * 1024];
+ int bytesRead;
+ while ((bytesRead = from.read(buffer)) != -1) {
+ to.write(buffer, 0, bytesRead);
+ }
+ to.flush();
+ } finally {
+ if (from != null) {
+ from.close(); // ??
+ }
+ if (to != null) {
+ to.close(); // ??
+ }
}
- to.flush();
- from.close(); // ??
- from = null;
- to.close(); // ??
- to = null;
targetFile.setLastModified(sourceFile.lastModified());
}
@@ -2340,7 +2647,7 @@ public class Base {
for (int i = 0; i < files.length; i++) {
if (files[i].equals(".") || (files[i].equals("..")) ||
- files[i].equals(".DS_Store")) continue;
+ files[i].equals(".DS_Store")) continue;
File fella = new File(folder, files[i]);
if (fella.isDirectory()) {
size += calcFolderSize(fella);
@@ -2434,9 +2741,9 @@ public class Base {
String libName = libFolder.getName();
if (!BaseNoGui.isSanitaryName(libName)) {
String mess = I18n.format(_("The library \"{0}\" cannot be used.\n"
- + "Library names must contain only basic letters and numbers.\n"
- + "(ASCII only and no spaces, and it cannot start with a number)"),
- libName);
+ + "Library names must contain only basic letters and numbers.\n"
+ + "(ASCII only and no spaces, and it cannot start with a number)"),
+ libName);
activeEditor.statusError(mess);
return;
}
@@ -2453,7 +2760,7 @@ public class Base {
activeEditor.statusError(e);
return;
}
- activeEditor.statusNotice(_("Library added to your libraries. Check \"Import library\" menu"));
+ activeEditor.statusNotice(_("Library added to your libraries. Check \"Include library\" menu"));
} finally {
// delete zip created temp folder, if exists
FileUtils.recursiveDelete(tmpFolder);
@@ -2463,4 +2770,24 @@ public class Base {
public static DiscoveryManager getDiscoveryManager() {
return BaseNoGui.getDiscoveryManager();
}
+
+ public Editor getActiveEditor() {
+ return activeEditor;
+ }
+
+ public boolean hasActiveEditor() {
+ return activeEditor != null;
+ }
+
+ public List getEditors() {
+ return new LinkedList(editors);
+ }
+
+ public Action getOpenBoardsManager() {
+ return openBoardsManager;
+ }
+
+ public PdeKeywords getPdeKeywords() {
+ return pdeKeywords;
+ }
}
diff --git a/app/src/processing/app/CaretAwareUndoableEdit.java b/app/src/processing/app/CaretAwareUndoableEdit.java
index ba8e67d85..b0983ad2f 100644
--- a/app/src/processing/app/CaretAwareUndoableEdit.java
+++ b/app/src/processing/app/CaretAwareUndoableEdit.java
@@ -1,6 +1,6 @@
package processing.app;
-import processing.app.syntax.JEditTextArea;
+import processing.app.syntax.SketchTextArea;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
@@ -11,7 +11,7 @@ public class CaretAwareUndoableEdit implements UndoableEdit {
private final UndoableEdit undoableEdit;
private final int caretPosition;
- public CaretAwareUndoableEdit(UndoableEdit undoableEdit, JEditTextArea textArea) {
+ public CaretAwareUndoableEdit(UndoableEdit undoableEdit, SketchTextArea textArea) {
this.undoableEdit = undoableEdit;
this.caretPosition = textArea.getCaretPosition();
}
diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java
index 9d6151278..37d258ed1 100644
--- a/app/src/processing/app/Editor.java
+++ b/app/src/processing/app/Editor.java
@@ -24,11 +24,8 @@ package processing.app;
import cc.arduino.packages.MonitorFactory;
-import cc.arduino.view.*;
-import cc.arduino.view.Event;
-import cc.arduino.view.EventListener;
+import cc.arduino.view.StubMenuListener;
import com.jcraft.jsch.JSchException;
-
import jssc.SerialPortException;
import processing.app.debug.*;
import processing.app.forms.PasswordAuthorizationDialog;
@@ -50,10 +47,17 @@ import java.util.List;
import java.util.zip.*;
import javax.swing.*;
+import javax.swing.border.MatteBorder;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.undo.*;
+import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
+import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
+import org.fife.ui.rtextarea.Gutter;
+import org.fife.ui.rtextarea.RTextScrollPane;
+
import cc.arduino.packages.BoardPort;
import cc.arduino.packages.Uploader;
import cc.arduino.packages.uploaders.SerialUploader;
@@ -96,7 +100,6 @@ public class Editor extends JFrame implements RunnerListener {
// file, sketch, and tools menus for re-inserting items
JMenu fileMenu;
- JMenu sketchMenu;
JMenu toolsMenu;
int numTools = 0;
@@ -109,10 +112,6 @@ public class Editor extends JFrame implements RunnerListener {
static JMenu examplesMenu;
static JMenu importMenu;
- // these menus are shared so that the board and serial port selections
- // are the same for all windows (since the board and serial port that are
- // actually used are determined by the preferences, which are shared)
- static List boardsMenus;
static JMenu serialMenu;
static AbstractMonitor serialMonitor;
@@ -133,8 +132,8 @@ public class Editor extends JFrame implements RunnerListener {
//JEditorPane editorPane;
- JEditTextArea textarea;
- EditorListener listener;
+ SketchTextArea textarea;
+ RTextScrollPane scrollPane;
// runtime information and window placement
Point sketchWindowLocation;
@@ -152,14 +151,13 @@ public class Editor extends JFrame implements RunnerListener {
JMenuItem undoItem, redoItem;
protected UndoAction undoAction;
protected RedoAction redoAction;
- LastUndoableEditAwareUndoManager undo;
- // used internally, and only briefly
- CompoundEdit compoundEdit;
FindReplace find;
Runnable runHandler;
Runnable presentHandler;
+ Runnable runAndSaveHandler;
+ Runnable presentAndSaveHandler;
Runnable stopHandler;
Runnable exportHandler;
Runnable exportAppHandler;
@@ -188,29 +186,25 @@ public class Editor extends JFrame implements RunnerListener {
// When bringing a window to front, let the Base know
addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
-// System.err.println("activate"); // not coming through
base.handleActivated(Editor.this);
- // re-add the sub-menus that are shared by all windows
- fileMenu.insert(sketchbookMenu, 2);
- fileMenu.insert(examplesMenu, 3);
- sketchMenu.insert(importMenu, 4);
- int offset = 0;
- for (JMenu menu : boardsMenus) {
- toolsMenu.insert(menu, numTools + offset);
- offset++;
- }
- toolsMenu.insert(serialMenu, numTools + offset);
}
// added for 1.0.5
// http://dev.processing.org/bugs/show_bug.cgi?id=1260
public void windowDeactivated(WindowEvent e) {
-// System.err.println("deactivate"); // not coming through
fileMenu.remove(sketchbookMenu);
fileMenu.remove(examplesMenu);
- sketchMenu.remove(importMenu);
- for (JMenu menu : boardsMenus) {
- toolsMenu.remove(menu);
+ List toolsMenuItemsToRemove = new LinkedList();
+ for (Component menuItem : toolsMenu.getMenuComponents()) {
+ if (menuItem instanceof JComponent) {
+ Object removeOnWindowDeactivation = ((JComponent) menuItem).getClientProperty("removeOnWindowDeactivation");
+ if (removeOnWindowDeactivation != null && Boolean.valueOf(removeOnWindowDeactivation.toString())) {
+ toolsMenuItemsToRemove.add(menuItem);
+ }
+ }
+ }
+ for (Component menuItem : toolsMenuItemsToRemove) {
+ toolsMenu.remove(menuItem);
}
toolsMenu.remove(serialMenu);
}
@@ -241,10 +235,8 @@ public class Editor extends JFrame implements RunnerListener {
header = new EditorHeader(this);
upper.add(header);
- textarea = new JEditTextArea(new PdeTextAreaDefaults());
+ textarea = createTextArea();
textarea.setName("editor");
- textarea.setRightClickPopup(new TextAreaPopup());
- textarea.setHorizontalOffset(6);
// assemble console panel, consisting of status area and the console itself
consolePanel = new JPanel();
@@ -259,12 +251,23 @@ public class Editor extends JFrame implements RunnerListener {
console.setBorder(null);
consolePanel.add(console, BorderLayout.CENTER);
- lineStatus = new EditorLineStatus(textarea);
+ lineStatus = new EditorLineStatus();
consolePanel.add(lineStatus, BorderLayout.SOUTH);
- upper.add(textarea);
- splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
- upper, consolePanel);
+ // RTextScrollPane
+ scrollPane = new RTextScrollPane(textarea, true);
+ scrollPane.setBorder(new MatteBorder(0, 6, 0, 0, Theme.getColor("editor.bgcolor")));
+ scrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
+ scrollPane.setLineNumbersEnabled(PreferencesData.getBoolean("editor.linenumbers"));
+ scrollPane.setIconRowHeaderEnabled(false);
+
+ Gutter gutter = scrollPane.getGutter();
+ gutter.setBookmarkingEnabled(false);
+ //gutter.setBookmarkIcon(CompletionsRenderer.getIcon(CompletionType.TEMPLATE));
+ gutter.setIconRowHeaderInheritsGutterBackground(true);
+
+ upper.add(scrollPane);
+ splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, upper, consolePanel);
splitPane.setOneTouchExpandable(true);
// repaint child panes while resizing
@@ -278,7 +281,7 @@ public class Editor extends JFrame implements RunnerListener {
splitPane.setBorder(null);
// the default size on windows is too small and kinda ugly
- int dividerSize = Preferences.getInteger("editor.divider.size");
+ int dividerSize = PreferencesData.getInteger("editor.divider.size");
if (dividerSize != 0) {
splitPane.setDividerSize(dividerSize);
}
@@ -290,7 +293,7 @@ public class Editor extends JFrame implements RunnerListener {
// hopefully these are no longer needed w/ swing
// (har har har.. that was wishful thinking)
- listener = new EditorListener(this, textarea);
+ // listener = new EditorListener(this, textarea);
pain.add(box);
// get shift down/up events so we can show the alt version of toolbar buttons
@@ -310,8 +313,8 @@ public class Editor extends JFrame implements RunnerListener {
// Set the minimum size for the editor window
- setMinimumSize(new Dimension(Preferences.getInteger("editor.window.width.min"),
- Preferences.getInteger("editor.window.height.min")));
+ setMinimumSize(new Dimension(PreferencesData.getInteger("editor.window.width.min"),
+ PreferencesData.getInteger("editor.window.height.min")));
// System.out.println("t3");
// Bring back the general options for the editor
@@ -440,47 +443,46 @@ public class Editor extends JFrame implements RunnerListener {
* the app is just starting up, or the user just finished messing
* with things in the Preferences window.
*/
- protected void applyPreferences() {
+ public void applyPreferences() {
// apply the setting for 'use external editor'
- boolean external = Preferences.getBoolean("editor.external");
+ boolean external = PreferencesData.getBoolean("editor.external");
textarea.setEditable(!external);
saveMenuItem.setEnabled(!external);
saveAsMenuItem.setEnabled(!external);
- textarea.setDisplayLineNumbers(Preferences.getBoolean("editor.linenumbers"));
+ textarea.setCodeFoldingEnabled(PreferencesData.getBoolean("editor.code_folding"));
+ scrollPane.setLineNumbersEnabled(PreferencesData.getBoolean("editor.linenumbers"));
- TextAreaPainter painter = textarea.getPainter();
if (external) {
// disable line highlight and turn off the caret when disabling
Color color = Theme.getColor("editor.external.bgcolor");
- painter.setBackground(color);
- painter.setLineHighlightEnabled(false);
- textarea.setCaretVisible(false);
+ textarea.setBackground(color);
+ textarea.setHighlightCurrentLine(false);
+ textarea.setEditable(false);
} else {
- Color color = Theme.getColor("editor.bgcolor");
- painter.setBackground(color);
- boolean highlight = Preferences.getBoolean("editor.linehighlight");
- painter.setLineHighlightEnabled(highlight);
- textarea.setCaretVisible(true);
+ boolean highlight = PreferencesData.getBoolean("editor.linehighlight");
+ textarea.setHighlightCurrentLine(highlight);
+ textarea.setEditable(true);
}
// apply changes to the font size for the editor
//TextAreaPainter painter = textarea.getPainter();
- painter.setFont(Preferences.getFont("editor.font"));
+ textarea.setFont(PreferencesData.getFont("editor.font"));
//Font font = painter.getFont();
//textarea.getPainter().setFont(new Font("Courier", Font.PLAIN, 36));
// in case tab expansion stuff has changed
- listener.applyPreferences();
+ // listener.applyPreferences();
// in case moved to a new location
// For 0125, changing to async version (to be implemented later)
//sketchbook.rebuildMenus();
// For 0126, moved into Base, which will notify all editors.
//base.rebuildMenusAsync();
+
}
@@ -489,10 +491,59 @@ public class Editor extends JFrame implements RunnerListener {
protected void buildMenuBar() throws Exception {
JMenuBar menubar = new JMenuBar();
- menubar.add(buildFileMenu());
+ final JMenu fileMenu = buildFileMenu();
+ fileMenu.addMenuListener(new StubMenuListener() {
+ @Override
+ public void menuSelected(MenuEvent e) {
+ List components = Arrays.asList(fileMenu.getComponents());
+ if (!components.contains(sketchbookMenu)) {
+ fileMenu.insert(sketchbookMenu, 2);
+ }
+ if (!components.contains(sketchbookMenu)) {
+ fileMenu.insert(examplesMenu, 3);
+ }
+ fileMenu.revalidate();
+ validate();
+ }
+ });
+ menubar.add(fileMenu);
+
menubar.add(buildEditMenu());
- menubar.add(buildSketchMenu());
- menubar.add(buildToolsMenu());
+
+ final JMenu sketchMenu = new JMenu(_("Sketch"));
+ sketchMenu.addMenuListener(new StubMenuListener() {
+
+ @Override
+ public void menuSelected(MenuEvent e) {
+ buildSketchMenu(sketchMenu);
+ sketchMenu.revalidate();
+ validate();
+ }
+ });
+ buildSketchMenu(sketchMenu);
+ menubar.add(sketchMenu);
+
+ final JMenu toolsMenu = buildToolsMenu();
+ toolsMenu.addMenuListener(new StubMenuListener() {
+ @Override
+ public void menuSelected(MenuEvent e) {
+ List components = Arrays.asList(fileMenu.getComponents());
+ int offset = 0;
+ for (JMenu menu : base.getBoardsCustomMenus()) {
+ if (!components.contains(menu)) {
+ toolsMenu.insert(menu, numTools + offset);
+ offset++;
+ }
+ }
+ if (!components.contains(serialMenu)) {
+ toolsMenu.insert(serialMenu, numTools + offset);
+ }
+ toolsMenu.revalidate();
+ validate();
+ }
+ });
+ menubar.add(toolsMenu);
+
menubar.add(buildHelpMenu());
setJMenuBar(menubar);
}
@@ -564,30 +615,14 @@ public class Editor extends JFrame implements RunnerListener {
});
fileMenu.add(saveAsMenuItem);
- item = newJMenuItem(_("Upload"), 'U');
- item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleExport(false);
- }
- });
- fileMenu.add(item);
-
- item = newJMenuItemShift(_("Upload Using Programmer"), 'U');
- item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleExport(true);
- }
- });
- fileMenu.add(item);
-
fileMenu.addSeparator();
item = newJMenuItemShift(_("Page Setup"), 'P');
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handlePageSetup();
- }
- });
+ public void actionPerformed(ActionEvent e) {
+ handlePageSetup();
+ }
+ });
fileMenu.add(item);
item = newJMenuItem(_("Print"), 'P');
@@ -624,25 +659,41 @@ public class Editor extends JFrame implements RunnerListener {
}
- protected JMenu buildSketchMenu() {
- JMenuItem item;
- sketchMenu = new JMenu(_("Sketch"));
+ protected void buildSketchMenu(JMenu sketchMenu) {
+ sketchMenu.removeAll();
- item = newJMenuItem(_("Verify / Compile"), 'R');
+ JMenuItem item = newJMenuItem(_("Verify / Compile"), 'R');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- handleRun(false);
+ handleRun(false, Editor.this.presentHandler, Editor.this.runHandler);
}
});
sketchMenu.add(item);
-// item = newJMenuItemShift("Verify / Compile (verbose)", 'R');
-// item.addActionListener(new ActionListener() {
-// public void actionPerformed(ActionEvent e) {
-// handleRun(true);
-// }
-// });
-// sketchMenu.add(item);
+ item = newJMenuItem(_("Upload"), 'U');
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleExport(false);
+ }
+ });
+ sketchMenu.add(item);
+
+ item = newJMenuItemShift(_("Upload Using Programmer"), 'U');
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleExport(true);
+ }
+ });
+ sketchMenu.add(item);
+
+
+ item = newJMenuItemAlt(_("Export compiled Binary"), 'S');
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleRun(false, Editor.this.presentAndSaveHandler, Editor.this.runAndSaveHandler);
+ }
+ });
+ sketchMenu.add(item);
// item = new JMenuItem("Stop");
// item.addActionListener(new ActionListener() {
@@ -654,83 +705,69 @@ public class Editor extends JFrame implements RunnerListener {
sketchMenu.addSeparator();
+ item = newJMenuItem(_("Show Sketch Folder"), 'K');
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Base.openFolder(sketch.getFolder());
+ }
+ });
+ sketchMenu.add(item);
+ item.setEnabled(Base.openFolderAvailable());
+
if (importMenu == null) {
- importMenu = new JMenu(_("Import Library..."));
+ importMenu = new JMenu(_("Include Library"));
MenuScroller.setScrollerFor(importMenu);
base.rebuildImportMenu(importMenu);
}
sketchMenu.add(importMenu);
- item = newJMenuItem(_("Show Sketch Folder"), 'K');
- item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- Base.openFolder(sketch.getFolder());
- }
- });
- sketchMenu.add(item);
- item.setEnabled(Base.openFolderAvailable());
-
item = new JMenuItem(_("Add File..."));
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- sketch.handleAddFile();
- }
- });
+ public void actionPerformed(ActionEvent e) {
+ sketch.handleAddFile();
+ }
+ });
sketchMenu.add(item);
-
- return sketchMenu;
}
protected JMenu buildToolsMenu() throws Exception {
toolsMenu = new JMenu(_("Tools"));
- JMenu menu = toolsMenu;
- JMenuItem item;
- addInternalTools(menu);
+ addInternalTools(toolsMenu);
- item = newJMenuItemShift(_("Serial Monitor"), 'M');
+ JMenuItem item = newJMenuItemShift(_("Serial Monitor"), 'M');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
handleSerial();
}
});
- menu.add(item);
+ toolsMenu.add(item);
- addTools(menu, Base.getToolsFolder());
+ addTools(toolsMenu, Base.getToolsFolder());
File sketchbookTools = new File(Base.getSketchbookFolder(), "tools");
- addTools(menu, sketchbookTools);
+ addTools(toolsMenu, sketchbookTools);
- menu.addSeparator();
+ toolsMenu.addSeparator();
- numTools = menu.getItemCount();
+ numTools = toolsMenu.getItemCount();
// XXX: DAM: these should probably be implemented using the Tools plugin
// API, if possible (i.e. if it supports custom actions, etc.)
- if (boardsMenus == null) {
- boardsMenus = new LinkedList();
-
- JMenu boardsMenu = new JMenu(_("Board"));
- MenuScroller.setScrollerFor(boardsMenu);
- Editor.boardsMenus.add(boardsMenu);
- toolsMenu.add(boardsMenu);
-
- base.rebuildBoardsMenu(toolsMenu, this);
- //Debug: rebuild imports
- importMenu.removeAll();
- base.rebuildImportMenu(importMenu);
+ for (JMenu menu : base.getBoardsCustomMenus()) {
+ toolsMenu.add(menu);
}
if (serialMenu == null)
serialMenu = new JMenu(_("Port"));
populatePortMenu();
- menu.add(serialMenu);
- menu.addSeparator();
+ toolsMenu.add(serialMenu);
+ toolsMenu.addSeparator();
JMenu programmerMenu = new JMenu(_("Programmer"));
base.rebuildProgrammerMenu(programmerMenu);
- menu.add(programmerMenu);
+ toolsMenu.add(programmerMenu);
item = new JMenuItem(_("Burn Bootloader"));
item.addActionListener(new ActionListener() {
@@ -738,18 +775,42 @@ public class Editor extends JFrame implements RunnerListener {
handleBurnBootloader();
}
});
- menu.add(item);
+ toolsMenu.add(item);
- menu.addMenuListener(new MenuListener() {
- public void menuCanceled(MenuEvent e) {}
- public void menuDeselected(MenuEvent e) {}
+ toolsMenu.addMenuListener(new StubMenuListener() {
public void menuSelected(MenuEvent e) {
//System.out.println("Tools menu selected.");
populatePortMenu();
+ for (Component c : toolsMenu.getMenuComponents()) {
+ if ((c instanceof JMenu) && c.isVisible()) {
+ JMenu menu = (JMenu)c;
+ String name = menu.getText();
+ if (name == null) continue;
+ String basename = name;
+ int index = name.indexOf(':');
+ if (index > 0) basename = name.substring(0, index);
+ String sel = null;
+ int count = menu.getItemCount();
+ for (int i=0; i < count; i++) {
+ JMenuItem item = menu.getItem(i);
+ if (item != null && item.isSelected()) {
+ sel = item.getText();
+ if (sel != null) break;
+ }
+ }
+ if (sel == null) {
+ if (!name.equals(basename)) menu.setText(basename);
+ } else {
+ if (sel.length() > 17) sel = sel.substring(0, 16) + "...";
+ String newname = basename + ": \"" + sel + "\"";
+ if (!name.equals(newname)) menu.setText(newname);
+ }
+ }
+ }
}
});
- return menu;
+ return toolsMenu;
}
@@ -895,6 +956,44 @@ public class Editor extends JFrame implements RunnerListener {
}
+ protected SketchTextArea createTextArea() throws IOException {
+ final SketchTextArea textArea = new SketchTextArea(base.getPdeKeywords());
+ textArea.requestFocusInWindow();
+ textArea.setMarkOccurrences(PreferencesData.getBoolean("editor.advanced"));
+ textArea.setMarginLineEnabled(false);
+ textArea.setCodeFoldingEnabled(PreferencesData.getBoolean("editor.code_folding"));
+ textArea.setAntiAliasingEnabled(PreferencesData.getBoolean("editor.antialias"));
+ textArea.setTabsEmulated(PreferencesData.getBoolean("editor.tabs.expand"));
+ textArea.setTabSize(PreferencesData.getInteger("editor.tabs.size"));
+ textArea.setEditorListener(new EditorListener(this));
+ textArea.addHyperlinkListener(new HyperlinkListener() {
+ @Override
+ public void hyperlinkUpdate(HyperlinkEvent hyperlinkEvent) {
+ try {
+ base.getPlatform().openURL(hyperlinkEvent.getURL().toExternalForm());
+ } catch (Exception e) {
+ Base.showWarning(e.getMessage(), e.getMessage(), e);
+ }
+ }
+ });
+ textArea.addCaretListener(new CaretListener() {
+
+ @Override
+ public void caretUpdate(CaretEvent e) {
+ int lineStart = textArea.getDocument().getDefaultRootElement().getElementIndex(e.getMark());
+ int lineEnd = textArea.getDocument().getDefaultRootElement().getElementIndex(e.getDot());
+
+ lineStatus.set(lineStart, lineEnd);
+ }
+
+ });
+
+ ToolTipManager.sharedInstance().registerComponent(textArea);
+
+ configurePopupMenu(textArea);
+ return textArea;
+ }
+
protected JMenuItem createToolMenuItem(String className) {
try {
Class> toolClass = Class.forName(className);
@@ -947,22 +1046,15 @@ public class Editor extends JFrame implements RunnerListener {
class SerialMenuListener implements ActionListener {
- private final Frame parent;
private final String serialPort;
- private final String warning;
- public SerialMenuListener(Frame parent, String serialPort, String warning) {
- this.parent = parent;
+ public SerialMenuListener(String serialPort) {
this.serialPort = serialPort;
- this.warning = warning;
}
public void actionPerformed(ActionEvent e) {
selectSerialPort(serialPort);
base.onBoardOrPortChange();
- if (warning != null && !Preferences.getBoolean("uncertifiedBoardWarning_dontShowMeAgain")) {
- SwingUtilities.invokeLater(new ShowUncertifiedBoardWarning(parent));
- }
}
}
@@ -1011,11 +1103,11 @@ public class Editor extends JFrame implements RunnerListener {
protected void populatePortMenu() {
serialMenu.removeAll();
- String selectedPort = Preferences.get("serial.port");
+ String selectedPort = PreferencesData.get("serial.port");
List ports = Base.getDiscoveryManager().discovery();
- ports = Base.getPlatform().filterPorts(ports, Preferences.getBoolean("serial.ports.showall"));
+ ports = Base.getPlatform().filterPorts(ports, PreferencesData.getBoolean("serial.ports.showall"));
Collections.sort(ports, new Comparator() {
@Override
@@ -1038,13 +1130,15 @@ public class Editor extends JFrame implements RunnerListener {
} else {
lastProtocolTranslated = port.getProtocol();
}
- serialMenu.add(new JMenuItem(_(lastProtocolTranslated)));
+ JMenuItem lastProtocolMenuItem = new JMenuItem(_(lastProtocolTranslated));
+ lastProtocolMenuItem.setEnabled(false);
+ serialMenu.add(lastProtocolMenuItem);
}
String address = port.getAddress();
String label = port.getLabel();
JCheckBoxMenuItem item = new JCheckBoxMenuItem(label, address.equals(selectedPort));
- item.addActionListener(new SerialMenuListener(this, address, port.getPrefs().get("warning")));
+ item.addActionListener(new SerialMenuListener(address));
serialMenu.add(item);
}
@@ -1097,35 +1191,79 @@ public class Editor extends JFrame implements RunnerListener {
item = new JMenuItem(_("Getting Started"));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- Base.showGettingStarted();
+ Base.showArduinoGettingStarted();
}
});
menu.add(item);
item = new JMenuItem(_("Environment"));
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- Base.showEnvironment();
- }
- });
+ public void actionPerformed(ActionEvent e) {
+ Base.showEnvironment();
+ }
+ });
menu.add(item);
item = new JMenuItem(_("Troubleshooting"));
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- Base.showTroubleshooting();
- }
- });
+ public void actionPerformed(ActionEvent e) {
+ Base.showTroubleshooting();
+ }
+ });
menu.add(item);
item = new JMenuItem(_("Reference"));
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- Base.showReference();
- }
- });
+ public void actionPerformed(ActionEvent e) {
+ Base.showReference();
+ }
+ });
menu.add(item);
+ menu.addSeparator();
+
+ item = new JMenuItem(_("Galileo Help"));
+ item.setEnabled(false);
+ menu.add(item);
+
+ item = new JMenuItem(_("Getting Started"));
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Base.showReference("reference/Galileo_help_files", "ArduinoIDE_guide_galileo");
+ }
+ });
+ menu.add(item);
+ item = new JMenuItem(_("Troubleshooting"));
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Base.showReference("reference/Galileo_help_files", "Guide_Troubleshooting_Galileo");;
+ }
+ });
+ menu.add(item);
+
+ menu.addSeparator();
+
+ item = new JMenuItem(_("Edison Help"));
+ item.setEnabled(false);
+ menu.add(item);
+
+ item = new JMenuItem(_("Getting Started"));
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Base.showReference("reference/Edison_help_files", "ArduinoIDE_guide_edison");
+ }
+ });
+ menu.add(item);
+ item = new JMenuItem(_("Troubleshooting"));
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Base.showReference("reference/Edison_help_files", "Guide_Troubleshooting_Edison");;
+ }
+ });
+ menu.add(item);
+
+ menu.addSeparator();
+
item = newJMenuItemShift(_("Find in Reference"), 'F');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@@ -1280,50 +1418,55 @@ public class Editor extends JFrame implements RunnerListener {
item = newJMenuItem(_("Find..."), 'F');
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (find == null) {
- find = new FindReplace(Editor.this);
- }
- if (getSelectedText()!= null) find.setFindText( getSelectedText() );
- //new FindReplace(Editor.this).show();
- find.setVisible(true);
- //find.setVisible(true);
+ public void actionPerformed(ActionEvent e) {
+ if (find == null) {
+ find = new FindReplace(Editor.this);
}
- });
+ if (!OSUtils.isMacOS() && getSelectedText() != null) {
+ find.setFindText(getSelectedText());
+ }
+ find.setLocationRelativeTo(Editor.this);
+ find.setVisible(true);
+ }
+ });
menu.add(item);
- // TODO find next should only be enabled after a
- // search has actually taken place
item = newJMenuItem(_("Find Next"), 'G');
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (find != null) {
- find.findNext();
- }
+ public void actionPerformed(ActionEvent e) {
+ if (find != null) {
+ find.findNext();
}
- });
+ }
+ });
menu.add(item);
item = newJMenuItemShift(_("Find Previous"), 'G');
item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (find != null) {
- find.findPrevious();
- }
+ public void actionPerformed(ActionEvent e) {
+ if (find != null) {
+ find.findPrevious();
}
- });
+ }
+ });
menu.add(item);
- item = newJMenuItem(_("Use Selection For Find"), 'E');
- item.addActionListener(new ActionListener() {
+ if (OSUtils.isMacOS()) {
+ 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() );
+ if (getSelectedText() != null) {
+ find.setFindText(getSelectedText());
+ }
+ find.setLocationRelativeTo(Editor.this);
+ find.setVisible(true);
}
});
- menu.add(item);
+ menu.add(item);
+ }
return menu;
}
@@ -1374,24 +1517,18 @@ public class Editor extends JFrame implements RunnerListener {
public void actionPerformed(ActionEvent e) {
try {
- undo.undo();
+ textarea.undoLastAction();
sketch.setModified(true);
} catch (CannotUndoException ex) {
//System.out.println("Unable to undo: " + ex);
//ex.printStackTrace();
}
- if (undo.getLastUndoableEdit() != null && undo.getLastUndoableEdit() instanceof CaretAwareUndoableEdit) {
- CaretAwareUndoableEdit undoableEdit = (CaretAwareUndoableEdit) undo.getLastUndoableEdit();
- int nextCaretPosition = undoableEdit.getCaretPosition() - 1;
- if (nextCaretPosition >= 0 && textarea.getDocumentLength() > nextCaretPosition) {
- textarea.setCaretPosition(nextCaretPosition);
- }
- }
- updateUndoState();
- redoAction.updateRedoState();
}
protected void updateUndoState() {
+
+ UndoManager undo = textarea.getUndoManager();
+
if (undo.canUndo()) {
this.setEnabled(true);
undoItem.setEnabled(true);
@@ -1415,21 +1552,17 @@ public class Editor extends JFrame implements RunnerListener {
public void actionPerformed(ActionEvent e) {
try {
- undo.redo();
+ textarea.redoLastAction();
sketch.setModified(true);
} catch (CannotRedoException ex) {
//System.out.println("Unable to redo: " + ex);
//ex.printStackTrace();
}
- if (undo.getLastUndoableEdit() != null && undo.getLastUndoableEdit() instanceof CaretAwareUndoableEdit) {
- CaretAwareUndoableEdit undoableEdit = (CaretAwareUndoableEdit) undo.getLastUndoableEdit();
- textarea.setCaretPosition(undoableEdit.getCaretPosition());
- }
- updateRedoState();
- undoAction.updateUndoState();
}
protected void updateRedoState() {
+ UndoManager undo = textarea.getUndoManager();
+
if (undo.canRedo()) {
redoItem.setEnabled(true);
redoItem.setText(undo.getRedoPresentationName());
@@ -1453,11 +1586,17 @@ public class Editor extends JFrame implements RunnerListener {
// abstract from the editor in this fashion.
- public void setHandlers(Runnable runHandler, Runnable presentHandler,
+ public void setHandlers(Runnable runHandler,
+ Runnable presentHandler,
+ Runnable runAndSaveHandler,
+ Runnable presentAndSaveHandler,
Runnable stopHandler,
- Runnable exportHandler, Runnable exportAppHandler) {
+ Runnable exportHandler,
+ Runnable exportAppHandler) {
this.runHandler = runHandler;
this.presentHandler = presentHandler;
+ this.runAndSaveHandler = runAndSaveHandler;
+ this.presentAndSaveHandler = presentAndSaveHandler;
this.stopHandler = stopHandler;
this.exportHandler = exportHandler;
this.exportAppHandler = exportAppHandler;
@@ -1467,6 +1606,8 @@ public class Editor extends JFrame implements RunnerListener {
public void resetHandlers() {
runHandler = new BuildHandler();
presentHandler = new BuildHandler(true);
+ runAndSaveHandler = new BuildHandler(false, true);
+ presentAndSaveHandler = new BuildHandler(true, true);
stopHandler = new DefaultStopHandler();
exportHandler = new DefaultExportHandler();
exportAppHandler = new DefaultExportAppHandler();
@@ -1485,13 +1626,13 @@ public class Editor extends JFrame implements RunnerListener {
/**
- * Get the JEditTextArea object for use (not recommended). This should only
+ * Get the TextArea object for use (not recommended). This should only
* be used in obscure cases that really need to hack the internals of the
* JEditTextArea. Most tools should only interface via the get/set functions
* found in this class. This will maintain compatibility with future releases,
- * which will not use JEditTextArea.
+ * which will not use TextArea.
*/
- public JEditTextArea getTextArea() {
+ public SketchTextArea getTextArea() {
return textarea;
}
@@ -1508,7 +1649,11 @@ public class Editor extends JFrame implements RunnerListener {
* Get a range of text from the current buffer.
*/
public String getText(int start, int stop) {
- return textarea.getText(start, stop - start);
+ try {
+ return textarea.getText(start, stop - start);
+ } catch (BadLocationException e) {
+ return null;
+ }
}
@@ -1516,20 +1661,10 @@ public class Editor extends JFrame implements RunnerListener {
* Replace the entire contents of the front-most tab.
*/
public void setText(String what) {
- startCompoundEdit();
textarea.setText(what);
- stopCompoundEdit();
}
- public void insertText(String what) {
- startCompoundEdit();
- int caret = getCaretOffset();
- setSelection(caret, caret);
- textarea.setSelectedText(what);
- stopCompoundEdit();
- }
-
/**
* Called to update the text but not switch to a different set of code
@@ -1555,15 +1690,10 @@ public class Editor extends JFrame implements RunnerListener {
public void setSelectedText(String what) {
- textarea.setSelectedText(what);
+ textarea.replaceSelection(what);
}
-
public void setSelection(int start, int stop) {
- // make sure that a tool isn't asking for a bad location
- start = PApplet.constrain(start, 0, textarea.getDocumentLength());
- stop = PApplet.constrain(stop, 0, textarea.getDocumentLength());
-
textarea.select(start, stop);
}
@@ -1599,7 +1729,7 @@ public class Editor extends JFrame implements RunnerListener {
* Get the end point of the current selection.
*/
public int getSelectionStop() {
- return textarea.getSelectionStop();
+ return textarea.getSelectionEnd();
}
@@ -1607,18 +1737,11 @@ public class Editor extends JFrame implements RunnerListener {
* Get text for a specified line.
*/
public String getLineText(int line) {
- return textarea.getLineText(line);
- }
-
-
- /**
- * Replace the text on a specified line.
- */
- public void setLineText(int line, String what) {
- startCompoundEdit();
- textarea.select(getLineStartOffset(line), getLineStopOffset(line));
- textarea.setSelectedText(what);
- stopCompoundEdit();
+ try {
+ return textarea.getText(textarea.getLineStartOffset(line), textarea.getLineEndOffset(line));
+ } catch (BadLocationException e) {
+ return "";
+ }
}
@@ -1626,7 +1749,11 @@ public class Editor extends JFrame implements RunnerListener {
* Get character offset for the start of a given line of text.
*/
public int getLineStartOffset(int line) {
- return textarea.getLineStartOffset(line);
+ try {
+ return textarea.getLineStartOffset(line);
+ } catch (BadLocationException e) {
+ return -1;
+ }
}
@@ -1634,7 +1761,11 @@ public class Editor extends JFrame implements RunnerListener {
* Get character offset for end of a given line of text.
*/
public int getLineStopOffset(int line) {
- return textarea.getLineStopOffset(line);
+ try {
+ return textarea.getLineEndOffset(line);
+ } catch (BadLocationException e) {
+ return -1;
+ }
}
@@ -1644,31 +1775,10 @@ public class Editor extends JFrame implements RunnerListener {
public int getLineCount() {
return textarea.getLineCount();
}
-
-
- /**
- * Use before a manipulating text to group editing operations together as a
- * single undo. Use stopCompoundEdit() once finished.
- */
- public void startCompoundEdit() {
- compoundEdit = new CompoundEdit();
- }
-
-
- /**
- * Use with startCompoundEdit() to group edit operations in a single undo.
- */
- public void stopCompoundEdit() {
- compoundEdit.end();
- undo.addEdit(compoundEdit);
- undoAction.updateUndoState();
- redoAction.updateRedoState();
- compoundEdit = null;
- }
-
+
public int getScrollPosition() {
- return textarea.getScrollPosition();
+ return scrollPane.getVerticalScrollBar().getValue();
}
@@ -1679,15 +1789,12 @@ public class Editor extends JFrame implements RunnerListener {
* Switch between tabs, this swaps out the Document object
* that's currently being manipulated.
*/
- protected void setCode(SketchCodeDocument codeDoc) {
- SyntaxDocument document = (SyntaxDocument) codeDoc.getDocument();
+ protected void setCode(final SketchCodeDocument codeDoc) {
+ RSyntaxDocument document = (RSyntaxDocument) codeDoc.getDocument();
if (document == null) { // this document not yet inited
- document = new SyntaxDocument();
- codeDoc.setDocument(document);
-
- // turn on syntax highlighting
- document.setTokenMarker(new PdeKeywords());
+ document = new RSyntaxDocument(new ArduinoTokenMakerFactory(base.getPdeKeywords()), RSyntaxDocument.SYNTAX_STYLE_CPLUSPLUS);
+ document.putProperty(PlainDocument.tabSizeAttribute, PreferencesData.getInteger("editor.tabs.size"));
// insert the program text into the document object
try {
@@ -1695,37 +1802,39 @@ public class Editor extends JFrame implements RunnerListener {
} catch (BadLocationException bl) {
bl.printStackTrace();
}
-
// set up this guy's own undo manager
// code.undo = new UndoManager();
-
- // connect the undo listener to the editor
- document.addUndoableEditListener(new UndoableEditListener() {
- public void undoableEditHappened(UndoableEditEvent e) {
- if (compoundEdit != null) {
- compoundEdit.addEdit(new CaretAwareUndoableEdit(e.getEdit(), textarea));
- } else if (undo != null) {
- undo.addEdit(new CaretAwareUndoableEdit(e.getEdit(), textarea));
- }
- if (compoundEdit != null || undo != null) {
- sketch.setModified(true);
- undoAction.updateUndoState();
- redoAction.updateRedoState();
- }
- }
- });
+
+ codeDoc.setDocument(document);
}
- // update the document object that's in use
- textarea.setDocument(document,
- codeDoc.getSelectionStart(), codeDoc.getSelectionStop(),
- codeDoc.getScrollPosition());
-
+ if(codeDoc.getUndo() == null){
+ codeDoc.setUndo(new LastUndoableEditAwareUndoManager(textarea, this));
+ document.addUndoableEditListener(codeDoc.getUndo());
+ }
+
+ // Update the document object that's in use
+ textarea.switchDocument(document, codeDoc.getUndo());
+
+ // HACK multiple tabs: for update Listeners of Gutter, forcin call: Gutter.setTextArea(RTextArea)
+ // BUG: https://github.com/bobbylight/RSyntaxTextArea/issues/84
+ scrollPane.setViewportView(textarea);
+
+ textarea.select(codeDoc.getSelectionStart(), codeDoc.getSelectionStop());
textarea.requestFocus(); // get the caret blinking
-
- this.undo = codeDoc.getUndo();
- undoAction.updateUndoState();
- redoAction.updateRedoState();
+
+ final int position = codeDoc.getScrollPosition();
+
+ // invokeLater: Expect the document to be rendered correctly to set the new position
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ scrollPane.getVerticalScrollBar().setValue(position);
+ undoAction.updateUndoState();
+ redoAction.updateRedoState();
+ }
+ });
+
}
@@ -1737,7 +1846,6 @@ public class Editor extends JFrame implements RunnerListener {
*/
public void handleCut() {
textarea.cut();
- sketch.setModified(true);
}
@@ -1764,7 +1872,6 @@ public class Editor extends JFrame implements RunnerListener {
*/
public void handlePaste() {
textarea.paste();
- sketch.setModified(true);
}
@@ -1775,104 +1882,68 @@ public class Editor extends JFrame implements RunnerListener {
textarea.selectAll();
}
-
- protected void handleCommentUncomment() {
- startCompoundEdit();
-
- int startLine = textarea.getSelectionStartLine();
- int stopLine = textarea.getSelectionStopLine();
-
- int lastLineStart = textarea.getLineStartOffset(stopLine);
- int selectionStop = textarea.getSelectionStop();
- // If the selection ends at the beginning of the last line,
- // then don't (un)comment that line.
- if (selectionStop == lastLineStart) {
- // Though if there's no selection, don't do that
- if (textarea.isSelectionActive()) {
- stopLine--;
- }
- }
-
- // If the text is empty, ignore the user.
- // Also ensure that all lines are commented (not just the first)
- // when determining whether to comment or uncomment.
- int length = textarea.getDocumentLength();
- boolean commented = true;
- for (int i = startLine; commented && (i <= stopLine); i++) {
- int pos = textarea.getLineStartOffset(i);
- if (pos + 2 > length) {
- commented = false;
- } else {
- // Check the first two characters to see if it's already a comment.
- String begin = textarea.getText(pos, 2);
- //System.out.println("begin is '" + begin + "'");
- commented = begin.equals("//");
- }
- }
-
- for (int line = startLine; line <= stopLine; line++) {
- int location = textarea.getLineStartOffset(line);
- if (commented) {
- // remove a comment
- textarea.select(location, location+2);
- if (textarea.getSelectedText().equals("//")) {
- textarea.setSelectedText("");
- }
- } else {
- // add a comment
- textarea.select(location, location);
- textarea.setSelectedText("//");
- }
- }
- // Subtract one from the end, otherwise selects past the current line.
- // (Which causes subsequent calls to keep expanding the selection)
- textarea.select(textarea.getLineStartOffset(startLine),
- textarea.getLineStopOffset(stopLine) - 1);
- stopCompoundEdit();
+ /**
+ * Begins an "atomic" edit. This method is called when TextArea
+ * KNOWS that some edits should be compound automatically, such as the playing back of a macro.
+ *
+ * @see #endInternalAtomicEdit()
+ */
+ public void beginInternalAtomicEdit(){
+ textarea.getUndoManager().beginInternalAtomicEdit();
}
+ /**
+ * Ends an "atomic" edit.
+ *
+ * @see #beginInternalAtomicEdit()
+ */
+ public void endInternalAtomicEdit(){
+ textarea.getUndoManager().endInternalAtomicEdit();
+ }
+
+
+ void handleCommentUncomment() {
+
+ Action action = textarea.getActionMap().get(RSyntaxTextAreaEditorKit.rstaToggleCommentAction);
+ action.actionPerformed(null);
+
+ }
+
protected void handleIndentOutdent(boolean indent) {
- int tabSize = Preferences.getInteger("editor.tabs.size");
- String tabString = Editor.EMPTY.substring(0, tabSize);
+ if (indent) {
- startCompoundEdit();
+ int caretPosition = textarea.getCaretPosition();
+ boolean noSelec = !textarea.isSelectionActive();
- int startLine = textarea.getSelectionStartLine();
- int stopLine = textarea.getSelectionStopLine();
-
- // If the selection ends at the beginning of the last line,
- // then don't (un)comment that line.
- int lastLineStart = textarea.getLineStartOffset(stopLine);
- int selectionStop = textarea.getSelectionStop();
- if (selectionStop == lastLineStart) {
- // Though if there's no selection, don't do that
- if (textarea.isSelectionActive()) {
- stopLine--;
- }
- }
-
- for (int line = startLine; line <= stopLine; line++) {
- int location = textarea.getLineStartOffset(line);
-
- if (indent) {
- textarea.select(location, location);
- textarea.setSelectedText(tabString);
-
- } else { // outdent
- textarea.select(location, location + tabSize);
- // Don't eat code if it's not indented
- if (textarea.getSelectedText().equals(tabString)) {
- textarea.setSelectedText("");
+ // if no selection, focus on first char.
+ if (noSelec) {
+ try {
+ int line = textarea.getCaretLineNumber();
+ int startOffset = textarea.getLineStartOffset(line);
+ textarea.setCaretPosition(startOffset);
+ } catch (BadLocationException e) {
}
}
+
+ // Insert Tab or Spaces..
+ Action action = textarea.getActionMap().get(RSyntaxTextAreaEditorKit.insertTabAction);
+ action.actionPerformed(null);
+
+ if (noSelec) {
+ textarea.setCaretPosition(caretPosition);
+ }
+
+ } else {
+ Action action = textarea.getActionMap().get(RSyntaxTextAreaEditorKit.rstaDecreaseIndentAction);
+ action.actionPerformed(null);
}
- // Subtract one from the end, otherwise selects past the current line.
- // (Which causes subsequent calls to keep expanding the selection)
- textarea.select(textarea.getLineStartOffset(startLine),
- textarea.getLineStopOffset(stopLine) - 1);
- stopCompoundEdit();
}
+
+ /** Checks the preferences you are in external editing mode */
+ public static boolean isExternalMode(){
+ return PreferencesData.getBoolean("editor.external");
+ }
protected String getCurrentKeyword() {
String text = "";
@@ -1918,7 +1989,7 @@ public class Editor extends JFrame implements RunnerListener {
protected void handleFindReference() {
String text = getCurrentKeyword();
- String referenceFile = PdeKeywords.getReference(text);
+ String referenceFile = base.getPdeKeywords().getReference(text);
if (referenceFile == null) {
statusNotice(I18n.format(_("No reference available for \"{0}\""), text));
} else {
@@ -1933,10 +2004,12 @@ public class Editor extends JFrame implements RunnerListener {
/**
* Implements Sketch → Run.
* @param verbose Set true to run with verbose output.
+ * @param verboseHandler
+ * @param nonVerboseHandler
*/
- public void handleRun(final boolean verbose) {
+ public void handleRun(final boolean verbose, Runnable verboseHandler, Runnable nonVerboseHandler) {
internalCloseRunner();
- if (Preferences.getBoolean("editor.save_on_verify")) {
+ if (PreferencesData.getBoolean("editor.save_on_verify")) {
if (sketch.isModified() && !sketch.isReadOnly()) {
handleSave(true);
}
@@ -1949,32 +2022,39 @@ public class Editor extends JFrame implements RunnerListener {
for (int i = 0; i < 10; i++) System.out.println();
// clear the console on each run, unless the user doesn't want to
- if (Preferences.getBoolean("console.auto_clear")) {
+ if (PreferencesData.getBoolean("console.auto_clear")) {
console.clear();
}
// Cannot use invokeLater() here, otherwise it gets
// placed on the event thread and causes a hang--bad idea all around.
- new Thread(verbose ? presentHandler : runHandler).start();
+ new Thread(verbose ? verboseHandler : nonVerboseHandler).start();
}
class BuildHandler implements Runnable {
private final boolean verbose;
+ private final boolean saveHex;
public BuildHandler() {
this(false);
}
public BuildHandler(boolean verbose) {
+ this(verbose, false);
+ }
+
+ public BuildHandler(boolean verbose, boolean saveHex) {
this.verbose = verbose;
+ this.saveHex = saveHex;
}
@Override
public void run() {
try {
+ textarea.removeAllLineHighlights();
sketch.prepare();
- sketch.build(verbose);
+ sketch.build(verbose, saveHex);
statusNotice(_("Done compiling."));
} catch (PreferencesMapException e) {
statusError(I18n.format(
@@ -2154,7 +2234,7 @@ public class Editor extends JFrame implements RunnerListener {
sketch.setCurrentCode(codeIndex);
textarea.select(selStart, selStop);
- textarea.setScrollPosition(scrollPos);
+ scrollPane.getVerticalScrollBar().setValue(scrollPos);
}
@@ -2245,16 +2325,14 @@ public class Editor extends JFrame implements RunnerListener {
return false;
}
header.rebuild();
- // Set the title of the window to "sketch_070752a - Processing 0126"
- setTitle(I18n.format(_("{0} | Arduino {1}"), sketch.getName(),
- BaseNoGui.VERSION_NAME));
+ setTitle(I18n.format(_("{0} | Arduino {1}"), sketch.getName(), BaseNoGui.VERSION_NAME_LONG));
// Disable untitled setting from previous document, if any
untitled = false;
// Store information on who's open and running
// (in case there's a crash or something that can't be recovered)
base.storeSketches();
- Preferences.save();
+ PreferencesData.save();
// opening was successful
return true;
@@ -2279,6 +2357,7 @@ public class Editor extends JFrame implements RunnerListener {
public boolean handleSave(boolean immediately) {
//stopRunner();
handleStop(); // 0136
+ textarea.removeAllLineHighlights();
if (untitled) {
return handleSaveAs();
@@ -2375,7 +2454,7 @@ public class Editor extends JFrame implements RunnerListener {
I18n.format(
_("Serial port {0} not found.\n" +
"Retry the upload with another serial port?"),
- Preferences.get("serial.port")
+ PreferencesData.get("serial.port")
),
"Serial port not found",
JOptionPane.PLAIN_MESSAGE,
@@ -2405,7 +2484,7 @@ public class Editor extends JFrame implements RunnerListener {
* hitting export twice, quickly, and horking things up.
*/
synchronized public void handleExport(final boolean usingProgrammer) {
- if (Preferences.getBoolean("editor.save_on_verify")) {
+ if (PreferencesData.getBoolean("editor.save_on_verify")) {
if (sketch.isModified() && !sketch.isReadOnly()) {
handleSave(true);
}
@@ -2548,10 +2627,10 @@ public class Editor extends JFrame implements RunnerListener {
}
}
- BoardPort port = Base.getDiscoveryManager().find(Preferences.get("serial.port"));
+ BoardPort port = Base.getDiscoveryManager().find(PreferencesData.get("serial.port"));
if (port == null) {
- statusError(I18n.format("Board at {0} is not available", Preferences.get("serial.port")));
+ statusError(I18n.format("Board at {0} is not available", PreferencesData.get("serial.port")));
return;
}
@@ -2560,7 +2639,7 @@ public class Editor extends JFrame implements RunnerListener {
boolean success = false;
do {
- if (serialMonitor.requiresAuthorization() && !Preferences.has(serialMonitor.getAuthorizationKey())) {
+ if (serialMonitor.requiresAuthorization() && !PreferencesData.has(serialMonitor.getAuthorizationKey())) {
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(this, _("Type board password to access its console"));
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
@@ -2570,7 +2649,7 @@ public class Editor extends JFrame implements RunnerListener {
return;
}
- Preferences.set(serialMonitor.getAuthorizationKey(), dialog.getPassword());
+ PreferencesData.set(serialMonitor.getAuthorizationKey(), dialog.getPassword());
}
try {
@@ -2591,7 +2670,7 @@ public class Editor extends JFrame implements RunnerListener {
statusError(e);
} finally {
if (serialMonitor.requiresAuthorization() && !success) {
- Preferences.remove(serialMonitor.getAuthorizationKey());
+ PreferencesData.remove(serialMonitor.getAuthorizationKey());
}
}
@@ -2655,9 +2734,9 @@ public class Editor extends JFrame implements RunnerListener {
}
if (pageFormat != null) {
//System.out.println("setting page format " + pageFormat);
- printerJob.setPrintable(textarea.getPainter(), pageFormat);
+ printerJob.setPrintable(textarea, pageFormat);
} else {
- printerJob.setPrintable(textarea.getPainter());
+ printerJob.setPrintable(textarea);
}
// set the name of the job to the code name
printerJob.setJobName(sketch.getCurrentCode().getPrettyName());
@@ -2714,7 +2793,7 @@ public class Editor extends JFrame implements RunnerListener {
// The error is at the end of this current chunk of code,
// so the last line needs to be selected.
line = textarea.getLineCount() - 1;
- if (textarea.getLineText(line).length() == 0) {
+ if (getLineText(line).length() == 0) {
// The last line may be zero length, meaning nothing to select.
// If so, back up one more line.
line--;
@@ -2723,8 +2802,12 @@ public class Editor extends JFrame implements RunnerListener {
if (line < 0 || line >= textarea.getLineCount()) {
System.err.println(I18n.format(_("Bad error line: {0}"), line));
} else {
- textarea.select(textarea.getLineStartOffset(line),
- textarea.getLineStopOffset(line) - 1);
+ try {
+ textarea.addLineHighlight(line, new Color(1, 0, 0, 0.2f));
+ textarea.setCaretPosition(textarea.getLineStartOffset(line));
+ } catch (BadLocationException e1) {
+ e1.printStackTrace();
+ }
}
}
}
@@ -2767,154 +2850,109 @@ public class Editor extends JFrame implements RunnerListener {
protected void onBoardOrPortChange() {
Map boardPreferences = Base.getBoardPreferences();
- lineStatus.setBoardName(boardPreferences.get("name"));
- lineStatus.setSerialPort(Preferences.get("serial.port"));
+ if (boardPreferences != null)
+ lineStatus.setBoardName(boardPreferences.get("name"));
+ else
+ lineStatus.setBoardName("-");
+ lineStatus.setSerialPort(PreferencesData.get("serial.port"));
lineStatus.repaint();
}
- /**
- * Returns the edit popup menu.
- */
- class TextAreaPopup extends JPopupMenu {
- //private String currentDir = System.getProperty("user.dir");
- private String referenceFile = null;
+ protected void configurePopupMenu(final SketchTextArea textarea){
- private JMenuItem cutItem;
- private JMenuItem copyItem;
- private JMenuItem discourseItem;
- private JMenuItem referenceItem;
- private JMenuItem openURLItem;
- private JSeparator openURLItemSeparator;
+ JPopupMenu menu = textarea.getPopupMenu();
- private String clickedURL;
+ menu.addSeparator();
- public TextAreaPopup() {
- openURLItem = new JMenuItem(_("Open URL"));
- openURLItem.addActionListener(new ActionListener() {
+ JMenuItem item = createToolMenuItem("cc.arduino.packages.formatter.AStyle");
+ item.setName("menuToolsAutoFormat");
+
+ menu.add(item);
+
+ item = newJMenuItem(_("Comment/Uncomment"), '/');
+ item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- Base.openURL(clickedURL);
+ handleCommentUncomment();
}
- });
- add(openURLItem);
+ });
+ menu.add(item);
- openURLItemSeparator = new JSeparator();
- add(openURLItemSeparator);
-
- cutItem = new JMenuItem(_("Cut"));
- cutItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleCut();
- }
- });
- add(cutItem);
-
- copyItem = new JMenuItem(_("Copy"));
- copyItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleCopy();
- }
- });
- add(copyItem);
-
- discourseItem = new JMenuItem(_("Copy for Forum"));
- discourseItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleDiscourseCopy();
- }
- });
- add(discourseItem);
-
- discourseItem = new JMenuItem(_("Copy as HTML"));
- discourseItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleHTMLCopy();
- }
- });
- add(discourseItem);
-
- JMenuItem item = new JMenuItem(_("Paste"));
- item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handlePaste();
- }
- });
- add(item);
-
- item = new JMenuItem(_("Select All"));
- item.addActionListener(new ActionListener() {
+ item = newJMenuItem(_("Increase Indent"), ']');
+ item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
- handleSelectAll();
+ handleIndentOutdent(true);
}
- });
- add(item);
+ });
+ menu.add(item);
- addSeparator();
+ item = newJMenuItem(_("Decrease Indent"), '[');
+ item.setName("menuDecreaseIndent");
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleIndentOutdent(false);
+ }
+ });
+ menu.add(item);
- item = new JMenuItem(_("Comment/Uncomment"));
- item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleCommentUncomment();
- }
- });
- add(item);
+ item = new JMenuItem(_("Copy for Forum"));
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleDiscourseCopy();
+ }
+ });
+ menu.add(item);
- item = new JMenuItem(_("Increase Indent"));
- item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleIndentOutdent(true);
- }
- });
- add(item);
+ item = new JMenuItem(_("Copy as HTML"));
+ item.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleHTMLCopy();
+ }
+ });
+ menu.add(item);
- item = new JMenuItem(_("Decrease Indent"));
- item.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleIndentOutdent(false);
- }
- });
- add(item);
+ final JMenuItem referenceItem = new JMenuItem(_("Find in Reference"));
+ referenceItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ handleFindReference();
+ }
+ });
+ menu.add(referenceItem);
- addSeparator();
+ final JMenuItem openURLItem = new JMenuItem(_("Open URL"));
+ openURLItem.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Base.openURL(e.getActionCommand());
+ }
+ });
+ menu.add(openURLItem);
+
+ menu.addPopupMenuListener(new PopupMenuListener() {
- referenceItem = new JMenuItem(_("Find in Reference"));
- referenceItem.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- handleFindReference();
- }
- });
- add(referenceItem);
- }
-
- // if no text is selected, disable copy and cut menu items
- public void show(Component component, int x, int y) {
- int lineNo = textarea.getLineOfOffset(textarea.xyToOffset(x, y));
- int offset = textarea.xToOffset(lineNo, x);
- String line = textarea.getLineText(lineNo);
- clickedURL = textarea.checkClickedURL(line, offset);
- if (clickedURL != null) {
- openURLItem.setVisible(true);
- openURLItemSeparator.setVisible(true);
- } else {
- openURLItem.setVisible(false);
- openURLItemSeparator.setVisible(false);
+ @Override
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+ String referenceFile = base.getPdeKeywords().getReference(getCurrentKeyword());
+ referenceItem.setEnabled(referenceFile != null);
+
+ int offset = textarea.getCaretPosition();
+ org.fife.ui.rsyntaxtextarea.Token token = RSyntaxUtilities.getTokenAtOffset(textarea, offset);
+ if (token != null && token.isHyperlink()) {
+ openURLItem.setEnabled(true);
+ openURLItem.setActionCommand(token.getLexeme());
+ } else {
+ openURLItem.setEnabled(false);
+ }
}
- if (textarea.isSelectionActive()) {
- cutItem.setEnabled(true);
- copyItem.setEnabled(true);
- discourseItem.setEnabled(true);
-
- } else {
- cutItem.setEnabled(false);
- copyItem.setEnabled(false);
- discourseItem.setEnabled(false);
+ @Override
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
- referenceFile = PdeKeywords.getReference(getCurrentKeyword());
- referenceItem.setEnabled(referenceFile != null);
+ @Override
+ public void popupMenuCanceled(PopupMenuEvent e) {
+ }
+ });
- super.show(component, x, y);
- }
}
+
}
diff --git a/app/src/processing/app/EditorConsole.java b/app/src/processing/app/EditorConsole.java
index 8c4910093..a2116f8b4 100644
--- a/app/src/processing/app/EditorConsole.java
+++ b/app/src/processing/app/EditorConsole.java
@@ -68,7 +68,7 @@ public class EditorConsole extends JScrollPane {
public EditorConsole(Editor _editor) {
editor = _editor;
- int maxLineCount = Preferences.getInteger("console.length");
+ int maxLineCount = PreferencesData.getInteger("console.length");
consoleDoc = new BufferedStyledDocument(4000, maxLineCount);
consoleTextPane = new JTextPane(consoleDoc);
@@ -84,7 +84,7 @@ public class EditorConsole extends JScrollPane {
Color fgColorOut = Theme.getColor("console.output.color");
Color fgColorErr = Theme.getColor("console.error.color");
Font consoleFont = Theme.getFont("console.font");
- Font editorFont = Preferences.getFont("editor.font");
+ Font editorFont = PreferencesData.getFont("editor.font");
Font font = new Font(consoleFont.getName(), consoleFont.getStyle(), editorFont.getSize());
stdStyle = new SimpleAttributeSet();
@@ -112,7 +112,7 @@ public class EditorConsole extends JScrollPane {
// and size window accordingly
FontMetrics metrics = getFontMetrics(font);
int height = metrics.getAscent() + metrics.getDescent();
- int lines = Preferences.getInteger("console.lines");
+ int lines = PreferencesData.getInteger("console.lines");
int sizeFudge = 6; //10; // unclear why this is necessary, but it is
setPreferredSize(new Dimension(1024, (height * lines) + sizeFudge));
setMinimumSize(new Dimension(1024, (height * 4) + sizeFudge));
diff --git a/app/src/processing/app/EditorConsoleStream.java b/app/src/processing/app/EditorConsoleStream.java
index 06e232673..6ad0a336a 100644
--- a/app/src/processing/app/EditorConsoleStream.java
+++ b/app/src/processing/app/EditorConsoleStream.java
@@ -1,5 +1,7 @@
package processing.app;
+import cc.arduino.files.DeleteFilesOnShutdown;
+
import static processing.app.I18n._;
import java.io.File;
@@ -33,19 +35,19 @@ class EditorConsoleStream extends OutputStream {
// The files and folders are not deleted on exit because they may be
// needed for debugging or bug reporting.
tempFolder = Base.createTempFolder("console");
- tempFolder.deleteOnExit();
+ DeleteFilesOnShutdown.add(tempFolder);
try {
- String outFileName = Preferences.get("console.output.file");
+ String outFileName = PreferencesData.get("console.output.file");
if (outFileName != null) {
outFile = new File(tempFolder, outFileName);
- outFile.deleteOnExit();
+ DeleteFilesOnShutdown.add(outFile);
stdoutFile = new FileOutputStream(outFile);
}
- String errFileName = Preferences.get("console.error.file");
+ String errFileName = PreferencesData.get("console.error.file");
if (errFileName != null) {
errFile = new File(tempFolder, errFileName);
- errFile.deleteOnExit();
+ DeleteFilesOnShutdown.add(errFile);
stderrFile = new FileOutputStream(errFile);
}
} catch (IOException e) {
@@ -56,7 +58,7 @@ class EditorConsoleStream extends OutputStream {
consoleOut = new PrintStream(new EditorConsoleStream(false));
consoleErr = new PrintStream(new EditorConsoleStream(true));
- if (Preferences.getBoolean("console")) {
+ if (PreferencesData.getBoolean("console")) {
try {
System.setOut(consoleOut);
System.setErr(consoleErr);
diff --git a/app/src/processing/app/EditorLineStatus.java b/app/src/processing/app/EditorLineStatus.java
index 8420ddd4c..2696d7d41 100644
--- a/app/src/processing/app/EditorLineStatus.java
+++ b/app/src/processing/app/EditorLineStatus.java
@@ -1,3 +1,5 @@
+/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
+
/*
Part of the Processing project - http://processing.org
@@ -20,26 +22,21 @@
package processing.app;
-import processing.app.helpers.OSUtils;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Image;
+import java.awt.*;
import java.awt.geom.Rectangle2D;
+import java.util.Map;
import javax.swing.JComponent;
+import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesMap;
-import processing.app.syntax.JEditTextArea;
+import processing.app.syntax.SketchTextArea;
+
/**
* Li'l status bar fella that shows the line number.
*/
-@SuppressWarnings("serial")
public class EditorLineStatus extends JComponent {
- JEditTextArea textarea;
int start = -1, stop;
Image resize;
@@ -55,10 +52,8 @@ public class EditorLineStatus extends JComponent {
String name = "";
String serialport = "";
- public EditorLineStatus(JEditTextArea textarea) {
- this.textarea = textarea;
- textarea.editorLineStatus = this;
+ public EditorLineStatus() {
background = Theme.getColor("linestatus.bgcolor");
font = Theme.getFont("linestatus.font");
foreground = Theme.getColor("linestatus.color");
@@ -101,7 +96,7 @@ public class EditorLineStatus extends JComponent {
setBoardName(boardPreferences.get("name"));
else
setBoardName("-");
- setSerialPort(Preferences.get("serial.port"));
+ setSerialPort(PreferencesData.get("serial.port"));
}
g.setColor(background);
Dimension size = getSize();
diff --git a/app/src/processing/app/EditorListener.java b/app/src/processing/app/EditorListener.java
index c2d2fe600..19e90b1c3 100644
--- a/app/src/processing/app/EditorListener.java
+++ b/app/src/processing/app/EditorListener.java
@@ -1,636 +1,83 @@
-/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-
-/*
- Part of the Processing project - http://processing.org
-
- Copyright (c) 2004-08 Ben Fry and Casey Reas
- Copyright (c) 2001-04 Massachusetts Institute of Technology
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
package processing.app;
-import processing.app.syntax.*;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
-import java.awt.*;
-import java.awt.event.*;
+import processing.app.syntax.SketchTextArea;
-
-/**
- * Filters key events for tab expansion/indent/etc.
- *
- * For version 0099, some changes have been made to make the indents
- * smarter. There are still issues though:
- * + indent happens when it picks up a curly brace on the previous line,
- * but not if there's a blank line between them.
- * + It also doesn't handle single indent situations where a brace
- * isn't used (i.e. an if statement or for loop that's a single line).
- * It shouldn't actually be using braces.
- * Solving these issues, however, would probably best be done by a
- * smarter parser/formatter, rather than continuing to hack this class.
- */
-public class EditorListener {
+public class EditorListener implements KeyListener {
+
private Editor editor;
- private JEditTextArea textarea;
-
- private boolean externalEditor;
- private boolean tabsExpand;
- private boolean tabsIndent;
- private int tabSize;
- private String tabString;
- private boolean autoIndent;
-
-// private int selectionStart, selectionEnd;
-// private int position;
-
- /** ctrl-alt on windows and linux, cmd-alt on mac os x */
- static final int CTRL_ALT = ActionEvent.ALT_MASK |
- Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
-
-
- public EditorListener(Editor editor, JEditTextArea textarea) {
+
+ public EditorListener(Editor editor) {
+ super();
this.editor = editor;
- this.textarea = textarea;
-
- // let him know that i'm leechin'
- textarea.editorListener = this;
-
- applyPreferences();
}
+
+ /** ctrl-alt on windows and linux, cmd-alt on mac os x */
+ static final int CTRL_ALT = ActionEvent.ALT_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
+ static final int CTRL_SHIFT = ActionEvent.SHIFT_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
+
+ static final int CTRL = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
+
- public void applyPreferences() {
- tabsExpand = Preferences.getBoolean("editor.tabs.expand");
- //tabsIndent = Preferences.getBoolean("editor.tabs.indent");
- tabSize = Preferences.getInteger("editor.tabs.size");
- tabString = Editor.EMPTY.substring(0, tabSize);
- autoIndent = Preferences.getBoolean("editor.indent");
- externalEditor = Preferences.getBoolean("editor.external");
- }
-
-
- //public void setExternalEditor(boolean externalEditor) {
- //this.externalEditor = externalEditor;
- //}
-
-
- /**
- * Intercepts key pressed events for JEditTextArea.
- *
- * Called by JEditTextArea inside processKeyEvent(). Note that this
- * won't intercept actual characters, because those are fired on
- * keyTyped().
- * @return true if the event has been handled (to remove it from the queue)
- */
- public boolean keyPressed(KeyEvent event) {
- // don't do things if the textarea isn't editable
- if (externalEditor) return false;
-
- //deselect(); // this is for paren balancing
+ public void keyTyped(KeyEvent event) {
char c = event.getKeyChar();
- int code = event.getKeyCode();
-// if (code == KeyEvent.VK_SHIFT) {
-// editor.toolbar.setShiftPressed(true);
-// }
-
- //System.out.println((int)c + " " + code + " " + event);
- //System.out.println();
+ if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
+ // The char is not control code when CTRL key pressed? It should be a shortcut.
+ if (!Character.isISOControl(c)) {
+ event.consume();
+ }
+ }
+ }
+ @Override
+ public void keyPressed(KeyEvent event) {
+
+ SketchTextArea textarea = editor.getTextArea();
+
+ if (!textarea.isEditable()) return;
+
Sketch sketch = editor.getSketch();
+ int code = event.getKeyCode();
+
+ // Navigation..
+ if ((event.getModifiers() & CTRL) == CTRL && code == KeyEvent.VK_TAB) {
+ sketch.handleNextCode();
+ }
+
+ // Navigation..
+ // FIXME: not working on LINUX !!!
+ if (((event.getModifiers() & CTRL_SHIFT) == CTRL_SHIFT)) {
+ if(code == KeyEvent.VK_TAB)
+ sketch.handlePrevCode();
+ }
+
+ // Navigation..
if ((event.getModifiers() & CTRL_ALT) == CTRL_ALT) {
if (code == KeyEvent.VK_LEFT) {
sketch.handlePrevCode();
- return true;
} else if (code == KeyEvent.VK_RIGHT) {
sketch.handleNextCode();
- return true;
}
}
-
- if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
- // Consume ctrl-m(carriage return) keypresses
- if (code == KeyEvent.VK_M) {
- event.consume(); // does nothing
- return false;
- }
-
- // The char is not control code when CTRL key pressed? It should be a shortcut.
- if (!Character.isISOControl(c)) {
- return false;
- }
- }
-
- if ((event.getModifiers() & KeyEvent.META_MASK) != 0) {
- //event.consume(); // does nothing
- return false;
- }
-
- // TODO i don't like these accessors. clean em up later.
- if (!editor.getSketch().isModified()) {
- if ((code == KeyEvent.VK_BACK_SPACE) || (code == KeyEvent.VK_TAB) ||
- (code == KeyEvent.VK_ENTER) || ((c >= 32) && (c < 128))) {
- sketch.setModified(true);
- }
- }
-
- if ((code == KeyEvent.VK_UP) &&
- ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
- // back up to the last empty line
- char contents[] = textarea.getText().toCharArray();
- //int origIndex = textarea.getCaretPosition() - 1;
- int caretIndex = textarea.getCaretPosition();
-
- int index = calcLineStart(caretIndex - 1, contents);
- //System.out.println("line start " + (int) contents[index]);
- index -= 2; // step over the newline
- //System.out.println((int) contents[index]);
- boolean onlySpaces = true;
- while (index > 0) {
- if (contents[index] == 10) {
- if (onlySpaces) {
- index++;
- break;
- } else {
- onlySpaces = true; // reset
- }
- } else if (contents[index] != ' ') {
- onlySpaces = false;
- }
- index--;
- }
- // if the first char, index will be -2
- if (index < 0) index = 0;
-
- if ((event.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
- textarea.setSelectionStart(caretIndex);
- textarea.setSelectionEnd(index);
- } else {
- textarea.setCaretPosition(index);
- }
- event.consume();
- return true;
-
- } else if ((code == KeyEvent.VK_DOWN) &&
- ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
- char contents[] = textarea.getText().toCharArray();
- int caretIndex = textarea.getCaretPosition();
-
- int index = caretIndex;
- int lineStart = 0;
- boolean onlySpaces = false; // don't count this line
- while (index < contents.length) {
- if (contents[index] == 10) {
- if (onlySpaces) {
- index = lineStart; // this is it
- break;
- } else {
- lineStart = index + 1;
- onlySpaces = true; // reset
- }
- } else if (contents[index] != ' ') {
- onlySpaces = false;
- }
- index++;
- }
- // if the first char, index will be -2
- //if (index < 0) index = 0;
-
- //textarea.setSelectionStart(index);
- //textarea.setSelectionEnd(index);
- if ((event.getModifiers() & KeyEvent.SHIFT_MASK) != 0) {
- textarea.setSelectionStart(caretIndex);
- textarea.setSelectionEnd(index);
- } else {
- textarea.setCaretPosition(index);
- }
- event.consume();
- return true;
- }
-
-
- switch ((int) c) {
-
- case 9: // TAB
- if (textarea.isSelectionActive()) {
- boolean outdent = (event.getModifiers() & KeyEvent.SHIFT_MASK) != 0;
- editor.handleIndentOutdent(!outdent);
-
- } else if (tabsExpand) { // expand tabs
- textarea.setSelectedText(tabString);
- event.consume();
- return true;
-
- } else if (tabsIndent) {
- // this code is incomplete
-
- // if this brace is the only thing on the line, outdent
- //char contents[] = getCleanedContents();
- char contents[] = textarea.getText().toCharArray();
- // index to the character to the left of the caret
- int prevCharIndex = textarea.getCaretPosition() - 1;
-
- // now find the start of this line
- int lineStart = calcLineStart(prevCharIndex, contents);
-
- int lineEnd = lineStart;
- while ((lineEnd < contents.length - 1) &&
- (contents[lineEnd] != 10)) {
- lineEnd++;
- }
-
- // get the number of braces, to determine whether this is an indent
- int braceBalance = 0;
- int index = lineStart;
- while ((index < contents.length) &&
- (contents[index] != 10)) {
- if (contents[index] == '{') {
- braceBalance++;
- } else if (contents[index] == '}') {
- braceBalance--;
- }
- index++;
- }
-
- // if it's a starting indent, need to ignore it, so lineStart
- // will be the counting point. but if there's a closing indent,
- // then the lineEnd should be used.
- int where = (braceBalance > 0) ? lineStart : lineEnd;
- int indent = calcBraceIndent(where, contents);
- if (indent == -1) {
- // no braces to speak of, do nothing
- indent = 0;
- } else {
- indent += tabSize;
- }
-
- // and the number of spaces it has
- int spaceCount = calcSpaceCount(prevCharIndex, contents);
-
- textarea.setSelectionStart(lineStart);
- textarea.setSelectionEnd(lineStart + spaceCount);
- textarea.setSelectedText(Editor.EMPTY.substring(0, indent));
-
- event.consume();
- return true;
- }
- break;
-
- case 10: // auto-indent
- case 13:
- if (autoIndent) {
- char contents[] = textarea.getText().toCharArray();
-
- // this is the previous character
- // (i.e. when you hit return, it'll be the last character
- // just before where the newline will be inserted)
- int origIndex = textarea.getCaretPosition() - 1;
-
- // NOTE all this cursing about CRLF stuff is probably moot
- // NOTE since the switch to JEditTextArea, which seems to use
- // NOTE only LFs internally (thank god). disabling for 0099.
- // walk through the array to the current caret position,
- // and count how many weirdo windows line endings there are,
- // which would be throwing off the caret position number
- /*
- int offset = 0;
- int realIndex = origIndex;
- for (int i = 0; i < realIndex-1; i++) {
- if ((contents[i] == 13) && (contents[i+1] == 10)) {
- offset++;
- realIndex++;
- }
- }
- // back up until \r \r\n or \n.. @#($* cross platform
- //System.out.println(origIndex + " offset = " + offset);
- origIndex += offset; // ARGH!#(* WINDOWS#@($*
- */
-
- // if the previous thing is a brace (whether prev line or
- // up farther) then the correct indent is the number of spaces
- // on that line + 'indent'.
- // if the previous line is not a brace, then just use the
- // identical indentation to the previous line
-
- // calculate the amount of indent on the previous line
- // this will be used *only if the prev line is not an indent*
- int spaceCount = calcSpaceCount(origIndex, contents);
-
- // If the last character was a left curly brace, then indent.
- // For 0122, walk backwards a bit to make sure that the there
- // isn't a curly brace several spaces (or lines) back. Also
- // moved this before calculating extraCount, since it'll affect
- // that as well.
- int index2 = origIndex;
- while ((index2 >= 0) &&
- Character.isWhitespace(contents[index2])) {
- index2--;
- }
- if (index2 != -1) {
- // still won't catch a case where prev stuff is a comment
- if (contents[index2] == '{') {
- // intermediate lines be damned,
- // use the indent for this line instead
- spaceCount = calcSpaceCount(index2, contents);
- spaceCount += tabSize;
- }
- }
- //System.out.println("spaceCount should be " + spaceCount);
-
- // now before inserting this many spaces, walk forward from
- // the caret position and count the number of spaces,
- // so that the number of spaces aren't duplicated again
- int index = origIndex + 1;
- int extraCount = 0;
- while ((index < contents.length) &&
- (contents[index] == ' ')) {
- //spaceCount--;
- extraCount++;
- index++;
- }
- int braceCount = 0;
- while ((index < contents.length) && (contents[index] != '\n')) {
- if (contents[index] == '}') {
- braceCount++;
- }
- index++;
- }
-
- // hitting return on a line with spaces *after* the caret
- // can cause trouble. for 0099, was ignoring the case, but this is
- // annoying, so in 0122 we're trying to fix that.
- /*
- if (spaceCount - extraCount > 0) {
- spaceCount -= extraCount;
- }
- */
- spaceCount -= extraCount;
- //if (spaceCount < 0) spaceCount = 0;
- //System.out.println("extraCount is " + extraCount);
-
- // now, check to see if the current line contains a } and if so,
- // outdent again by indent
- //if (braceCount > 0) {
- //spaceCount -= 2;
- //}
-
- if (spaceCount < 0) {
- // for rev 0122, actually delete extra space
- //textarea.setSelectionStart(origIndex + 1);
- textarea.setSelectionEnd(textarea.getSelectionStop() - spaceCount);
- textarea.setSelectedText("\n");
- } else {
- String insertion = "\n" + Editor.EMPTY.substring(0, spaceCount);
- textarea.setSelectedText(insertion);
- }
-
- // not gonna bother handling more than one brace
- if (braceCount > 0) {
- int sel = textarea.getSelectionStart();
- // sel - tabSize will be -1 if start/end parens on the same line
- // http://dev.processing.org/bugs/show_bug.cgi?id=484
- if (sel - tabSize >= 0) {
- textarea.select(sel - tabSize, sel);
- String s = Editor.EMPTY.substring(0, tabSize);
- // if these are spaces that we can delete
- if (textarea.getSelectedText().equals(s)) {
- textarea.setSelectedText("");
- } else {
- textarea.select(sel, sel);
- }
- }
- }
- } else {
- // Enter/Return was being consumed by somehow even if false
- // was returned, so this is a band-aid to simply fire the event again.
- // http://dev.processing.org/bugs/show_bug.cgi?id=1073
- textarea.setSelectedText(String.valueOf(c));
- }
- // mark this event as already handled (all but ignored)
- event.consume();
- return true;
-
- case '}':
- if (autoIndent) {
- // first remove anything that was there (in case this multiple
- // characters are selected, so that it's not in the way of the
- // spaces for the auto-indent
- if (textarea.getSelectionStart() != textarea.getSelectionStop()) {
- textarea.setSelectedText("");
- }
-
- // if this brace is the only thing on the line, outdent
- char contents[] = textarea.getText().toCharArray();
- // index to the character to the left of the caret
- int prevCharIndex = textarea.getCaretPosition() - 1;
-
- // backup from the current caret position to the last newline,
- // checking for anything besides whitespace along the way.
- // if there's something besides whitespace, exit without
- // messing any sort of indenting.
- int index = prevCharIndex;
- boolean finished = false;
- while ((index != -1) && (!finished)) {
- if (contents[index] == 10) {
- finished = true;
- index++;
- } else if (contents[index] != ' ') {
- // don't do anything, this line has other stuff on it
- return false;
- } else {
- index--;
- }
- }
- if (!finished) return false; // brace with no start
- int lineStartIndex = index;
-
- int pairedSpaceCount = calcBraceIndent(prevCharIndex, contents); //, 1);
- if (pairedSpaceCount == -1) return false;
-
- textarea.setSelectionStart(lineStartIndex);
- textarea.setSelectedText(Editor.EMPTY.substring(0, pairedSpaceCount));
-
- // mark this event as already handled
- event.consume();
- return true;
- }
- break;
- }
- return false;
- }
-
-
-// public boolean keyReleased(KeyEvent event) {
-// if (code == KeyEvent.VK_SHIFT) {
-// editor.toolbar.setShiftPressed(false);
+
+// if (event.isAltDown() && code == KeyEvent.VK_T) {
+// int line = textarea.getCaretLineNumber();
+// textarea.setActiveLineRange(line, line + 3);
// }
-// }
-
-
- public boolean keyTyped(KeyEvent event) {
- char c = event.getKeyChar();
-
- if ((event.getModifiers() & KeyEvent.CTRL_MASK) != 0) {
- // The char is not control code when CTRL key pressed? It should be a shortcut.
- if (!Character.isISOControl(c)) {
- event.consume();
- return true;
- }
- }
- return false;
+
}
-
-
- /**
- * Return the index for the first character on this line.
- */
- protected int calcLineStart(int index, char contents[]) {
- // backup from the current caret position to the last newline,
- // so that we can figure out how far this line was indented
- /*int spaceCount = 0;*/
- boolean finished = false;
- while ((index != -1) && (!finished)) {
- if ((contents[index] == 10) ||
- (contents[index] == 13)) {
- finished = true;
- //index++; // maybe ?
- } else {
- index--; // new
- }
- }
- // add one because index is either -1 (the start of the document)
- // or it's the newline character for the previous line
- return index + 1;
+ @Override
+ public void keyReleased(KeyEvent e) {
+ // TODO Auto-generated method stub
+
}
-
- /**
- * Calculate the number of spaces on this line.
- */
- protected int calcSpaceCount(int index, char contents[]) {
- index = calcLineStart(index, contents);
-
- int spaceCount = 0;
- // now walk forward and figure out how many spaces there are
- while ((index < contents.length) && (index >= 0) &&
- (contents[index++] == ' ')) {
- spaceCount++;
- }
- return spaceCount;
- }
-
-
- /**
- * Walk back from 'index' until the brace that seems to be
- * the beginning of the current block, and return the number of
- * spaces found on that line.
- */
- protected int calcBraceIndent(int index, char contents[]) {
- // now that we know things are ok to be indented, walk
- // backwards to the last { to see how far its line is indented.
- // this isn't perfect cuz it'll pick up commented areas,
- // but that's not really a big deal and can be fixed when
- // this is all given a more complete (proper) solution.
- int braceDepth = 1;
- boolean finished = false;
- while ((index != -1) && (!finished)) {
- if (contents[index] == '}') {
- // aww crap, this means we're one deeper
- // and will have to find one more extra {
- braceDepth++;
- //if (braceDepth == 0) {
- //finished = true;
- //}
- index--;
- } else if (contents[index] == '{') {
- braceDepth--;
- if (braceDepth == 0) {
- finished = true;
- }
- index--;
- } else {
- index--;
- }
- }
- // never found a proper brace, be safe and don't do anything
- if (!finished) return -1;
-
- // check how many spaces on the line with the matching open brace
- //int pairedSpaceCount = calcSpaceCount(index, contents);
- //System.out.println(pairedSpaceCount);
- return calcSpaceCount(index, contents);
- }
-
-
- /**
- * Get the character array and blank out the commented areas.
- * This hasn't yet been tested, the plan was to make auto-indent
- * less gullible (it gets fooled by braces that are commented out).
- */
- protected char[] getCleanedContents() {
- char c[] = textarea.getText().toCharArray();
-
- int index = 0;
- while (index < c.length - 1) {
- if ((c[index] == '/') && (c[index+1] == '*')) {
- c[index++] = 0;
- c[index++] = 0;
- while ((index < c.length - 1) &&
- !((c[index] == '*') && (c[index+1] == '/'))) {
- c[index++] = 0;
- }
-
- } else if ((c[index] == '/') && (c[index+1] == '/')) {
- // clear out until the end of the line
- while ((index < c.length) && (c[index] != 10)) {
- c[index++] = 0;
- }
- if (index != c.length) {
- index++; // skip over the newline
- }
- }
- }
- return c;
- }
-
- /*
- protected char[] getCleanedContents() {
- char c[] = textarea.getText().toCharArray();
- boolean insideMulti; // multi-line comment
- boolean insideSingle; // single line double slash
-
- //for (int i = 0; i < c.length - 1; i++) {
- int index = 0;
- while (index < c.length - 1) {
- if (insideMulti && (c[index] == '*') && (c[index+1] == '/')) {
- insideMulti = false;
- index += 2;
- } else if ((c[index] == '/') && (c[index+1] == '*')) {
- insideMulti = true;
- index += 2;
- } else if ((c[index] == '/') && (c[index+1] == '/')) {
- // clear out until the end of the line
- while (c[index] != 10) {
- c[index++] = 0;
- }
- index++;
- }
- }
- }
- */
-}
+}
\ No newline at end of file
diff --git a/app/src/processing/app/EditorStatus.java b/app/src/processing/app/EditorStatus.java
index 1d90760f1..82abf3aa2 100644
--- a/app/src/processing/app/EditorStatus.java
+++ b/app/src/processing/app/EditorStatus.java
@@ -219,7 +219,7 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
public void unprogress()
{
- if (Preferences.getBoolean("editor.beep.compile")) {
+ if (PreferencesData.getBoolean("editor.beep.compile")) {
Toolkit.getDefaultToolkit().beep();
}
if (progressBar == null) return;
@@ -464,10 +464,10 @@ public class EditorStatus extends JPanel /*implements ActionListener*/ {
copyErrorButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String message = "";
- message += _("Arduino: ") + BaseNoGui.VERSION_NAME + " (" + System.getProperty("os.name") + "), ";
+ message += _("Arduino: ") + BaseNoGui.VERSION_NAME_LONG + " (" + System.getProperty("os.name") + "), ";
message += _("Board: ") + "\"" + Base.getBoardPreferences().get("name") + "\"\n\n";
message += editor.console.consoleTextPane.getText().trim();
- if ((Preferences.getBoolean("build.verbose")) == false) {
+ if ((PreferencesData.getBoolean("build.verbose")) == false) {
message += "\n\n";
message += " " + _("This report would have more information with") + "\n";
message += " \"" + _("Show verbose output during compilation") + "\"\n";
diff --git a/app/src/processing/app/EditorToolbar.java b/app/src/processing/app/EditorToolbar.java
index e33789b36..67edcdb79 100644
--- a/app/src/processing/app/EditorToolbar.java
+++ b/app/src/processing/app/EditorToolbar.java
@@ -321,7 +321,7 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key
switch (sel) {
case RUN:
- editor.handleRun(false);
+ editor.handleRun(false, editor.presentHandler, editor.runHandler);
break;
// case STOP:
diff --git a/app/src/processing/app/LastUndoableEditAwareUndoManager.java b/app/src/processing/app/LastUndoableEditAwareUndoManager.java
index 0cd678a93..736be42d3 100644
--- a/app/src/processing/app/LastUndoableEditAwareUndoManager.java
+++ b/app/src/processing/app/LastUndoableEditAwareUndoManager.java
@@ -2,31 +2,36 @@ package processing.app;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
-import javax.swing.undo.UndoManager;
-import javax.swing.undo.UndoableEdit;
-@SuppressWarnings("serial")
-public class LastUndoableEditAwareUndoManager extends UndoManager {
+import org.fife.ui.rtextarea.RUndoManager;
- private UndoableEdit lastUndoableEdit;
+import processing.app.syntax.SketchTextArea;
- public LastUndoableEditAwareUndoManager() {
- this.lastUndoableEdit = null;
+public class LastUndoableEditAwareUndoManager extends RUndoManager {
+
+ private Editor editor;
+
+ public LastUndoableEditAwareUndoManager(SketchTextArea textarea, Editor editor) {
+ super(textarea);
+ this.editor = editor;
}
@Override
public synchronized void undo() throws CannotUndoException {
- lastUndoableEdit = super.editToBeUndone();
super.undo();
}
@Override
public synchronized void redo() throws CannotRedoException {
- lastUndoableEdit = super.editToBeRedone();
super.redo();
}
-
- public UndoableEdit getLastUndoableEdit() {
- return lastUndoableEdit;
+
+ @Override
+ public void updateActions() {
+ super.updateActions();
+ editor.undoAction.updateUndoState();
+ editor.redoAction.updateRedoState();
}
+
+
}
diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java
index e0910c343..6f76d6e4f 100644
--- a/app/src/processing/app/Preferences.java
+++ b/app/src/processing/app/Preferences.java
@@ -21,58 +21,30 @@
package processing.app;
-import static processing.app.I18n._;
-
-import java.awt.Color;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Insets;
-import java.awt.SystemColor;
-import java.awt.Toolkit;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.io.File;
-
-import javax.swing.Box;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JTextField;
-import javax.swing.KeyStroke;
-
-import processing.app.helpers.FileUtils;
-import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesHelper;
import processing.app.helpers.PreferencesMap;
-import processing.app.legacy.PApplet;
+
+import java.awt.*;
+import java.io.File;
/**
* Storage class for user preferences and environment settings.
- *
+ *
* This class no longer uses the Properties class, since
* properties files are iso8859-1, which is highly likely to
* be a problem when trying to save sketch folders and locations.
- *
+ *
* The GUI portion in here is really ugly, as it uses exact layout. This was
* done in frustration one evening (and pre-Swing), but that's long since past,
* and it should all be moved to a proper swing layout like BoxLayout.
- *
+ *
* This is very poorly put together, that the preferences panel and the actual
* preferences i/o is part of the same code. But there hasn't yet been a
* compelling reason to bother with the separation aside from concern about
* being lectured by strangers who feel that it doesn't look like what they
* learned in CS class.
- *
+ *
* Would also be possible to change this to use the Java Preferences API.
* Some useful articles
* here and
@@ -85,114 +57,12 @@ import processing.app.legacy.PApplet;
*/
public class Preferences {
- static final String PREFS_FILE = PreferencesData.PREFS_FILE;
-
- class Language {
- Language(String _name, String _originalName, String _isoCode) {
- name = _name;
- originalName = _originalName;
- isoCode = _isoCode;
- }
-
- public String toString() {
- if (originalName.length() == 0)
- return name;
- return originalName + " (" + name + ")";
- };
-
- String name;
- String originalName;
- String isoCode;
- }
-
- Language languages[] = {
- new Language(_("System Default"), "", ""),
- new Language(_("Albanian"), "shqip", "sq"),
- new Language(_("Arabic"), "العربية", "ar"),
- new Language(_("Aragonese"), "Aragonés", "an"),
- new Language(_("Belarusian"), "БеларуÑÐºÐ°Ñ Ð¼Ð¾Ð²Ð°", "be"),
- new Language(_("Bulgarian"), "българÑки", "bg"),
- new Language(_("Catalan"), "Català ", "ca"),
- new Language(_("Chinese Simplified"), "ç®€ä½“ä¸æ–‡", "zh_CN"),
- new Language(_("Chinese Traditional"), "ç¹é«”䏿–‡", "zh_TW"),
- new Language(_("Croatian"), "Hrvatski", "hr_HR"),
- new Language(_("Czech (Czech Republic)"), "Äeský (Czech Republic)", "cs_CZ"),
- new Language(_("Danish (Denmark)"), "Dansk (Denmark)", "da_DK"),
- new Language(_("Dutch"), "Nederlands", "nl"),
- new Language(_("English"), "English", "en"),
- new Language(_("English (United Kingdom)"), "English (United Kingdom)", "en_GB"),
- new Language(_("Estonian"), "Eesti", "et"),
- new Language(_("Estonian (Estonia)"), "Eesti keel", "et_EE"),
- new Language(_("Filipino"), "Pilipino", "fil"),
- new Language(_("Finnish"), "Suomi", "fi"),
- new Language(_("French"), "Français", "fr"),
- new Language(_("Canadian French"), "Canadienne-français", "fr_CA"),
- new Language(_("Galician"), "Galego", "gl"),
- new Language(_("Georgian"), "სáƒáƒ¥áƒáƒ თველáƒáƒ¡", "ka_GE"),
- new Language(_("German"), "Deutsch", "de_DE"),
- new Language(_("Greek"), "ελληνικά", "el_GR"),
- new Language(_("Hebrew"), "עברית", "he"),
- new Language(_("Hindi"), "हिंदी", "hi"),
- new Language(_("Hungarian"), "Magyar", "hu"),
- new Language(_("Indonesian"), "Bahasa Indonesia", "id"),
- new Language(_("Italian"), "Italiano", "it_IT"),
- new Language(_("Japanese"), "日本語", "ja_JP"),
- new Language(_("Korean"), "한êµì–´", "ko_KR"),
- new Language(_("Latvian"), "Latviešu", "lv_LV"),
- new Language(_("Lithuaninan"), "Lietuvių Kalba", "lt_LT"),
- new Language(_("Norwegian Bokmål"), "Norsk bokmål", "nb_NO"),
- new Language(_("Persian"), "ÙØ§Ø±Ø³ÛŒ", "fa"),
- new Language(_("Polish"), "Język Polski", "pl"),
- new Language(_("Portuguese (Brazil)"), "Português (Brazil)", "pt_BR"),
- new Language(_("Portuguese (Portugal)"), "Português (Portugal)", "pt_PT"),
- new Language(_("Romanian"), "Română", "ro"),
- new Language(_("Russian"), "РуÑÑкий", "ru"),
- new Language(_("Slovenian"), "SlovenÅ¡Äina", "sl_SI"),
- new Language(_("Spanish"), "Español", "es"),
- new Language(_("Swedish"), "Svenska", "sv"),
- new Language(_("Tamil"), "தமிழà¯", "ta"),
- new Language(_("Turkish"), "Türk", "tr"),
- new Language(_("Ukrainian"), "УкраїнÑький", "uk"),
- new Language(_("Vietnamese"), "Tiếng Việt", "vi"),
- };
-
- // Incomplete languages
- Language missingLanguages[] = {
- new Language(_("Afrikaans"), "Afrikaans", "af"),
- new Language(_("Armenian"), "Õ€Õ¡ÕµÕ¥Ö€Õ¥Õ¶", "hy"),
- new Language(_("Asturian"), "Asturianu", "ast"),
- new Language(_("Basque"), "Euskara", "eu"),
- new Language(_("Bengali (India)"), "বাংলা (India)", "bn_IN"),
- new Language(_("Bosnian"), "Bosanski", "bs"),
- new Language(_("Burmese (Myanmar)"), "ဗမာစကား", "my_MM"),
- new Language(_("Chinese (China)"), "", "zh_CN"),
- new Language(_("Chinese (Hong Kong)"), "", "zh_HK"),
- new Language(_("Chinese (Taiwan)"), "", "zh_TW"),
- new Language(_("Chinese (Taiwan) (Big5)"), "", "zh_TW.Big5"),
- new Language(_("Czech"), "Äeský", "cs"),
- new Language(_("Danish"), "Dansk", "da"),
- new Language(_("Dutch (Netherlands)"), "Nederlands", "nl_NL"),
- new Language(_("Galician (Spain)"), "Galego (Spain)", "gl_ES"),
- new Language(_("Nepali"), "नेपाली", "ne"),
- new Language(_("N'Ko"), "ß’ßžß", "nqo"),
- new Language(_("Marathi"), "मराठी", "mr"),
- new Language(_("Malay (Malaysia)"), "بهاس ملايو (Malaysia)", "ms_MY"),
- new Language(_("Norwegian"), "Norsk", "no"),
- new Language(_("Norwegian Nynorsk"), "Norsk Nynorsk", "nn"),
- new Language(_("Portugese"), "Português", "pt"),
- new Language(_("Persian (Iran)"), "ÙØ§Ø±Ø³ÛŒ (Iran)", "fa_IR"),
- new Language(_("Slovak"), "SlovenÄina", "sk"),
- new Language(_("Swahili"), "ÙƒÙØ³ÙˆÙŽÙ‡ÙÙ„", "sw"),
- new Language(_("Talossan"), "Talossan", "tzl"),
- new Language(_("Urdu (Pakistan)"), "اردو (Pakistan)", "ur_PK"),
- new Language(_("Western Frisian"), "Western Frisian", "fy"),
- };
/**
* 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.
*/
- static public int BUTTON_WIDTH = 80;
+ static public int BUTTON_WIDTH = 80;
/**
* Standardized button height. Mac OS X 10.3 (Java 1.4) wants 29,
@@ -205,549 +75,85 @@ public class Preferences {
// value for the size bars, buttons, etc
- static final int GRID_SIZE = 33;
+ static final int GRID_SIZE = 33;
// indents and spacing standards. these probably need to be modified
// per platform as well, since macosx is so huge, windows is smaller,
// and linux is all over the map
- static final int GUI_BIG = 13;
- static final int GUI_BETWEEN = 10;
- static final int GUI_SMALL = 6;
-
- // gui elements
-
- JFrame dialog;
- int wide, high;
-
- JTextField sketchbookLocationField;
- JCheckBox exportSeparateBox;
- JCheckBox verboseCompilationBox;
- JCheckBox verboseUploadBox;
- JCheckBox displayLineNumbersBox;
- JCheckBox verifyUploadBox;
- JCheckBox externalEditorBox;
- JCheckBox memoryOverrideBox;
- JTextField memoryField;
- JCheckBox checkUpdatesBox;
- JTextField fontSizeField;
- JCheckBox updateExtensionBox;
- JCheckBox autoAssociateBox;
- JComboBox comboLanguage;
- JCheckBox saveVerifyUploadBox;
-
-
- // the calling editor, so updates can be applied
-
- Editor editor;
-
+ static final int GUI_SMALL = 6;
static protected void init(File file) {
-
- PreferencesData.init(file);
+ PreferencesData.init(file);
// other things that have to be set explicitly for the defaults
PreferencesHelper.putColor(PreferencesData.prefs, "run.window.bgcolor", SystemColor.control);
}
-
- public Preferences() {
-
- // setup dialog for the prefs
-
- //dialog = new JDialog(editor, "Preferences", true);
- dialog = new JFrame(_("Preferences"));
- dialog.setResizable(false);
-
- Container pain = dialog.getContentPane();
- pain.setLayout(null);
-
- int top = GUI_BIG;
- int left = GUI_BIG;
- int right = 0;
-
- JLabel label;
- JButton button; //, button2;
- //JComboBox combo;
- Dimension d, d2; //, d3;
- int h, vmax;
-
-
- // Sketchbook location:
- // [...............................] [ Browse ]
-
- label = new JLabel(_("Sketchbook location:"));
- pain.add(label);
- d = label.getPreferredSize();
- label.setBounds(left, top, d.width, d.height);
- top += d.height; // + GUI_SMALL;
-
- sketchbookLocationField = new JTextField(40);
- pain.add(sketchbookLocationField);
- d = sketchbookLocationField.getPreferredSize();
-
- button = new JButton(I18n.PROMPT_BROWSE);
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- File dflt = new File(sketchbookLocationField.getText());
- File file =
- Base.selectFolder(_("Select new sketchbook location"), dflt, dialog);
- if (file != null) {
- String path = file.getAbsolutePath();
- if (Base.getPortableFolder() != null) {
- path = FileUtils.relativePath(Base.getPortableFolder().toString(), path);
- if (path == null) {
- path = Base.getPortableSketchbookFolder();
- }
- }
- sketchbookLocationField.setText(path);
- }
- }
- });
- pain.add(button);
- d2 = button.getPreferredSize();
-
- // take max height of all components to vertically align em
- vmax = Math.max(d.height, d2.height);
- sketchbookLocationField.setBounds(left, top + (vmax-d.height)/2,
- d.width, d.height);
- h = left + d.width + GUI_SMALL;
- button.setBounds(h, top + (vmax-d2.height)/2,
- d2.width, d2.height);
-
- right = Math.max(right, h + d2.width + GUI_BIG);
- 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);
- String currentLanguage = PreferencesData.get("editor.languages.current");
- for (Language language : languages) {
- if (language.isoCode.equals(currentLanguage))
- comboLanguage.setSelectedItem(language);
- }
- 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 [ ]
-
- box = Box.createHorizontalBox();
- label = new JLabel(_("Editor font size: "));
- box.add(label);
- fontSizeField = new JTextField(4);
- box.add(fontSizeField);
- label = new JLabel(_(" (requires restart of Arduino)"));
- box.add(label);
- pain.add(box);
- d = box.getPreferredSize();
- box.setBounds(left, top, d.width, d.height);
- Font editorFont = Preferences.getFont("editor.font");
- fontSizeField.setText(String.valueOf(editorFont.getSize()));
- top += d.height + GUI_BETWEEN;
-
-
- // Show verbose output during: [ ] compilation [ ] upload
-
- box = Box.createHorizontalBox();
- label = new JLabel(_("Show verbose output during: "));
- box.add(label);
- verboseCompilationBox = new JCheckBox(_("compilation "));
- box.add(verboseCompilationBox);
- verboseUploadBox = new JCheckBox(_("upload"));
- box.add(verboseUploadBox);
- pain.add(box);
- d = box.getPreferredSize();
- box.setBounds(left, top, d.width, d.height);
- top += d.height + GUI_BETWEEN;
-
- // [ ] Display line numbers
-
- displayLineNumbersBox = new JCheckBox(_("Display line numbers"));
- pain.add(displayLineNumbersBox);
- d = displayLineNumbersBox.getPreferredSize();
- displayLineNumbersBox.setBounds(left, top, d.width + 10, d.height);
- right = Math.max(right, left + d.width);
- 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"));
- pain.add(externalEditorBox);
- d = externalEditorBox.getPreferredSize();
- externalEditorBox.setBounds(left, top, d.width + 10, d.height);
- right = Math.max(right, left + d.width);
- top += d.height + GUI_BETWEEN;
-
-
- // [ ] Check for updates on startup
-
- checkUpdatesBox = new JCheckBox(_("Check for updates on startup"));
- pain.add(checkUpdatesBox);
- d = checkUpdatesBox.getPreferredSize();
- checkUpdatesBox.setBounds(left, top, d.width + 10, d.height);
- right = Math.max(right, left + d.width);
- top += d.height + GUI_BETWEEN;
-
- // [ ] Update sketch files to new extension on save (.pde -> .ino)
-
- updateExtensionBox = new JCheckBox(_("Update sketch files to new extension on save (.pde -> .ino)"));
- pain.add(updateExtensionBox);
- d = updateExtensionBox.getPreferredSize();
- updateExtensionBox.setBounds(left, top, d.width + 10, d.height);
- right = Math.max(right, left + d.width);
- top += d.height + GUI_BETWEEN;
-
- // [ ] Automatically associate .pde files with Processing
-
- if (OSUtils.isWindows()) {
- autoAssociateBox =
- new JCheckBox(_("Automatically associate .ino files with Arduino"));
- pain.add(autoAssociateBox);
- d = autoAssociateBox.getPreferredSize();
- autoAssociateBox.setBounds(left, top, d.width + 10, d.height);
- right = Math.max(right, left + d.width);
- top += d.height + GUI_BETWEEN;
-
- // If using portable mode, it's bad manner to change PC setting.
- if (Base.getPortableFolder() != null)
- autoAssociateBox.setEnabled(false);
- }
-
- // [ ] save when verifying or uploading
-
- saveVerifyUploadBox = new JCheckBox(_("Save when verifying or uploading"));
- pain.add(saveVerifyUploadBox);
- d = saveVerifyUploadBox.getPreferredSize();
- saveVerifyUploadBox.setBounds(left, top, d.width + 10, d.height);
- right = Math.max(right, left + d.width);
- top += d.height + GUI_BETWEEN;
-
- // More preferences are in the ...
-
- label = new JLabel(_("More preferences can be edited directly in the file"));
- pain.add(label);
- d = label.getPreferredSize();
- label.setForeground(Color.gray);
- label.setBounds(left, top, d.width, d.height);
- right = Math.max(right, left + d.width);
- top += d.height; // + GUI_SMALL;
-
- label = new JLabel(PreferencesData.preferencesFile.getAbsolutePath());
- final JLabel clickable = label;
- label.addMouseListener(new MouseAdapter() {
- public void mousePressed(MouseEvent e) {
- Base.openFolder(PreferencesData.preferencesFile.getParentFile());
- }
-
- public void mouseEntered(MouseEvent e) {
- clickable.setForeground(new Color(0, 0, 140));
- }
-
- public void mouseExited(MouseEvent e) {
- clickable.setForeground(Color.BLACK);
- }
- });
- pain.add(label);
- d = label.getPreferredSize();
- label.setBounds(left, top, d.width, d.height);
- right = Math.max(right, left + d.width);
- top += d.height;
-
- label = new JLabel(_("(edit only when Arduino is not running)"));
- pain.add(label);
- d = label.getPreferredSize();
- label.setForeground(Color.gray);
- label.setBounds(left, top, d.width, d.height);
- right = Math.max(right, left + d.width);
- top += d.height; // + GUI_SMALL;
-
-
- // [ OK ] [ Cancel ] maybe these should be next to the message?
-
- button = new JButton(I18n.PROMPT_OK);
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- applyFrame();
- disposeFrame();
- }
- });
- pain.add(button);
- d2 = button.getPreferredSize();
- BUTTON_HEIGHT = d2.height;
-
- h = right - (BUTTON_WIDTH + GUI_SMALL + BUTTON_WIDTH);
- button.setBounds(h, top, BUTTON_WIDTH, BUTTON_HEIGHT);
- h += BUTTON_WIDTH + GUI_SMALL;
-
- button = new JButton(I18n.PROMPT_CANCEL);
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- disposeFrame();
- }
- });
- pain.add(button);
- button.setBounds(h, top, BUTTON_WIDTH, BUTTON_HEIGHT);
-
- top += BUTTON_HEIGHT + GUI_BETWEEN;
-
-
- // finish up
-
- wide = right + GUI_BIG;
- high = top + GUI_SMALL;
-
-
- // closing the window is same as hitting cancel button
-
- dialog.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- disposeFrame();
- }
- });
-
- ActionListener disposer = new ActionListener() {
- public void actionPerformed(ActionEvent actionEvent) {
- disposeFrame();
- }
- };
- Base.registerWindowCloseKeys(dialog.getRootPane(), disposer);
- Base.setIcon(dialog);
-
- Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- dialog.setLocation((screen.width - wide) / 2,
- (screen.height - high) / 2);
-
- dialog.pack(); // get insets
- Insets insets = dialog.getInsets();
- dialog.setSize(wide + insets.left + insets.right,
- high + insets.top + insets.bottom);
-
-
- // handle window closing commands for ctrl/cmd-W or hitting ESC.
-
- pain.addKeyListener(new KeyAdapter() {
- public void keyPressed(KeyEvent e) {
- //System.out.println(e);
- KeyStroke wc = Editor.WINDOW_CLOSE_KEYSTROKE;
- if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) ||
- (KeyStroke.getKeyStrokeForEvent(e).equals(wc))) {
- disposeFrame();
- }
- }
- });
- }
-
-
- // .................................................................
-
-
- /**
- * Close the window after an OK or Cancel.
- */
- protected void disposeFrame() {
- dialog.dispose();
- }
-
-
- /**
- * Change internal settings based on what was chosen in the prefs,
- * then send a message to the editor saying that it's time to do the same.
- */
- protected void applyFrame() {
- // put each of the settings into the table
- PreferencesData.setBoolean("build.verbose", verboseCompilationBox.isSelected());
- PreferencesData.setBoolean("upload.verbose", verboseUploadBox.isSelected());
- PreferencesData.setBoolean("editor.linenumbers", displayLineNumbersBox.isSelected());
- PreferencesData.setBoolean("upload.verify", verifyUploadBox.isSelected());
- PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected());
-
-// setBoolean("sketchbook.closing_last_window_quits",
-// closingLastQuitsBox.isSelected());
- //setBoolean("sketchbook.prompt", sketchPromptBox.isSelected());
- //setBoolean("sketchbook.auto_clean", sketchCleanBox.isSelected());
-
- // if the sketchbook path has changed, rebuild the menus
- String oldPath = PreferencesData.get("sketchbook.path");
- String newPath = sketchbookLocationField.getText();
- if (newPath.isEmpty()) {
- if (Base.getPortableFolder() == null)
- newPath = editor.base.getDefaultSketchbookFolderOrPromptForIt().toString();
- else
- newPath = Base.getPortableSketchbookFolder();
- }
- if (!newPath.equals(oldPath)) {
- editor.base.rebuildSketchbookMenus();
- PreferencesData.set("sketchbook.path", newPath);
- }
-
- PreferencesData.setBoolean("editor.external", externalEditorBox.isSelected());
- PreferencesData.setBoolean("update.check", checkUpdatesBox.isSelected());
- PreferencesData.setBoolean("editor.save_on_verify", saveVerifyUploadBox.isSelected());
-
- /*
- // was gonna use this to check memory settings,
- // but it quickly gets much too messy
- if (getBoolean("run.options.memory")) {
- Process process = Runtime.getRuntime().exec(new String[] {
- "java", "-Xms" + memoryMin + "m", "-Xmx" + memoryMax + "m"
- });
- processInput = new SystemOutSiphon(process.getInputStream());
- processError = new MessageSiphon(process.getErrorStream(), this);
- }
- */
-
- String newSizeText = fontSizeField.getText();
- try {
- int newSize = Integer.parseInt(newSizeText.trim());
- String pieces[] = PApplet.split(PreferencesData.get("editor.font"), ',');
- pieces[2] = String.valueOf(newSize);
- PreferencesData.set("editor.font", PApplet.join(pieces, ','));
-
- } catch (Exception e) {
- System.err.println(I18n.format(_("ignoring invalid font size {0}"), newSizeText));
- }
-
- if (autoAssociateBox != null) {
- PreferencesData.setBoolean("platform.auto_file_type_associations",
- autoAssociateBox.isSelected());
- }
-
- PreferencesData.setBoolean("editor.update_extension", updateExtensionBox.isSelected());
-
- // adds the selected language to the preferences file
- Language newLanguage = (Language) comboLanguage.getSelectedItem();
- PreferencesData.set("editor.languages.current", newLanguage.isoCode);
-
- editor.applyPreferences();
- }
-
-
- protected void showFrame(Editor editor) {
- this.editor = editor;
-
- // set all settings entry boxes to their actual status
- verboseCompilationBox.setSelected(PreferencesData.getBoolean("build.verbose"));
- verboseUploadBox.setSelected(PreferencesData.getBoolean("upload.verbose"));
- displayLineNumbersBox.setSelected(PreferencesData.getBoolean("editor.linenumbers"));
- verifyUploadBox.setSelected(PreferencesData.getBoolean("upload.verify"));
-
- //closingLastQuitsBox.
- // setSelected(getBoolean("sketchbook.closing_last_window_quits"));
- //sketchPromptBox.
- // setSelected(getBoolean("sketchbook.prompt"));
- //sketchCleanBox.
- // setSelected(getBoolean("sketchbook.auto_clean"));
-
- sketchbookLocationField.
- setText(PreferencesData.get("sketchbook.path"));
- externalEditorBox.
- setSelected(PreferencesData.getBoolean("editor.external"));
- checkUpdatesBox.
- setSelected(PreferencesData.getBoolean("update.check"));
- saveVerifyUploadBox.
- setSelected(PreferencesData.getBoolean("editor.save_on_verify"));
-
- if (autoAssociateBox != null) {
- autoAssociateBox.
- setSelected(PreferencesData.getBoolean("platform.auto_file_type_associations"));
- }
-
- updateExtensionBox.setSelected(PreferencesData.get("editor.update_extension") == null ||
- PreferencesData.getBoolean("editor.update_extension"));
-
- dialog.setVisible(true);
- }
-
-
- static protected void save() {
+ @Deprecated
+ protected static void save() {
PreferencesData.save();
}
-
- // .................................................................
-
- static public String get(String attribute) {
+ @Deprecated
+ public static String get(String attribute) {
return PreferencesData.get(attribute);
}
- static public String get(String attribute, String defaultValue) {
+ @Deprecated
+ public static String get(String attribute, String defaultValue) {
return PreferencesData.get(attribute, defaultValue);
}
+ @Deprecated
public static boolean has(String key) {
return PreferencesData.has(key);
}
+ @Deprecated
public static void remove(String key) {
PreferencesData.remove(key);
}
-
- static public void set(String attribute, String value) {
+ @Deprecated
+ public static void set(String attribute, String value) {
PreferencesData.set(attribute, value);
}
-
- static public boolean getBoolean(String attribute) {
+ @Deprecated
+ public static boolean getBoolean(String attribute) {
return PreferencesData.getBoolean(attribute);
}
-
- static public void setBoolean(String attribute, boolean value) {
+ @Deprecated
+ public static void setBoolean(String attribute, boolean value) {
PreferencesData.setBoolean(attribute, value);
}
-
- static public int getInteger(String attribute) {
+ @Deprecated
+ public static int getInteger(String attribute) {
return PreferencesData.getInteger(attribute);
}
+ @Deprecated
+ public static int getInteger(String attribute, int defaultValue) {
+ return PreferencesData.getInteger(attribute, defaultValue);
+ }
- static public void setInteger(String key, int value) {
+ @Deprecated
+ public static void setInteger(String key, int value) {
PreferencesData.setInteger(key, value);
}
-
- static public Font getFont(String attr) {
- Font font = PreferencesHelper.getFont(PreferencesData.prefs, attr);
- if (font == null) {
- String value = PreferencesData.defaults.get(attr);
- PreferencesData.prefs.put(attr, value);
- font = PreferencesHelper.getFont(PreferencesData.prefs, attr);
- }
- return font;
- }
-
- // get a copy of the Preferences
- static public PreferencesMap getMap()
- {
+ @Deprecated
+ public static PreferencesMap getMap() {
return PreferencesData.getMap();
}
- // Decide wether changed preferences will be saved. When value is
- // false, Preferences.save becomes a no-op.
- static public void setDoSave(boolean value)
- {
+ @Deprecated
+ public static void setDoSave(boolean value) {
PreferencesData.setDoSave(value);
}
+
}
diff --git a/app/src/processing/app/PresentMode.java b/app/src/processing/app/PresentMode.java
index 34cba7928..f9bc568de 100644
--- a/app/src/processing/app/PresentMode.java
+++ b/app/src/processing/app/PresentMode.java
@@ -74,14 +74,14 @@ public class PresentMode {
public void actionPerformed(ActionEvent e) {
int index = selector.getSelectedIndex();
//device = devices[index];
- Preferences.setInteger("run.present.display", index + 1);
+ PreferencesData.setInteger("run.present.display", index + 1);
}
});
}
static public JComboBox getSelector() {
- int deviceIndex = Preferences.getInteger("run.present.display") - 1;
+ int deviceIndex = PreferencesData.getInteger("run.present.display") - 1;
selector.setSelectedIndex(deviceIndex);
return selector;
}
diff --git a/app/src/processing/app/SerialMonitor.java b/app/src/processing/app/SerialMonitor.java
index 122e3323d..9f48f82cb 100644
--- a/app/src/processing/app/SerialMonitor.java
+++ b/app/src/processing/app/SerialMonitor.java
@@ -39,14 +39,14 @@ public class SerialMonitor extends AbstractMonitor {
this.port = port.getAddress();
- serialRate = Preferences.getInteger("serial.debug_rate");
+ serialRate = PreferencesData.getInteger("serial.debug_rate");
serialRates.setSelectedItem(serialRate + " " + _("baud"));
onSerialRateChange(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String wholeString = (String) serialRates.getSelectedItem();
String rateString = wholeString.substring(0, wholeString.indexOf(' '));
serialRate = Integer.parseInt(rateString);
- Preferences.set("serial.debug_rate", rateString);
+ PreferencesData.set("serial.debug_rate", rateString);
try {
close();
Thread.sleep(100); // Wait for serial port to properly close
@@ -80,9 +80,9 @@ public class SerialMonitor extends AbstractMonitor {
s += "\r\n";
break;
}
- if ("".equals(s) && lineEndings.getSelectedIndex() == 0 && !Preferences.has("runtime.line.ending.alert.notified")) {
+ if ("".equals(s) && lineEndings.getSelectedIndex() == 0 && !PreferencesData.has("runtime.line.ending.alert.notified")) {
noLineEndingAlert.setForeground(Color.RED);
- Preferences.set("runtime.line.ending.alert.notified", "true");
+ PreferencesData.set("runtime.line.ending.alert.notified", "true");
}
serial.write(s);
}
@@ -103,7 +103,7 @@ public class SerialMonitor extends AbstractMonitor {
if (serial != null) {
int[] location = getPlacement();
String locationStr = PApplet.join(PApplet.str(location), ",");
- Preferences.set("last.serial.location", locationStr);
+ PreferencesData.set("last.serial.location", locationStr);
textArea.setText("");
serial.dispose();
serial = null;
diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java
index 2f142d01b..74ca35733 100644
--- a/app/src/processing/app/Sketch.java
+++ b/app/src/processing/app/Sketch.java
@@ -23,18 +23,15 @@
package processing.app;
-import cc.arduino.packages.BoardPort;
import cc.arduino.packages.Uploader;
-import cc.arduino.view.*;
import processing.app.debug.Compiler;
import processing.app.debug.Compiler.ProgressListener;
import processing.app.debug.RunnerException;
-import processing.app.debug.TargetBoard;
import processing.app.forms.PasswordAuthorizationDialog;
import processing.app.helpers.OSUtils;
-import processing.app.helpers.PreferencesMap;
import processing.app.helpers.PreferencesMapException;
-import processing.app.packages.Library;
+import processing.app.packages.UserLibrary;
+import static processing.app.I18n._;
import javax.swing.*;
import java.awt.*;
@@ -45,8 +42,6 @@ import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
-import static processing.app.I18n._;
-
/**
* Stores information about files in the current sketch
@@ -117,7 +112,7 @@ public class Sketch {
for (SketchCode code : data.getCodes()) {
if (code.getMetadata() == null)
- code.setMetadata(new SketchCodeDocument(code));
+ code.setMetadata(new SketchCodeDocument(this, code));
}
// set the main file to be the current tab
@@ -414,7 +409,7 @@ public class Sketch {
return;
}
ensureExistence();
- data.addCode((new SketchCodeDocument(newFile)).getCode());
+ data.addCode((new SketchCodeDocument(this, newFile)).getCode());
}
// sort the entries
@@ -580,7 +575,7 @@ public class Sketch {
});
if (pdeFiles != null && pdeFiles.length > 0) {
- if (Preferences.get("editor.update_extension") == null) {
+ if (PreferencesData.get("editor.update_extension") == null) {
Object[] options = { _("OK"), _("Cancel") };
int result = JOptionPane.showOptionDialog(editor,
_("In Arduino 1.0, the default file extension has changed\n" +
@@ -599,10 +594,10 @@ public class Sketch {
if (result != JOptionPane.OK_OPTION) return false; // save cancelled
- Preferences.setBoolean("editor.update_extension", true);
+ PreferencesData.setBoolean("editor.update_extension", true);
}
- if (Preferences.getBoolean("editor.update_extension")) {
+ if (PreferencesData.getBoolean("editor.update_extension")) {
// Do rename of all .pde files to new .ino extension
for (File pdeFile : pdeFiles)
renameCodeToInoExtension(pdeFile);
@@ -806,7 +801,7 @@ public class Sketch {
if (result) {
editor.statusNotice(_("One file added to the sketch."));
- Preferences.set("last.folder", sourceFile.getAbsolutePath());
+ PreferencesData.set("last.folder", sourceFile.getAbsolutePath());
}
}
@@ -910,7 +905,7 @@ public class Sketch {
}
if (codeExtension != null) {
- SketchCode newCode = (new SketchCodeDocument(destFile)).getCode();
+ SketchCode newCode = (new SketchCodeDocument(this, destFile)).getCode();
if (replacement) {
data.replaceCode(newCode);
@@ -938,7 +933,7 @@ public class Sketch {
}
- public void importLibrary(Library lib) throws IOException {
+ public void importLibrary(UserLibrary lib) throws IOException {
importLibrary(lib.getSrcFolder());
}
@@ -1064,7 +1059,7 @@ public class Sketch {
// if an external editor is being used, need to grab the
// latest version of the code from the file.
- if (Preferences.getBoolean("editor.external")) {
+ if (PreferencesData.getBoolean("editor.external")) {
// history gets screwed by the open..
//String historySaved = history.lastRecorded;
//handleOpen(sketch);
@@ -1138,8 +1133,8 @@ public class Sketch {
* @return null if compilation failed, main class name if not
* @throws RunnerException
*/
- public String build(boolean verbose) throws RunnerException, PreferencesMapException {
- return build(tempBuildFolder.getAbsolutePath(), verbose);
+ public String build(boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
+ return build(tempBuildFolder.getAbsolutePath(), verbose, save);
}
/**
@@ -1151,9 +1146,7 @@ public class Sketch {
*
* @return null if compilation failed, main class name if not
*/
- public String build(String buildPath, boolean verbose) throws RunnerException, PreferencesMapException {
- useOriginalVidPidIfUncertified();
-
+ public String build(String buildPath, boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
// run the preprocessor
editor.status.progressUpdate(20);
@@ -1166,7 +1159,7 @@ public class Sketch {
}
};
- return Compiler.build(data, buildPath, tempBuildFolder, pl, verbose);
+ return Compiler.build(data, buildPath, tempBuildFolder, pl, verbose, save);
}
protected boolean exportApplet(boolean usingProgrammer) throws Exception {
@@ -1184,7 +1177,7 @@ public class Sketch {
// build the sketch
editor.status.progressNotice(_("Compiling sketch..."));
- String foundName = build(appletPath, false);
+ String foundName = build(appletPath, false, false);
// (already reported) error during export, exit this function
if (foundName == null) return false;
@@ -1203,45 +1196,13 @@ public class Sketch {
return success;
}
- private void useOriginalVidPidIfUncertified() {
- BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port"));
- if (boardPort == null) {
- return;
- }
- TargetBoard targetBoard = BaseNoGui.getTargetBoard();
- if (targetBoard == null) {
- return;
- }
- PreferencesMap boardPreferences = targetBoard.getPreferences();
- if (boardPreferences.containsKey("build.vid") && boardPreferences.containsKey("build.pid")) {
- if (!boardPreferences.containsKey("backup.build.vid")) {
- boardPreferences.put("backup.build.vid", boardPreferences.get("build.vid"));
- boardPreferences.put("backup.build.pid", boardPreferences.get("build.pid"));
- }
-
- if (boardPort.getPrefs().get("warning") != null) {
- boardPreferences.put("build.vid", boardPort.getPrefs().get("vid"));
- boardPreferences.put("build.pid", boardPort.getPrefs().get("pid"));
- } else {
- boardPreferences.put("build.vid", boardPreferences.get("backup.build.vid"));
- boardPreferences.put("build.pid", boardPreferences.get("backup.build.pid"));
- }
- }
-
- if (boardPort.getPrefs().get("warning") != null && !Preferences.getBoolean("uncertifiedBoardWarning_dontShowMeAgain")) {
- SwingUtilities.invokeLater(new ShowUncertifiedBoardWarning(editor));
- }
-
-
- }
-
protected boolean upload(String buildPath, String suggestedClassName, boolean usingProgrammer) throws Exception {
Uploader uploader = Compiler.getUploaderByPreferences(false);
boolean success = false;
do {
- if (uploader.requiresAuthorization() && !Preferences.has(uploader.getAuthorizationKey())) {
+ if (uploader.requiresAuthorization() && !PreferencesData.has(uploader.getAuthorizationKey())) {
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(editor, _("Type board password to upload a new sketch"));
dialog.setLocationRelativeTo(editor);
dialog.setVisible(true);
@@ -1251,7 +1212,7 @@ public class Sketch {
return false;
}
- Preferences.set(uploader.getAuthorizationKey(), dialog.getPassword());
+ PreferencesData.set(uploader.getAuthorizationKey(), dialog.getPassword());
}
List warningsAccumulator = new LinkedList();
@@ -1259,7 +1220,7 @@ public class Sketch {
success = Compiler.upload(data, uploader, buildPath, suggestedClassName, usingProgrammer, false, warningsAccumulator);
} finally {
if (uploader.requiresAuthorization() && !success) {
- Preferences.remove(uploader.getAuthorizationKey());
+ PreferencesData.remove(uploader.getAuthorizationKey());
}
}
diff --git a/app/src/processing/app/SketchCodeDocument.java b/app/src/processing/app/SketchCodeDocument.java
index 857a270ab..681f0af91 100644
--- a/app/src/processing/app/SketchCodeDocument.java
+++ b/app/src/processing/app/SketchCodeDocument.java
@@ -2,37 +2,43 @@ package processing.app;
import java.io.File;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
+import javax.swing.undo.UndoManager;
-public class SketchCodeDocument{
+public class SketchCodeDocument implements DocumentListener{
private SketchCode code;
+ private Sketch sketch;
private Document document;
// Undo Manager for this tab, each tab keeps track of their own Editor.undo
// will be set to this object when this code is the tab that's currently the
// front.
- private LastUndoableEditAwareUndoManager undo = new LastUndoableEditAwareUndoManager();
+ private UndoManager undo;
// saved positions from last time this tab was used
private int selectionStart;
private int selectionStop;
private int scrollPosition;
- public SketchCodeDocument(SketchCode code) {
+ public SketchCodeDocument(Sketch sketch, SketchCode code) {
this.code = code;
+ this.sketch = sketch;
this.code.setMetadata(this);
}
- public SketchCodeDocument(File file) {
+ public SketchCodeDocument(Sketch sketch, File file) {
this.code = new SketchCode(file, this);
+ this.sketch = sketch;
}
- public LastUndoableEditAwareUndoManager getUndo() {
+ public UndoManager getUndo() {
return undo;
}
- public void setUndo(LastUndoableEditAwareUndoManager undo) {
+ public void setUndo(UndoManager undo) {
this.undo = undo;
}
@@ -74,6 +80,24 @@ public class SketchCodeDocument{
public void setDocument(Document document) {
this.document = document;
+ document.addDocumentListener(this);
}
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ if(!code.isModified()) sketch.setModified(true);
+ }
+
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ if(!code.isModified()) sketch.setModified(true);
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ // Callback for when styles in the current document change.
+ // This method is never called.
+ }
+
}
diff --git a/app/src/processing/app/Theme.java b/app/src/processing/app/Theme.java
index 7f23d3c46..841880d9b 100644
--- a/app/src/processing/app/Theme.java
+++ b/app/src/processing/app/Theme.java
@@ -21,15 +21,19 @@
package processing.app;
-import static processing.app.I18n._;
-
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.SystemColor;
-
+import processing.app.helpers.OSUtils;
import processing.app.helpers.PreferencesHelper;
import processing.app.helpers.PreferencesMap;
-import processing.app.syntax.SyntaxStyle;
+
+import javax.swing.text.StyleContext;
+import java.awt.*;
+import java.awt.font.TextAttribute;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import static processing.app.I18n._;
/**
* Storage class for theme settings. This was separated from the Preferences
@@ -38,17 +42,21 @@ import processing.app.syntax.SyntaxStyle;
*/
public class Theme {
- /** Copy of the defaults in case the user mangles a preference. */
+ /**
+ * Copy of the defaults in case the user mangles a preference.
+ */
static PreferencesMap defaults;
- /** Table of attributes/values for the theme. */
+ /**
+ * Table of attributes/values for the theme.
+ */
static PreferencesMap table = new PreferencesMap();
static protected void init() {
try {
- table.load(Base.getLibStream("theme/theme.txt"));
+ table.load(new File(BaseNoGui.getContentFile("lib"), "theme/theme.txt"));
} catch (Exception te) {
Base.showError(null, _("Could not read color theme settings.\n" +
- "You'll need to reinstall Arduino."), te);
+ "You'll need to reinstall Arduino."), te);
}
// other things that have to be set explicitly for the defaults
@@ -104,7 +112,41 @@ public class Theme {
return font;
}
- static public SyntaxStyle getStyle(String what) {
+ /**
+ * Returns the default font for text areas.
+ *
+ * @return The default font.
+ */
+ public static final Font getDefaultFont() {
+
+ // Use StyleContext to get a composite font for better Asian language
+ // support; see Sun bug S282887.
+ StyleContext sc = StyleContext.getDefaultStyleContext();
+ Font font = null;
+
+ if (OSUtils.isMacOS()) {
+ // Snow Leopard (1.6) uses Menlo as default monospaced font,
+ // pre-Snow Leopard used Monaco.
+ font = sc.getFont("Menlo", Font.PLAIN, 12);
+ if (!"Menlo".equals(font.getFamily())) {
+ font = sc.getFont("Monaco", Font.PLAIN, 12);
+ if (!"Monaco".equals(font.getFamily())) { // Shouldn't happen
+ font = sc.getFont("Monospaced", Font.PLAIN, 13);
+ }
+ }
+ } else {
+ // Consolas added in Vista, used by VS2010+.
+ font = sc.getFont("Consolas", Font.PLAIN, 13);
+ if (!"Consolas".equals(font.getFamily())) {
+ font = sc.getFont("Monospaced", Font.PLAIN, 13);
+ }
+ }
+
+ //System.out.println(font.getFamily() + ", " + font.getName());
+ return font;
+ }
+
+ public static Map getStyledFont(String what, Font font) {
String split[] = get("editor." + what + ".style").split(",");
Color color = PreferencesHelper.parseColor(split[0]);
@@ -114,6 +156,18 @@ public class Theme {
boolean italic = style.contains("italic");
boolean underlined = style.contains("underlined");
- return new SyntaxStyle(color, italic, bold, underlined);
+ Font styledFont = new Font(font.getFamily(), (bold ? Font.BOLD : 0) | (italic ? Font.ITALIC : 0), font.getSize());
+ if (underlined) {
+ Map attr = new Hashtable();
+ attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
+ styledFont = styledFont.deriveFont(attr);
+ }
+
+ Map result = new HashMap();
+ result.put("color", color);
+ result.put("font", styledFont);
+
+ return result;
}
+
}
diff --git a/app/src/processing/app/UpdateCheck.java b/app/src/processing/app/UpdateCheck.java
index 5e063bc6c..b3b48dfef 100644
--- a/app/src/processing/app/UpdateCheck.java
+++ b/app/src/processing/app/UpdateCheck.java
@@ -22,16 +22,16 @@
package processing.app;
+import processing.app.legacy.PApplet;
+
+import javax.swing.*;
import java.io.BufferedReader;
-import java.io.InputStream;
+import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Random;
-import javax.swing.JOptionPane;
-
-import processing.app.legacy.PApplet;
import static processing.app.I18n._;
@@ -69,11 +69,11 @@ public class UpdateCheck implements Runnable {
Random r = new Random();
long id = r.nextLong();
- String idString = Preferences.get("update.id");
+ String idString = PreferencesData.get("update.id");
if (idString != null) {
id = Long.parseLong(idString);
} else {
- Preferences.set("update.id", String.valueOf(id));
+ PreferencesData.set("update.id", String.valueOf(id));
}
try {
@@ -88,7 +88,7 @@ public class UpdateCheck implements Runnable {
int latest = readInt(downloadURL + "?" + info);
- String lastString = Preferences.get("update.last");
+ String lastString = PreferencesData.get("update.last");
long now = System.currentTimeMillis();
if (lastString != null) {
long when = Long.parseLong(lastString);
@@ -97,7 +97,7 @@ public class UpdateCheck implements Runnable {
return;
}
}
- Preferences.set("update.last", String.valueOf(now));
+ PreferencesData.set("update.last", String.valueOf(now));
String prompt =
_("A new version of Arduino is available,\n" +
@@ -126,11 +126,16 @@ public class UpdateCheck implements Runnable {
}
- protected int readInt(String filename) throws Exception {
+ protected int readInt(String filename) throws IOException {
URL url = new URL(filename);
- InputStream stream = url.openStream();
- InputStreamReader isr = new InputStreamReader(stream);
- BufferedReader reader = new BufferedReader(isr);
- return Integer.parseInt(reader.readLine());
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(url.openStream()));
+ return Integer.parseInt(reader.readLine());
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
}
}
diff --git a/app/src/processing/app/debug/TargetPackageStub.java b/app/src/processing/app/debug/TargetPackageStub.java
new file mode 100644
index 000000000..d564a9e4e
--- /dev/null
+++ b/app/src/processing/app/debug/TargetPackageStub.java
@@ -0,0 +1,38 @@
+package processing.app.debug;
+
+import java.util.Collection;
+import java.util.Map;
+
+public class TargetPackageStub implements TargetPackage {
+
+ private final String id;
+
+ public TargetPackageStub(String id) {
+ this.id = id;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public Map getPlatforms() {
+ return null;
+ }
+
+ @Override
+ public Collection platforms() {
+ return null;
+ }
+
+ @Override
+ public TargetPlatform get(String platform) {
+ return null;
+ }
+
+ @Override
+ public boolean hasPlatform(TargetPlatform platform) {
+ return false;
+ }
+}
diff --git a/app/src/processing/app/helpers/ConsoleLogger.java b/app/src/processing/app/helpers/ConsoleLogger.java
new file mode 100644
index 000000000..5aacc5af5
--- /dev/null
+++ b/app/src/processing/app/helpers/ConsoleLogger.java
@@ -0,0 +1,60 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.helpers;
+
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.logging.LogRecord;
+import java.util.logging.StreamHandler;
+
+public class ConsoleLogger extends StreamHandler {
+
+ public ConsoleLogger() {
+ setOutputStream(new PrintStream(new FileOutputStream(FileDescriptor.out)));
+ }
+
+
+ public void publish(LogRecord record) {
+ super.publish(record);
+ flush();
+ }
+
+ /**
+ * Override StreamHandler.close to do a flush but not
+ * to close the output stream. That is, we do not
+ * close FileDescriptor.out.
+ */
+ public void close() {
+ flush();
+ }
+
+}
diff --git a/app/src/processing/app/helpers/LogFormatter.java b/app/src/processing/app/helpers/LogFormatter.java
new file mode 100644
index 000000000..92a0859a7
--- /dev/null
+++ b/app/src/processing/app/helpers/LogFormatter.java
@@ -0,0 +1,79 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.helpers;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Date;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+public class LogFormatter extends Formatter {
+
+ public String format;
+ private final Date dat = new Date();
+
+ public LogFormatter(String logformat) {
+ format = logformat;
+ }
+
+ @Override
+ public String format(LogRecord record) {
+ dat.setTime(record.getMillis());
+ String source;
+ if (record.getSourceClassName() != null) {
+ source = record.getSourceClassName().substring(record.getSourceClassName().lastIndexOf('.') + 1);
+ if (record.getSourceMethodName() != null) {
+ source += "." + record.getSourceMethodName();
+ }
+ } else {
+ source = record.getLoggerName();
+ }
+ String message = formatMessage(record);
+ String throwable = "";
+ if (record.getThrown() != null) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ pw.println();
+ record.getThrown().printStackTrace(pw);
+ pw.close();
+ throwable = sw.toString();
+ }
+ return String.format(format,
+ dat,
+ source,
+ record.getLoggerName(),
+ record.getLevel(),
+ message,
+ throwable);
+ }
+
+}
diff --git a/app/src/processing/app/macosx/ThinkDifferent.java b/app/src/processing/app/macosx/ThinkDifferent.java
index e14770a9b..1f243a8d4 100644
--- a/app/src/processing/app/macosx/ThinkDifferent.java
+++ b/app/src/processing/app/macosx/ThinkDifferent.java
@@ -22,113 +22,95 @@
package processing.app.macosx;
-import processing.app.Base;
-
import com.apple.eawt.*;
+import processing.app.Base;
+import processing.app.Editor;
import java.io.File;
+import java.util.List;
/**
* Deal with issues related to thinking different. This handles the basic
* Mac OS X menu commands (and apple events) for open, about, prefs, etc.
- *
+ *
* Based on OSXAdapter.java from Apple DTS.
- *
- * As of 0140, this code need not be built on platforms other than OS X,
+ *
+ * As of 0140, this code need not be built on platforms other than OS X,
* because of the new platform structure which isolates through reflection.
*/
-public class ThinkDifferent implements ApplicationListener {
+public class ThinkDifferent {
- // pseudo-singleton model; no point in making multiple instances
- // of the EAWT application or our adapter
- private static ThinkDifferent adapter;
- // http://developer.apple.com/documentation/Java/Reference/1.4.2/appledoc/api/com/apple/eawt/Application.html
- private static Application application;
+ private static final int MAX_WAIT_FOR_BASE = 10000;
- // reference to the app where the existing quit, about, prefs code is
- private Base base;
+ static public void init() {
+ Application application = Application.getApplication();
+ application.setAboutHandler(new AboutHandler() {
+ @Override
+ public void handleAbout(AppEvent.AboutEvent aboutEvent) {
+ if (waitForBase()) {
+ Base.INSTANCE.handleAbout();
+ }
+ }
+ });
+ application.setPreferencesHandler(new PreferencesHandler() {
+ @Override
+ public void handlePreferences(AppEvent.PreferencesEvent preferencesEvent) {
+ if (waitForBase()) {
+ Base.INSTANCE.handlePrefs();
+ }
+ }
+ });
+ application.setOpenFileHandler(new OpenFilesHandler() {
+ @Override
+ public void openFiles(final AppEvent.OpenFilesEvent openFilesEvent) {
+ if (waitForBase()) {
+ for (File file : openFilesEvent.getFiles()) {
+ try {
+ Base.INSTANCE.handleOpen(file);
+ List editors = Base.INSTANCE.getEditors();
+ if (editors.size() == 2 && editors.get(0).getSketch().isUntitled()) {
+ Base.INSTANCE.handleClose(editors.get(0));
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ });
+ application.setQuitHandler(new QuitHandler() {
+ @Override
+ public void handleQuitRequestWith(AppEvent.QuitEvent quitEvent, QuitResponse quitResponse) {
+ if (waitForBase()) {
+ if (Base.INSTANCE.handleClose(Base.INSTANCE.getActiveEditor())) {
+ quitResponse.performQuit();
+ } else {
+ quitResponse.cancelQuit();
+ }
+ }
+ }
+ });
+ }
-
- static public void init(Base base) {
- if (application == null) {
- //application = new com.apple.eawt.Application();
- application = com.apple.eawt.Application.getApplication();
- }
- if (adapter == null) {
- adapter = new ThinkDifferent(base);
- }
- application.addApplicationListener(adapter);
- application.setEnabledAboutMenu(true);
- application.setEnabledPreferencesMenu(true);
- }
-
-
- public ThinkDifferent(Base base) {
- this.base = base;
- }
-
-
- // implemented handler methods. These are basically hooks into existing
- // functionality from the main app, as if it came over from another platform.
- public void handleAbout(ApplicationEvent ae) {
- if (base != null) {
- ae.setHandled(true);
- base.handleAbout();
- } else {
- throw new IllegalStateException("handleAbout: Base instance detached from listener");
- }
- }
-
-
- public void handlePreferences(ApplicationEvent ae) {
- if (base != null) {
- base.handlePrefs();
- ae.setHandled(true);
- } else {
- throw new IllegalStateException("handlePreferences: Base instance detached from listener");
+ private static boolean waitForBase() {
+ int slept = 0;
+ while (Base.INSTANCE == null) {
+ if (slept >= MAX_WAIT_FOR_BASE) {
+ return false;
+ }
+ sleep(100);
+ slept += 100;
}
+ return true;
}
-
- public void handleOpenApplication(ApplicationEvent ae) {
- }
-
-
- public void handleOpenFile(ApplicationEvent ae) {
-// System.out.println("got open file event " + ae.getFilename());
- String filename = ae.getFilename();
+ private static void sleep(int millis) {
try {
- base.handleOpen(new File(filename));
- } catch (Exception e) {
- e.printStackTrace();
- }
- ae.setHandled(true);
- }
-
-
- public void handlePrintFile(ApplicationEvent ae) {
- // TODO implement os x print handler here (open app, call handlePrint, quit)
- }
-
-
- public void handleQuit(ApplicationEvent ae) {
- if (base != null) {
- /*
- / You MUST setHandled(false) if you want to delay or cancel the quit.
- / This is important for cross-platform development -- have a universal quit
- / routine that chooses whether or not to quit, so the functionality is identical
- / on all platforms. This example simply cancels the AppleEvent-based quit and
- / defers to that universal method.
- */
- boolean result = base.handleQuit();
- ae.setHandled(result);
- } else {
- throw new IllegalStateException("handleQuit: Base instance detached from listener");
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ //ignore
}
}
-
-
- public void handleReOpenApplication(ApplicationEvent arg0) {
- }
+
}
\ No newline at end of file
diff --git a/app/src/processing/app/syntax/ArduinoTokenMakerFactory.java b/app/src/processing/app/syntax/ArduinoTokenMakerFactory.java
new file mode 100644
index 000000000..f1c374d80
--- /dev/null
+++ b/app/src/processing/app/syntax/ArduinoTokenMakerFactory.java
@@ -0,0 +1,54 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.syntax;
+
+import org.fife.ui.rsyntaxtextarea.AbstractTokenMakerFactory;
+import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
+import org.fife.ui.rsyntaxtextarea.TokenMaker;
+
+public class ArduinoTokenMakerFactory extends AbstractTokenMakerFactory {
+
+ private final PdeKeywords pdeKeywords;
+
+ public ArduinoTokenMakerFactory(PdeKeywords pdeKeywords) {
+ this.pdeKeywords = pdeKeywords;
+ }
+
+ @Override
+ protected TokenMaker getTokenMakerImpl(String key) {
+ return new SketchTokenMaker(pdeKeywords);
+ }
+
+ @Override
+ protected void initTokenMakerMap() {
+ putMapping(RSyntaxDocument.SYNTAX_STYLE_CPLUSPLUS, SketchTokenMaker.class.getName());
+ }
+
+}
diff --git a/app/src/processing/app/syntax/CTokenMarker.java b/app/src/processing/app/syntax/CTokenMarker.java
deleted file mode 100644
index ccb9b0b48..000000000
--- a/app/src/processing/app/syntax/CTokenMarker.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * CTokenMarker.java - C token marker
- * Copyright (C) 1998, 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import javax.swing.text.Segment;
-
-/**
- * C token marker.
- *
- * @author Slava Pestov
- */
-public class CTokenMarker extends TokenMarker
-{
- public CTokenMarker()
- {
- this(true,getKeywords());
- }
-
- public CTokenMarker(boolean cpp, KeywordMap keywords)
- {
- this.cpp = cpp;
- this.keywords = keywords;
- }
-
- public byte markTokensImpl(byte token, Segment line, int lineIndex)
- {
- char[] array = line.array;
- int offset = line.offset;
- lastOffset = offset;
- lastKeyword = offset;
- int mlength = line.count + offset;
- boolean backslash = false;
-
-loop: for(int i = offset; i < mlength; i++)
- {
- int i1 = (i+1);
-
- char c = array[i];
- if(c == '\\')
- {
- backslash = !backslash;
- continue;
- }
-
- switch(token)
- {
- case Token.NULL:
- switch(c)
- {
- case '#':
- if(backslash)
- backslash = false;
- else if(cpp)
- {
- if(doKeyword(line,i,c))
- break;
- addToken(i - lastOffset,token);
- addToken(mlength - i,Token.KEYWORD2);
- lastOffset = lastKeyword = mlength;
- break loop;
- }
- break;
- case '"':
- doKeyword(line,i,c);
- if(backslash)
- backslash = false;
- else
- {
- addToken(i - lastOffset,token);
- token = Token.LITERAL1;
- lastOffset = lastKeyword = i;
- }
- break;
- case '\'':
- doKeyword(line,i,c);
- if(backslash)
- backslash = false;
- else
- {
- addToken(i - lastOffset,token);
- token = Token.LITERAL2;
- lastOffset = lastKeyword = i;
- }
- break;
- case ':':
- if(lastKeyword == offset)
- {
- if(doKeyword(line,i,c))
- break;
- backslash = false;
- addToken(i1 - lastOffset,Token.LABEL);
- lastOffset = lastKeyword = i1;
- }
- else if(doKeyword(line,i,c))
- break;
- break;
- case '/':
- backslash = false;
- doKeyword(line,i,c);
- if(mlength - i > 1)
- {
- switch(array[i1])
- {
- case '*':
- addToken(i - lastOffset,token);
- lastOffset = lastKeyword = i;
- if(mlength - i > 2 && array[i+2] == '*')
- token = Token.COMMENT2;
- else
- token = Token.COMMENT1;
- break;
- case '/':
- addToken(i - lastOffset,token);
- addToken(mlength - i,Token.COMMENT1);
- lastOffset = lastKeyword = mlength;
- break loop;
- }
- }
- break;
- default:
- backslash = false;
- if(!Character.isLetterOrDigit(c)
- && c != '_')
- doKeyword(line,i,c);
- break;
- }
- break;
- case Token.COMMENT1:
- case Token.COMMENT2:
- backslash = false;
- if(c == '*' && mlength - i > 1)
- {
- if(array[i1] == '/')
- {
- i++;
- addToken((i+1) - lastOffset,token);
- token = Token.NULL;
- lastOffset = lastKeyword = i+1;
- }
- }
- break;
- case Token.LITERAL1:
- if(backslash)
- backslash = false;
- else if(c == '"')
- {
- addToken(i1 - lastOffset,token);
- token = Token.NULL;
- lastOffset = lastKeyword = i1;
- }
- break;
- case Token.LITERAL2:
- if(backslash)
- backslash = false;
- else if(c == '\'')
- {
- addToken(i1 - lastOffset,Token.LITERAL1);
- token = Token.NULL;
- lastOffset = lastKeyword = i1;
- }
- break;
- default:
- throw new InternalError("Invalid state: "
- + token);
- }
- }
-
- if(token == Token.NULL)
- doKeyword(line,mlength,'\0');
-
- switch(token)
- {
- case Token.LITERAL1:
- case Token.LITERAL2:
- addToken(mlength - lastOffset,Token.INVALID);
- token = Token.NULL;
- break;
- case Token.KEYWORD2:
- addToken(mlength - lastOffset,token);
- if (!backslash) token = Token.NULL;
- addToken(mlength - lastOffset,token);
- break;
- default:
- addToken(mlength - lastOffset,token);
- break;
- }
-
- return token;
- }
-
- public static KeywordMap getKeywords()
- {
- if(cKeywords == null)
- {
- cKeywords = new KeywordMap(false);
- cKeywords.add("char",Token.KEYWORD3);
- cKeywords.add("double",Token.KEYWORD3);
- cKeywords.add("enum",Token.KEYWORD3);
- cKeywords.add("float",Token.KEYWORD3);
- cKeywords.add("int",Token.KEYWORD3);
- cKeywords.add("long",Token.KEYWORD3);
- cKeywords.add("short",Token.KEYWORD3);
- cKeywords.add("signed",Token.KEYWORD3);
- cKeywords.add("struct",Token.KEYWORD3);
- cKeywords.add("typedef",Token.KEYWORD3);
- cKeywords.add("union",Token.KEYWORD3);
- cKeywords.add("unsigned",Token.KEYWORD3);
- cKeywords.add("void",Token.KEYWORD3);
- cKeywords.add("auto",Token.KEYWORD1);
- cKeywords.add("const",Token.KEYWORD1);
- cKeywords.add("extern",Token.KEYWORD1);
- cKeywords.add("register",Token.KEYWORD1);
- cKeywords.add("static",Token.KEYWORD1);
- cKeywords.add("volatile",Token.KEYWORD1);
- cKeywords.add("break",Token.KEYWORD1);
- cKeywords.add("case",Token.KEYWORD1);
- cKeywords.add("continue",Token.KEYWORD1);
- cKeywords.add("default",Token.KEYWORD1);
- cKeywords.add("do",Token.KEYWORD1);
- cKeywords.add("else",Token.KEYWORD1);
- cKeywords.add("for",Token.KEYWORD1);
- cKeywords.add("goto",Token.KEYWORD1);
- cKeywords.add("if",Token.KEYWORD1);
- cKeywords.add("return",Token.KEYWORD1);
- cKeywords.add("sizeof",Token.KEYWORD1);
- cKeywords.add("switch",Token.KEYWORD1);
- cKeywords.add("while",Token.KEYWORD1);
- cKeywords.add("asm",Token.KEYWORD2);
- cKeywords.add("asmlinkage",Token.KEYWORD2);
- cKeywords.add("far",Token.KEYWORD2);
- cKeywords.add("huge",Token.KEYWORD2);
- cKeywords.add("inline",Token.KEYWORD2);
- cKeywords.add("near",Token.KEYWORD2);
- cKeywords.add("pascal",Token.KEYWORD2);
- cKeywords.add("true",Token.LITERAL2);
- cKeywords.add("false",Token.LITERAL2);
- cKeywords.add("NULL",Token.LITERAL2);
- }
- return cKeywords;
- }
-
- // private members
- private static KeywordMap cKeywords;
-
- private boolean cpp;
- private KeywordMap keywords;
- private int lastOffset;
- private int lastKeyword;
-
- private boolean doKeyword(Segment line, int i, char c)
- {
- int i1 = i+1;
-
- int len = i - lastKeyword;
- byte id = keywords.lookup(line,lastKeyword,len);
- if(id != Token.NULL)
- {
- if(lastKeyword != lastOffset)
- addToken(lastKeyword - lastOffset,Token.NULL);
- addToken(len,id);
- lastOffset = i;
- }
- lastKeyword = i1;
- return false;
- }
-}
diff --git a/app/src/processing/app/syntax/DefaultInputHandler.java b/app/src/processing/app/syntax/DefaultInputHandler.java
deleted file mode 100644
index e9e23fea1..000000000
--- a/app/src/processing/app/syntax/DefaultInputHandler.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * DefaultInputHandler.java - Default implementation of an input handler
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import javax.swing.KeyStroke;
-import java.awt.event.*;
-import java.awt.Toolkit;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-
-/**
- * The default input handler. It maps sequences of keystrokes into actions
- * and inserts key typed events into the text area.
- * @author Slava Pestov
- */
-public class DefaultInputHandler extends InputHandler
-{
- /**
- * Creates a new input handler with no key bindings defined.
- */
- public DefaultInputHandler()
- {
- bindings = currentBindings = new Hashtable();
- }
-
- /**
- * Sets up the default key bindings.
- */
- public void addDefaultKeyBindings()
- {
- addKeyBinding("BACK_SPACE",BACKSPACE);
- addKeyBinding("C+BACK_SPACE",BACKSPACE_WORD);
- addKeyBinding("DELETE",DELETE);
- addKeyBinding("C+DELETE",DELETE_WORD);
-
- addKeyBinding("ENTER",INSERT_BREAK);
- addKeyBinding("TAB",INSERT_TAB);
-
- addKeyBinding("INSERT",OVERWRITE);
- addKeyBinding("C+\\",TOGGLE_RECT);
-
- addKeyBinding("HOME",HOME);
- addKeyBinding("END",END);
- addKeyBinding("S+HOME",SELECT_HOME);
- addKeyBinding("S+END",SELECT_END);
- addKeyBinding("C+HOME",DOCUMENT_HOME);
- addKeyBinding("C+END",DOCUMENT_END);
- addKeyBinding("CS+HOME",SELECT_DOC_HOME);
- addKeyBinding("CS+END",SELECT_DOC_END);
-
- addKeyBinding("PAGE_UP",PREV_PAGE);
- addKeyBinding("PAGE_DOWN",NEXT_PAGE);
- addKeyBinding("S+PAGE_UP",SELECT_PREV_PAGE);
- addKeyBinding("S+PAGE_DOWN",SELECT_NEXT_PAGE);
-
- addKeyBinding("LEFT",PREV_CHAR);
- addKeyBinding("S+LEFT",SELECT_PREV_CHAR);
- addKeyBinding("C+LEFT",PREV_WORD);
- addKeyBinding("CS+LEFT",SELECT_PREV_WORD);
- addKeyBinding("RIGHT",NEXT_CHAR);
- addKeyBinding("S+RIGHT",SELECT_NEXT_CHAR);
- addKeyBinding("C+RIGHT",NEXT_WORD);
- addKeyBinding("CS+RIGHT",SELECT_NEXT_WORD);
- addKeyBinding("UP",PREV_LINE);
- addKeyBinding("S+UP",SELECT_PREV_LINE);
- addKeyBinding("DOWN",NEXT_LINE);
- addKeyBinding("S+DOWN",SELECT_NEXT_LINE);
-
- addKeyBinding("C+ENTER",REPEAT);
- }
-
- /**
- * Adds a key binding to this input handler. The key binding is
- * a list of white space separated key strokes of the form
- * [modifiers+]key where modifier is C for Control, A for Alt,
- * or S for Shift, and key is either a character (a-z) or a field
- * name in the KeyEvent class prefixed with VK_ (e.g., BACK_SPACE)
- * @param keyBinding The key binding
- * @param action The action
- */
- public void addKeyBinding(String keyBinding, ActionListener action)
- {
- Hashtable current = bindings;
-
- StringTokenizer st = new StringTokenizer(keyBinding);
- while(st.hasMoreTokens())
- {
- KeyStroke keyStroke = parseKeyStroke(st.nextToken());
- if(keyStroke == null)
- return;
-
- if(st.hasMoreTokens())
- {
- Object o = current.get(keyStroke);
- if(o instanceof Hashtable)
- current = (Hashtable)o;
- else
- {
- o = new Hashtable();
- current.put(keyStroke,o);
- current = (Hashtable)o;
- }
- }
- else
- current.put(keyStroke,action);
- }
- }
-
- /**
- * Removes a key binding from this input handler. This is not yet
- * implemented.
- * @param keyBinding The key binding
- */
- public void removeKeyBinding(String keyBinding)
- {
- throw new InternalError("Not yet implemented");
- }
-
- /**
- * Removes all key bindings from this input handler.
- */
- public void removeAllKeyBindings()
- {
- bindings.clear();
- }
-
- /**
- * Returns a copy of this input handler that shares the same
- * key bindings. Setting key bindings in the copy will also
- * set them in the original.
- */
- public InputHandler copy()
- {
- return new DefaultInputHandler(this);
- }
-
- /**
- * Handle a key pressed event. This will look up the binding for
- * the key stroke and execute it.
- */
- public void keyPressed(KeyEvent evt)
- {
- int keyCode = evt.getKeyCode();
- int modifiers = evt.getModifiers();
-
- // moved this earlier so it doesn't get random meta clicks
- if (keyCode == KeyEvent.VK_CONTROL ||
- keyCode == KeyEvent.VK_SHIFT ||
- keyCode == KeyEvent.VK_ALT ||
- keyCode == KeyEvent.VK_META) {
- return;
- }
-
- // don't get command-s or other menu key equivs on mac
- // unless it's something that's specifically bound (cmd-left or right)
- //if ((modifiers & KeyEvent.META_MASK) != 0) return;
- if ((modifiers & KeyEvent.META_MASK) != 0) {
- KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers);
- if (currentBindings.get(keyStroke) == null) {
- return;
- }
- }
-
- /*
- char keyChar = evt.getKeyChar();
- System.out.println("code=" + keyCode + " char=" + keyChar +
- " charint=" + ((int)keyChar));
- System.out.println("other codes " + KeyEvent.VK_ALT + " " +
- KeyEvent.VK_META);
- */
-
- if((modifiers & ~KeyEvent.SHIFT_MASK) != 0
- || evt.isActionKey()
- || keyCode == KeyEvent.VK_BACK_SPACE
- || keyCode == KeyEvent.VK_DELETE
- || keyCode == KeyEvent.VK_ENTER
- || keyCode == KeyEvent.VK_TAB
- || keyCode == KeyEvent.VK_ESCAPE)
- {
- if(grabAction != null)
- {
- handleGrabAction(evt);
- return;
- }
-
- KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode,
- modifiers);
- Object o = currentBindings.get(keyStroke);
- if(o == null)
- {
- // Don't beep if the user presses some
- // key we don't know about unless a
- // prefix is active. Otherwise it will
- // beep when caps lock is pressed, etc.
- if(currentBindings != bindings)
- {
- Toolkit.getDefaultToolkit().beep();
- // F10 should be passed on, but C+e F10
- // shouldn't
- repeatCount = 0;
- repeat = false;
- evt.consume();
- }
- currentBindings = bindings;
- return;
- }
- else if(o instanceof ActionListener)
- {
- currentBindings = bindings;
-
- executeAction(((ActionListener)o),
- evt.getSource(),null);
-
- evt.consume();
- return;
- }
- else if(o instanceof Hashtable)
- {
- currentBindings = (Hashtable)o;
- evt.consume();
- return;
- }
- }
- }
-
- /**
- * Handle a key typed event. This inserts the key into the text area.
- */
- public void keyTyped(KeyEvent evt)
- {
- int modifiers = evt.getModifiers();
- char c = evt.getKeyChar();
-
- // this is the apple/cmd key on macosx.. so menu commands
- // were being passed through as legit keys.. added this line
- // in an attempt to prevent.
- if ((modifiers & KeyEvent.META_MASK) != 0) return;
-
- if (c != KeyEvent.CHAR_UNDEFINED) // &&
- // (modifiers & KeyEvent.ALT_MASK) == 0)
- {
- if(c >= 0x20 && c != 0x7f)
- {
- KeyStroke keyStroke = KeyStroke.getKeyStroke(
- Character.toUpperCase(c));
- Object o = currentBindings.get(keyStroke);
-
- if(o instanceof Hashtable)
- {
- currentBindings = (Hashtable)o;
- return;
- }
- else if(o instanceof ActionListener)
- {
- currentBindings = bindings;
- executeAction((ActionListener)o,
- evt.getSource(),
- String.valueOf(c));
- return;
- }
-
- currentBindings = bindings;
-
- if(grabAction != null)
- {
- handleGrabAction(evt);
- return;
- }
-
- // 0-9 adds another 'digit' to the repeat number
- if(repeat && Character.isDigit(c))
- {
- repeatCount *= 10;
- repeatCount += (c - '0');
- return;
- }
-
- executeAction(INSERT_CHAR,evt.getSource(),
- String.valueOf(evt.getKeyChar()));
-
- repeatCount = 0;
- repeat = false;
- }
- }
- }
-
- /**
- * Converts a string to a keystroke. The string should be of the
- * form modifiers+shortcut where modifiers
- * is any combination of A for Alt, C for Control, S for Shift
- * or M for Meta, and shortcut is either a single character,
- * or a keycode name from the KeyEvent
class, without
- * the VK_
prefix.
- * @param keyStroke A string description of the key stroke
- */
- public static KeyStroke parseKeyStroke(String keyStroke)
- {
- if(keyStroke == null)
- return null;
- int modifiers = 0;
- int index = keyStroke.indexOf('+');
- if(index != -1)
- {
- for(int i = 0; i < index; i++)
- {
- switch(Character.toUpperCase(keyStroke
- .charAt(i)))
- {
- case 'A':
- modifiers |= InputEvent.ALT_MASK;
- break;
- case 'C':
- modifiers |= InputEvent.CTRL_MASK;
- break;
- case 'M':
- modifiers |= InputEvent.META_MASK;
- break;
- case 'S':
- modifiers |= InputEvent.SHIFT_MASK;
- break;
- }
- }
- }
- String key = keyStroke.substring(index + 1);
- if(key.length() == 1)
- {
- char ch = Character.toUpperCase(key.charAt(0));
- if(modifiers == 0)
- return KeyStroke.getKeyStroke(ch);
- else
- return KeyStroke.getKeyStroke(ch,modifiers);
- }
- else if(key.length() == 0)
- {
- System.err.println("Invalid key stroke: " + keyStroke);
- return null;
- }
- else
- {
- int ch;
-
- try
- {
- ch = KeyEvent.class.getField("VK_".concat(key))
- .getInt(null);
- }
- catch(Exception e)
- {
- System.err.println("Invalid key stroke: "
- + keyStroke);
- return null;
- }
-
- return KeyStroke.getKeyStroke(ch,modifiers);
- }
- }
-
- // private members
- private Hashtable bindings;
- private Hashtable currentBindings;
-
- private DefaultInputHandler(DefaultInputHandler copy)
- {
- bindings = currentBindings = copy.bindings;
- }
-}
diff --git a/app/src/processing/app/syntax/InputHandler.java b/app/src/processing/app/syntax/InputHandler.java
deleted file mode 100644
index e14671348..000000000
--- a/app/src/processing/app/syntax/InputHandler.java
+++ /dev/null
@@ -1,1135 +0,0 @@
-/*
- * InputHandler.java - Manages key bindings and executes actions
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import javax.swing.text.*;
-import javax.swing.JPopupMenu;
-import java.awt.event.*;
-import java.awt.Component;
-import java.util.*;
-
-/**
- * An input handler converts the user's key strokes into concrete actions.
- * It also takes care of macro recording and action repetition.
- *
- * This class provides all the necessary support code for an input
- * handler, but doesn't actually do any key binding logic. It is up
- * to the implementations of this class to do so.
- *
- * @author Slava Pestov
- */
-public abstract class InputHandler extends KeyAdapter
-{
- /**
- * If this client property is set to Boolean.TRUE on the text area,
- * the home/end keys will support 'smart' BRIEF-like behaviour
- * (one press = start/end of line, two presses = start/end of
- * viewscreen, three presses = start/end of document). By default,
- * this property is not set.
- */
- public static final String SMART_HOME_END_PROPERTY = "InputHandler.homeEnd";
-
- public static final ActionListener BACKSPACE = new backspace();
- public static final ActionListener BACKSPACE_WORD = new backspace_word();
- public static final ActionListener DELETE = new delete();
- public static final ActionListener DELETE_WORD = new delete_word();
- public static final ActionListener END = new end(false);
- public static final ActionListener DOCUMENT_END = new document_end(false);
- public static final ActionListener SELECT_END = new end(true);
- public static final ActionListener SELECT_DOC_END = new document_end(true);
- public static final ActionListener INSERT_BREAK = new insert_break();
- public static final ActionListener INSERT_TAB = new insert_tab();
- public static final ActionListener HOME = new home(false);
- public static final ActionListener DOCUMENT_HOME = new document_home(false);
- public static final ActionListener SELECT_HOME = new home(true);
- public static final ActionListener SELECT_DOC_HOME = new document_home(true);
- public static final ActionListener NEXT_CHAR = new next_char(false);
- public static final ActionListener NEXT_LINE = new next_line(false);
- public static final ActionListener NEXT_PAGE = new next_page(false);
- public static final ActionListener NEXT_WORD = new next_word(false);
- public static final ActionListener SELECT_NEXT_CHAR = new next_char(true);
- public static final ActionListener SELECT_NEXT_LINE = new next_line(true);
- public static final ActionListener SELECT_NEXT_PAGE = new next_page(true);
- public static final ActionListener SELECT_NEXT_WORD = new next_word(true);
- public static final ActionListener OVERWRITE = new overwrite();
- public static final ActionListener PREV_CHAR = new prev_char(false);
- public static final ActionListener PREV_LINE = new prev_line(false);
- public static final ActionListener PREV_PAGE = new prev_page(false);
- public static final ActionListener PREV_WORD = new prev_word(false);
- public static final ActionListener SELECT_PREV_CHAR = new prev_char(true);
- public static final ActionListener SELECT_PREV_LINE = new prev_line(true);
- public static final ActionListener SELECT_PREV_PAGE = new prev_page(true);
- public static final ActionListener SELECT_PREV_WORD = new prev_word(true);
- public static final ActionListener REPEAT = new repeat();
- public static final ActionListener TOGGLE_RECT = new toggle_rect();
- public static final ActionListener CLIPBOARD_CUT = new clipboard_cut(); // [fry]
- public static final ActionListener CLIPBOARD_COPY = new clipboard_copy();
- public static final ActionListener CLIPBOARD_PASTE = new clipboard_paste();
-
- // Default action
- public static final ActionListener INSERT_CHAR = new insert_char();
-
- private static Hashtable actions;
-
- static
- {
- actions = new Hashtable();
- actions.put("backspace",BACKSPACE);
- actions.put("backspace-word",BACKSPACE_WORD);
- actions.put("delete",DELETE);
- actions.put("delete-word",DELETE_WORD);
- actions.put("end",END);
- actions.put("select-end",SELECT_END);
- actions.put("document-end",DOCUMENT_END);
- actions.put("select-doc-end",SELECT_DOC_END);
- actions.put("insert-break",INSERT_BREAK);
- actions.put("insert-tab",INSERT_TAB);
- actions.put("home",HOME);
- actions.put("select-home",SELECT_HOME);
- actions.put("document-home",DOCUMENT_HOME);
- actions.put("select-doc-home",SELECT_DOC_HOME);
- actions.put("next-char",NEXT_CHAR);
- actions.put("next-line",NEXT_LINE);
- actions.put("next-page",NEXT_PAGE);
- actions.put("next-word",NEXT_WORD);
- actions.put("select-next-char",SELECT_NEXT_CHAR);
- actions.put("select-next-line",SELECT_NEXT_LINE);
- actions.put("select-next-page",SELECT_NEXT_PAGE);
- actions.put("select-next-word",SELECT_NEXT_WORD);
- actions.put("overwrite",OVERWRITE);
- actions.put("prev-char",PREV_CHAR);
- actions.put("prev-line",PREV_LINE);
- actions.put("prev-page",PREV_PAGE);
- actions.put("prev-word",PREV_WORD);
- actions.put("select-prev-char",SELECT_PREV_CHAR);
- actions.put("select-prev-line",SELECT_PREV_LINE);
- actions.put("select-prev-page",SELECT_PREV_PAGE);
- actions.put("select-prev-word",SELECT_PREV_WORD);
- actions.put("repeat",REPEAT);
- actions.put("toggle-rect",TOGGLE_RECT);
- actions.put("insert-char",INSERT_CHAR);
- actions.put("clipboard-cut",CLIPBOARD_CUT);
- actions.put("clipboard-copy",CLIPBOARD_COPY);
- actions.put("clipboard-paste",CLIPBOARD_PASTE);
- }
-
- /**
- * Returns a named text area action.
- * @param name The action name
- */
- public static ActionListener getAction(String name)
- {
- return (ActionListener)actions.get(name);
- }
-
- /**
- * Returns the name of the specified text area action.
- * @param listener The action
- */
- public static String getActionName(ActionListener listener)
- {
- Enumeration en = getActions();
- while(en.hasMoreElements())
- {
- String name = (String)en.nextElement();
- ActionListener _listener = getAction(name);
- if(_listener == listener) {
- return name;
- }
- }
- return null;
- }
-
- /**
- * Returns an enumeration of all available actions.
- */
- public static Enumeration getActions()
- {
- return actions.keys();
- }
-
- /**
- * Adds the default key bindings to this input handler.
- * This should not be called in the constructor of this
- * input handler, because applications might load the
- * key bindings from a file, etc.
- */
- public abstract void addDefaultKeyBindings();
-
- /**
- * Adds a key binding to this input handler.
- * @param keyBinding The key binding (the format of this is
- * input-handler specific)
- * @param action The action
- */
- public abstract void addKeyBinding(String keyBinding, ActionListener action);
-
- /**
- * Removes a key binding from this input handler.
- * @param keyBinding The key binding
- */
- public abstract void removeKeyBinding(String keyBinding);
-
- /**
- * Removes all key bindings from this input handler.
- */
- public abstract void removeAllKeyBindings();
-
- /**
- * Grabs the next key typed event and invokes the specified
- * action with the key as a the action command.
- */
- public void grabNextKeyStroke(ActionListener listener)
- {
- grabAction = listener;
- }
-
- /**
- * Returns if repeating is enabled. When repeating is enabled,
- * actions will be executed multiple times. This is usually
- * invoked with a special key stroke in the input handler.
- */
- public boolean isRepeatEnabled()
- {
- return repeat;
- }
-
- /**
- * Enables repeating. When repeating is enabled, actions will be
- * executed multiple times. Once repeating is enabled, the input
- * handler should read a number from the keyboard.
- */
- public void setRepeatEnabled(boolean repeat)
- {
- this.repeat = repeat;
- }
-
- /**
- * Returns the number of times the next action will be repeated.
- */
- public int getRepeatCount()
- {
- return (repeat ? Math.max(1,repeatCount) : 1);
- }
-
- /**
- * Sets the number of times the next action will be repeated.
- * @param repeatCount The repeat count
- */
- public void setRepeatCount(int repeatCount)
- {
- this.repeatCount = repeatCount;
- }
-
- /**
- * Returns the macro recorder. If this is non-null, all executed
- * actions should be forwarded to the recorder.
- */
- public InputHandler.MacroRecorder getMacroRecorder()
- {
- return recorder;
- }
-
- /**
- * Sets the macro recorder. If this is non-null, all executed
- * actions should be forwarded to the recorder.
- * @param recorder The macro recorder
- */
- public void setMacroRecorder(InputHandler.MacroRecorder recorder)
- {
- this.recorder = recorder;
- }
-
- /**
- * Returns a copy of this input handler that shares the same
- * key bindings. Setting key bindings in the copy will also
- * set them in the original.
- */
- public abstract InputHandler copy();
-
- /**
- * Executes the specified action, repeating and recording it as
- * necessary.
- * @param listener The action listener
- * @param source The event source
- * @param actionCommand The action command
- */
- public void executeAction(ActionListener listener, Object source,
- String actionCommand)
- {
- // create event
- ActionEvent evt = new ActionEvent(source,
- ActionEvent.ACTION_PERFORMED,
- actionCommand);
-
- // don't do anything if the action is a wrapper
- // (like EditAction.Wrapper)
- if(listener instanceof Wrapper)
- {
- listener.actionPerformed(evt);
- return;
- }
-
- // remember old values, in case action changes them
- boolean _repeat = repeat;
- int _repeatCount = getRepeatCount();
-
- // execute the action
- if(listener instanceof InputHandler.NonRepeatable)
- listener.actionPerformed(evt);
- else
- {
- for(int i = 0; i < Math.max(1,repeatCount); i++)
- listener.actionPerformed(evt);
- }
-
- // do recording. Notice that we do no recording whatsoever
- // for actions that grab keys
- if(grabAction == null)
- {
- if(recorder != null)
- {
- if(!(listener instanceof InputHandler.NonRecordable))
- {
- if(_repeatCount != 1)
- recorder.actionPerformed(REPEAT,String.valueOf(_repeatCount));
-
- recorder.actionPerformed(listener,actionCommand);
- }
- }
-
- // If repeat was true originally, clear it
- // Otherwise it might have been set by the action, etc
- if(_repeat)
- {
- repeat = false;
- repeatCount = 0;
- }
- }
- }
-
- /**
- * Returns the text area that fired the specified event.
- * @param evt The event
- */
- public static JEditTextArea getTextArea(EventObject evt)
- {
- if(evt != null)
- {
- Object o = evt.getSource();
- if(o instanceof Component)
- {
- // find the parent text area
- Component c = (Component)o;
- for(;;)
- {
- if(c instanceof JEditTextArea)
- return (JEditTextArea)c;
- else if(c == null)
- break;
- if(c instanceof JPopupMenu)
- c = ((JPopupMenu)c)
- .getInvoker();
- else
- c = c.getParent();
- }
- }
- }
-
- // this shouldn't happen
- System.err.println("BUG: getTextArea() returning null");
- System.err.println("Report this to Slava Pestov ");
- return null;
- }
-
- // protected members
-
- /**
- * If a key is being grabbed, this method should be called with
- * the appropriate key event. It executes the grab action with
- * the typed character as the parameter.
- */
- protected void handleGrabAction(KeyEvent evt)
- {
- // Clear it *before* it is executed so that executeAction()
- // resets the repeat count
- ActionListener _grabAction = grabAction;
- grabAction = null;
- executeAction(_grabAction,evt.getSource(),
- String.valueOf(evt.getKeyChar()));
- }
-
- // protected members
- protected ActionListener grabAction;
- protected boolean repeat;
- protected int repeatCount;
- protected InputHandler.MacroRecorder recorder;
-
- /**
- * If an action implements this interface, it should not be repeated.
- * Instead, it will handle the repetition itself.
- */
- public interface NonRepeatable {}
-
- /**
- * If an action implements this interface, it should not be recorded
- * by the macro recorder. Instead, it will do its own recording.
- */
- public interface NonRecordable {}
-
- /**
- * For use by EditAction.Wrapper only.
- * @since jEdit 2.2final
- */
- public interface Wrapper {}
-
- /**
- * Macro recorder.
- */
- public interface MacroRecorder
- {
- void actionPerformed(ActionListener listener,
- String actionCommand);
- }
-
- public static class backspace implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
-
- if(!textArea.isEditable())
- {
- textArea.getToolkit().beep();
- return;
- }
-
- if(textArea.getSelectionStart()
- != textArea.getSelectionStop())
- {
- textArea.setSelectedText("");
- }
- else
- {
- int caret = textArea.getCaretPosition();
- if(caret == 0)
- {
- textArea.getToolkit().beep();
- return;
- }
- try
- {
- textArea.getDocument().remove(caret - 1,1);
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- }
- }
- }
- }
-
- public static class backspace_word implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int start = textArea.getSelectionStart();
- if(start != textArea.getSelectionStop())
- {
- textArea.setSelectedText("");
- }
-
- int line = textArea.getCaretLine();
- int lineStart = textArea.getLineStartOffset(line);
- int caret = start - lineStart;
-
- String lineText = textArea.getLineText(textArea
- .getCaretLine());
-
- if(caret == 0)
- {
- if(lineStart == 0)
- {
- textArea.getToolkit().beep();
- return;
- }
- caret--;
- }
- else
- {
- String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
- caret = TextUtilities.findWordStart(lineText,caret,noWordSep);
- }
-
- try
- {
- textArea.getDocument().remove(
- caret + lineStart,
- start - (caret + lineStart));
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- }
- }
- }
-
- public static class delete implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
-
- if(!textArea.isEditable())
- {
- textArea.getToolkit().beep();
- return;
- }
-
- if(textArea.getSelectionStart()
- != textArea.getSelectionStop())
- {
- textArea.setSelectedText("");
- }
- else
- {
- int caret = textArea.getCaretPosition();
- if(caret == textArea.getDocumentLength())
- {
- textArea.getToolkit().beep();
- return;
- }
- try
- {
- textArea.getDocument().remove(caret,1);
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- }
- }
- }
- }
-
- public static class delete_word implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int start = textArea.getSelectionStart();
- if(start != textArea.getSelectionStop())
- {
- textArea.setSelectedText("");
- }
-
- int line = textArea.getCaretLine();
- int lineStart = textArea.getLineStartOffset(line);
- int caret = start - lineStart;
-
- String lineText = textArea.getLineText(textArea
- .getCaretLine());
-
- if(caret == lineText.length())
- {
- if(lineStart + caret == textArea.getDocumentLength())
- {
- textArea.getToolkit().beep();
- return;
- }
- caret++;
- }
- else
- {
- String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
- caret = TextUtilities.findWordEnd(lineText,caret,noWordSep);
- }
-
- try
- {
- textArea.getDocument().remove(start,
- (caret + lineStart) - start);
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- }
- }
- }
-
- public static class end implements ActionListener
- {
- private boolean select;
-
- public end(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
-
- int caret = textArea.getCaretPosition();
-
- int lastOfLine = textArea.getLineStopOffset(
- textArea.getCaretLine()) - 1;
- int lastVisibleLine = textArea.getFirstLine()
- + textArea.getVisibleLines();
- if(lastVisibleLine >= textArea.getLineCount())
- {
- lastVisibleLine = Math.min(textArea.getLineCount() - 1,
- lastVisibleLine);
- }
- else
- lastVisibleLine -= (textArea.getElectricScroll() + 1);
-
- int lastVisible = textArea.getLineStopOffset(lastVisibleLine) - 1;
- int lastDocument = textArea.getDocumentLength();
-
- if(caret == lastDocument)
- {
- textArea.getToolkit().beep();
- return;
- }
- else if(!Boolean.TRUE.equals(textArea.getClientProperty(
- SMART_HOME_END_PROPERTY)))
- caret = lastOfLine;
- else if(caret == lastVisible)
- caret = lastDocument;
- else if(caret == lastOfLine)
- caret = lastVisible;
- else
- caret = lastOfLine;
-
- if(select)
- textArea.select(textArea.getMarkPosition(),caret);
- else
- textArea.setCaretPosition(caret);
- }
- }
-
- public static class document_end implements ActionListener
- {
- private boolean select;
-
- public document_end(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- if(select)
- textArea.select(textArea.getMarkPosition(),
- textArea.getDocumentLength());
- else
- textArea.setCaretPosition(textArea
- .getDocumentLength());
- }
- }
-
- public static class home implements ActionListener
- {
- private boolean select;
-
- public home(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
-
- int caret = textArea.getCaretPosition();
-
- int firstLine = textArea.getFirstLine();
-
- int firstOfLine = textArea.getLineStartOffset(
- textArea.getCaretLine());
- int firstVisibleLine = (firstLine == 0 ? 0 :
- firstLine + textArea.getElectricScroll());
- int firstVisible = textArea.getLineStartOffset(
- firstVisibleLine);
-
- if(caret == 0)
- {
- textArea.getToolkit().beep();
- return;
- }
- else if(!Boolean.TRUE.equals(textArea.getClientProperty(
- SMART_HOME_END_PROPERTY)))
- caret = firstOfLine;
- else if(caret == firstVisible)
- caret = 0;
- else if(caret == firstOfLine)
- caret = firstVisible;
- else
- caret = firstOfLine;
-
- if(select)
- textArea.select(textArea.getMarkPosition(),caret);
- else
- textArea.setCaretPosition(caret);
- }
- }
-
- public static class document_home implements ActionListener
- {
- private boolean select;
-
- public document_home(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- if(select)
- textArea.select(textArea.getMarkPosition(),0);
- else
- textArea.setCaretPosition(0);
- }
- }
-
- public static class insert_break implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
-
- if(!textArea.isEditable())
- {
- textArea.getToolkit().beep();
- return;
- }
-
- textArea.setSelectedText("\n");
- }
- }
-
- public static class insert_tab implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
-
- if(!textArea.isEditable())
- {
- textArea.getToolkit().beep();
- return;
- }
-
- textArea.overwriteSetSelectedText("\t");
- }
- }
-
- public static class next_char implements ActionListener
- {
- private boolean select;
-
- public next_char(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int caret = textArea.getCaretPosition();
-
- if(caret == textArea.getDocumentLength())
- {
- if (textArea.getSelectionStart() !=
- textArea.getSelectionStop()) {
- // just move to the end of the selection
- textArea.select(caret, caret);
- } else {
- // beep at the user for being annoying
- textArea.getToolkit().beep();
- }
-
- } else if (select) {
- textArea.select(textArea.getMarkPosition(), caret+1);
-
- } else {
- int start = textArea.getSelectionStart();
- int end = textArea.getSelectionStop();
- if (start != end) {
- textArea.select(end, end);
- } else {
- textArea.setCaretPosition(caret + 1);
- }
- }
- }
- }
-
- public static class next_line implements ActionListener
- {
- private boolean select;
-
- public next_line(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int caret = textArea.getCaretPosition();
- int line = textArea.getCaretLine();
-
- if(line == textArea.getLineCount() - 1)
- {
- //textArea.getToolkit().beep();
- int doc = textArea.getDocumentLength();
- if (select) {
- textArea.select(textArea.getMarkPosition(), doc);
- } else {
- textArea.setCaretPosition(doc);
- }
- return;
- }
-
- int magic = textArea.getMagicCaretPosition();
- if(magic == -1)
- {
- magic = textArea.offsetToX(line,
- caret - textArea.getLineStartOffset(line));
- }
-
- caret = textArea.getLineStartOffset(line + 1)
- + textArea.xToOffset(line + 1,magic);
- if(select)
- textArea.select(textArea.getMarkPosition(),caret);
- else
- textArea.setCaretPosition(caret);
- textArea.setMagicCaretPosition(magic);
- }
- }
-
- public static class next_page implements ActionListener
- {
- private boolean select;
-
- public next_page(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int lineCount = textArea.getLineCount();
- int firstLine = textArea.getFirstLine();
- int visibleLines = textArea.getVisibleLines();
- int line = textArea.getCaretLine();
-
- firstLine += visibleLines;
-
- if(firstLine + visibleLines >= lineCount - 1)
- firstLine = lineCount - visibleLines;
-
- textArea.setFirstLine(firstLine);
-
- int caret = textArea.getLineStartOffset(
- Math.min(textArea.getLineCount() - 1,
- line + visibleLines));
- if(select)
- textArea.select(textArea.getMarkPosition(),caret);
- else
- textArea.setCaretPosition(caret);
- }
- }
-
- public static class next_word implements ActionListener
- {
- private boolean select;
-
- public next_word(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int caret = textArea.getCaretPosition();
- int line = textArea.getCaretLine();
- int lineStart = textArea.getLineStartOffset(line);
- caret -= lineStart;
-
- String lineText = textArea.getLineText(textArea
- .getCaretLine());
-
- if(caret == lineText.length())
- {
- if(lineStart + caret == textArea.getDocumentLength())
- {
- textArea.getToolkit().beep();
- return;
- }
- caret++;
- }
- else
- {
- String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
- caret = TextUtilities.findWordEnd(lineText,caret,noWordSep);
- }
-
- if(select)
- textArea.select(textArea.getMarkPosition(),
- lineStart + caret);
- else
- textArea.setCaretPosition(lineStart + caret);
- }
- }
-
- public static class overwrite implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- textArea.setOverwriteEnabled(
- !textArea.isOverwriteEnabled());
- }
- }
-
- public static class prev_char implements ActionListener
- {
- private boolean select;
-
- public prev_char(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int caret = textArea.getCaretPosition();
- if(caret == 0)
- {
- textArea.getToolkit().beep();
- return;
- }
-
- if (select) {
- textArea.select(textArea.getMarkPosition(), caret-1);
- } else {
- int start = textArea.getSelectionStart();
- int end = textArea.getSelectionStop();
- if (start != end) {
- textArea.select(start, start);
- } else {
- textArea.setCaretPosition(caret - 1);
- }
- }
- }
- }
-
- public static class prev_line implements ActionListener
- {
- private boolean select;
-
- public prev_line(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int caret = textArea.getCaretPosition();
- int line = textArea.getCaretLine();
-
- if(line == 0)
- {
- if (select) {
- if (textArea.getSelectionStart() != 0) {
- textArea.select(textArea.getMarkPosition(), 0);
- }
- } else {
- textArea.setCaretPosition(0);
- }
- //textArea.getToolkit().beep();
- return;
- }
-
- int magic = textArea.getMagicCaretPosition();
- if(magic == -1)
- {
- magic = textArea.offsetToX(line,
- caret - textArea.getLineStartOffset(line));
- }
-
- caret = textArea.getLineStartOffset(line - 1)
- + textArea.xToOffset(line - 1,magic);
- if(select)
- textArea.select(textArea.getMarkPosition(),caret);
- else
- textArea.setCaretPosition(caret);
- textArea.setMagicCaretPosition(magic);
- }
- }
-
- public static class prev_page implements ActionListener
- {
- private boolean select;
-
- public prev_page(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int firstLine = textArea.getFirstLine();
- int visibleLines = textArea.getVisibleLines();
- int line = textArea.getCaretLine();
-
- if(firstLine < visibleLines)
- firstLine = visibleLines;
-
- textArea.setFirstLine(firstLine - visibleLines);
-
- int caret = textArea.getLineStartOffset(
- Math.max(0,line - visibleLines));
- if(select)
- textArea.select(textArea.getMarkPosition(),caret);
- else
- textArea.setCaretPosition(caret);
- }
- }
-
- public static class prev_word implements ActionListener
- {
- private boolean select;
-
- public prev_word(boolean select)
- {
- this.select = select;
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- int caret = textArea.getCaretPosition();
- int line = textArea.getCaretLine();
- int lineStart = textArea.getLineStartOffset(line);
- caret -= lineStart;
-
- String lineText = textArea.getLineText(textArea
- .getCaretLine());
-
- if(caret == 0)
- {
- if(lineStart == 0)
- {
- textArea.getToolkit().beep();
- return;
- }
- caret--;
- }
- else
- {
- String noWordSep = (String)textArea.getDocument().getProperty("noWordSep");
- caret = TextUtilities.findWordStart(lineText,caret,noWordSep);
- }
-
- if(select)
- textArea.select(textArea.getMarkPosition(),
- lineStart + caret);
- else
- textArea.setCaretPosition(lineStart + caret);
- }
- }
-
- public static class repeat implements ActionListener,
- InputHandler.NonRecordable
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- textArea.getInputHandler().setRepeatEnabled(true);
- String actionCommand = evt.getActionCommand();
- if(actionCommand != null)
- {
- textArea.getInputHandler().setRepeatCount(
- Integer.parseInt(actionCommand));
- }
- }
- }
-
- public static class toggle_rect implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- textArea.setSelectionRectangular(
- !textArea.isSelectionRectangular());
- }
- }
-
-
- public static class clipboard_cut implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- getTextArea(evt).cut();
- }
- }
-
-
- public static class clipboard_copy implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- getTextArea(evt).copy();
- }
- }
-
-
- public static class clipboard_paste implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- getTextArea(evt).paste();
- }
- }
-
-
- public static class insert_char implements ActionListener,
- InputHandler.NonRepeatable
- {
- public void actionPerformed(ActionEvent evt)
- {
- JEditTextArea textArea = getTextArea(evt);
- String str = evt.getActionCommand();
- int repeatCount = textArea.getInputHandler().getRepeatCount();
-
- if(textArea.isEditable())
- {
- StringBuffer buf = new StringBuffer();
- for(int i = 0; i < repeatCount; i++)
- buf.append(str);
- textArea.overwriteSetSelectedText(buf.toString());
- }
- else
- {
- textArea.getToolkit().beep();
- }
- }
- }
-}
diff --git a/app/src/processing/app/syntax/JEditTextArea.java b/app/src/processing/app/syntax/JEditTextArea.java
deleted file mode 100644
index c12102038..000000000
--- a/app/src/processing/app/syntax/JEditTextArea.java
+++ /dev/null
@@ -1,2448 +0,0 @@
-/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-
-/*
- * JEditTextArea.java - jEdit's text component
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import processing.app.*;
-
-import javax.swing.event.*;
-import javax.swing.text.*;
-import javax.swing.undo.*;
-import javax.swing.*;
-
-import java.awt.datatransfer.*;
-import java.awt.event.*;
-import java.awt.*;
-import java.util.Enumeration;
-import java.util.Vector;
-import java.awt.im.InputMethodRequests;
-
-import processing.app.syntax.im.InputMethodSupport;
-
-/**
- * jEdit's text area component. It is more suited for editing program
- * source code than JEditorPane, because it drops the unnecessary features
- * (images, variable-width lines, and so on) and adds a whole bunch of
- * useful goodies such as:
- *
- * - More flexible key binding scheme
- *
- Supports macro recorders
- *
- Rectangular selection
- *
- Bracket highlighting
- *
- Syntax highlighting
- *
- Command repetition
- *
- Block caret can be enabled
- *
- * It is also faster and doesn't have as many problems. It can be used
- * in other applications; the only other part of jEdit it depends on is
- * the syntax package.
- *
- * To use it in your app, treat it like any other component, for example:
- *
JEditTextArea ta = new JEditTextArea();
- * ta.setTokenMarker(new JavaTokenMarker());
- * ta.setText("public class Test {\n"
- * + " public static void main(String[] args) {\n"
- * + " System.out.println(\"Hello World\");\n"
- * + " }\n"
- * + "}");
- *
- * @author Slava Pestov
- */
-public class JEditTextArea extends JComponent
-{
- /**
- * Adding components with this name to the text area will place
- * them left of the horizontal scroll bar. In jEdit, the status
- * bar is added this way.
- */
- public static String LEFT_OF_SCROLLBAR = "los";
-
- /**
- * Creates a new JEditTextArea with the default settings.
- */
- /*
- public JEditTextArea()
- {
- this(TextAreaDefaults.getDefaults());
- }
- */
-
- /**
- * Creates a new JEditTextArea with the specified settings.
- * @param defaults The default settings
- */
- public JEditTextArea(TextAreaDefaults defaults)
- {
- // Enable the necessary events
- enableEvents(AWTEvent.KEY_EVENT_MASK);
-
- // Initialize some misc. stuff
- painter = new TextAreaPainter(this,defaults);
- editorLineNumbers = new TextAreaLineNumbers(this,defaults);
- documentHandler = new DocumentHandler();
- eventListenerList = new EventListenerList();
- caretEvent = new MutableCaretEvent();
- lineSegment = new Segment();
- bracketLine = bracketPosition = -1;
- blink = true;
-
- // Initialize the GUI
- setLayout(new ScrollLayout());
- add(LEFT, editorLineNumbers);
- add(CENTER, painter);
- add(RIGHT, vertical = new JScrollBar(JScrollBar.VERTICAL));
- add(BOTTOM, horizontal = new JScrollBar(JScrollBar.HORIZONTAL));
-
- // Add some event listeners
- vertical.addAdjustmentListener(new AdjustHandler());
- horizontal.addAdjustmentListener(new AdjustHandler());
- painter.addComponentListener(new ComponentHandler());
- painter.addMouseListener(new MouseHandler());
- painter.addMouseMotionListener(new DragHandler());
- addFocusListener(new FocusHandler());
- // send tab keys through to the text area
- // http://dev.processing.org/bugs/show_bug.cgi?id=1267
- setFocusTraversalKeysEnabled(false);
-
- // Load the defaults
- setInputHandler(defaults.inputHandler);
- setDocument(defaults.document);
- editable = defaults.editable;
- caretVisible = defaults.caretVisible;
- caretBlinks = defaults.caretBlinks;
- electricScroll = defaults.electricScroll;
-
- // We don't seem to get the initial focus event?
- focusedComponent = this;
-
- addMouseWheelListener(new MouseWheelListener() {
- public void mouseWheelMoved(MouseWheelEvent e) {
- if (!scrollBarsInitialized) return;
- int amt = e.getWheelRotation();
- vertical.setValue(vertical.getValue() + amt * 3);
- }
- });
- }
-
- /**
- * Inline Input Method Support for Japanese.
- */
- private InputMethodSupport inputMethodSupport = null;
- public InputMethodRequests getInputMethodRequests() {
- if (inputMethodSupport == null) {
- inputMethodSupport = new InputMethodSupport(this);
- }
- return inputMethodSupport;
- }
-
- /**
- * Get current position of the vertical scroll bar. [fry]
- */
- public int getScrollPosition() {
- return vertical.getValue();
- }
-
-
- /**
- * Set position of the vertical scroll bar. [fry]
- */
- public void setScrollPosition(int what) {
- vertical.setValue(what);
- }
-
-
- /**
- * Returns if this component can be traversed by pressing
- * the Tab key. This returns false.
- */
-// public final boolean isManagingFocus() {
-// return true;
-// }
-
- /**
- * Returns the object responsible for painting this text area.
- */
- public final TextAreaPainter getPainter() {
- return painter;
- }
-
- /**
- * Returns the input handler.
- */
- public final InputHandler getInputHandler() {
- return inputHandler;
- }
-
- /**
- * Sets the input handler.
- * @param inputHandler The new input handler
- */
- public void setInputHandler(InputHandler inputHandler) {
- this.inputHandler = inputHandler;
- }
-
- /**
- * Returns true if the caret is blinking, false otherwise.
- */
- public final boolean isCaretBlinkEnabled() {
- return caretBlinks;
- }
-
- /**
- * Toggles caret blinking.
- * @param caretBlinks True if the caret should blink, false otherwise
- */
- public void setCaretBlinkEnabled(boolean caretBlinks) {
- this.caretBlinks = caretBlinks;
- if(!caretBlinks)
- blink = false;
-
- painter.invalidateSelectedLines();
- }
-
- /**
- * Returns true if the caret is visible, false otherwise.
- */
- public final boolean isCaretVisible() {
- return (!caretBlinks || blink) && caretVisible;
- }
-
- /**
- * Sets if the caret should be visible.
- * @param caretVisible True if the caret should be visible, false
- * otherwise
- */
- public void setCaretVisible(boolean caretVisible) {
- this.caretVisible = caretVisible;
- blink = true;
-
- painter.invalidateSelectedLines();
- }
-
- /**
- * Blinks the caret.
- */
- public final void blinkCaret() {
- if (caretBlinks) {
- blink = !blink;
- painter.invalidateSelectedLines();
- } else {
- blink = true;
- }
- }
-
- /**
- * Returns the number of lines from the top and button of the
- * text area that are always visible.
- */
- public final int getElectricScroll() {
- return electricScroll;
- }
-
- /**
- * Sets the number of lines from the top and bottom of the text
- * area that are always visible
- * @param electricScroll The number of lines always visible from
- * the top or bottom
- */
- public final void setElectricScroll(int electricScroll) {
- this.electricScroll = electricScroll;
- }
-
-
- /**
- * Updates the state of the scroll bars. This should be called
- * if the number of lines in the document changes, or when the
- * size of the text are changes.
- */
- public void updateScrollBars() {
- if (vertical != null && visibleLines != 0) {
- vertical.setValues(firstLine,visibleLines,0,getLineCount());
- vertical.setUnitIncrement(2);
- vertical.setBlockIncrement(visibleLines);
- }
-
- //if (horizontal != null && width != 0) {
- if ((horizontal != null) && (painter.getWidth() != 0)) {
- //int value = horizontal.getValue();
- //System.out.println("updateScrollBars");
- //int width = painter.getWidth();
- int lineCount = getLineCount();
- int maxLineLength = 0;
- for (int i = 0; i < lineCount; i++) {
- int lineLength = getLineLength(i);
- if (lineLength > maxLineLength) {
- maxLineLength = lineLength;
- }
- }
- int charWidth = painter.getFontMetrics().charWidth('w');
- int width = maxLineLength * charWidth;
- int painterWidth = painter.getWidth();
- //System.out.println("max line len " + maxLineLength);
- //System.out.println("width " + width);
- //System.out.println("text area width " + painter.getWidth());
-
- // this was the default, but it's enormous
- //horizontal.setValues(-horizontalOffset,width,0,width * 5);
-
- // something more reasonable, though this is a bad solution
- //horizontal.setValues(-horizontalOffset,width,0,width * 2);
-
- // in general.. time to start looking at that other syntax pkg
- // since most code should fit the window horizontally, just use
- // the default settings for the width, this is a nicer solution
- // until a better update mechanism can be implemented [fry]
-
- //horizontal.setValues(0, width, 0, width);
- //0, width - horizontalOffset);
- // works, from pre-75 versions of p5
- //horizontal.setValues(-horizontalOffset, width, 0, width);
-
- // gets weird when writing to the end of lines
- //horizontal.setValues(value, painterWidth, 0, width);
-
- // seems to work, implemented for 0075
- horizontal.setValues(-horizontalOffset, painterWidth, 0, width);
-
- //horizontal.setUnitIncrement(painter.getFontMetrics().charWidth('w'));
- horizontal.setUnitIncrement(charWidth);
- horizontal.setBlockIncrement(width / 2);
- }
- updateLineNumbers();
- }
-
- private void updateLineNumbers() {
- if (editorLineNumbers != null) {
- editorLineNumbers.updateLineNumbers(getFirstLine() + 1, Math.min(getFirstLine() + getVisibleLines() + 1, getLineCount()));
- editorLineNumbers.updateWidthForNumDigits(String.valueOf(getLineCount()).length());
- }
- }
-
- /**
- * Returns the line displayed at the text area's origin.
- */
- public final int getFirstLine() {
- return firstLine;
- }
-
- /**
- * Sets the line displayed at the text area's origin without
- * updating the scroll bars.
- */
- public void setFirstLine(int firstLine) {
- if (firstLine == this.firstLine) return;
-
- this.firstLine = firstLine;
- if (firstLine != vertical.getValue()) {
- updateScrollBars();
- }
- repaintEditor();
- }
-
- /**
- * Returns the number of lines visible in this text area.
- */
- public final int getVisibleLines() {
- return visibleLines;
- }
-
- /**
- * Recalculates the number of visible lines. This should not
- * be called directly.
- */
- public final void recalculateVisibleLines() {
- if (painter == null) return;
-
- int height = painter.getHeight();
- int lineHeight = painter.getFontMetrics().getHeight();
- visibleLines = height / lineHeight;
- updateScrollBars();
- }
-
- /**
- * Returns the horizontal offset of drawn lines.
- */
- public final int getHorizontalOffset() {
- return horizontalOffset;
- }
-
- /**
- * Sets the horizontal offset of drawn lines. This can be used to
- * implement horizontal scrolling.
- * @param horizontalOffset offset The new horizontal offset
- */
- public void setHorizontalOffset(int horizontalOffset)
- {
- if(horizontalOffset == this.horizontalOffset)
- return;
- this.horizontalOffset = horizontalOffset;
- if(horizontalOffset != horizontal.getValue())
- updateScrollBars();
- repaintEditor();
- }
-
- /**
- * A fast way of changing both the first line and horizontal
- * offset.
- * @param firstLine The new first line
- * @param horizontalOffset The new horizontal offset
- * @return True if any of the values were changed, false otherwise
- */
- public boolean setOrigin(int firstLine, int horizontalOffset)
- {
- boolean changed = false;
- //int oldFirstLine = this.firstLine;
-
- if(horizontalOffset != this.horizontalOffset)
- {
- this.horizontalOffset = horizontalOffset;
- changed = true;
- }
-
- if(firstLine != this.firstLine)
- {
- this.firstLine = firstLine;
- changed = true;
- }
-
- if(changed)
- {
- updateScrollBars();
- repaintEditor();
- }
-
- return changed;
- }
-
- private void repaintEditor() {
- painter.repaint();
- updateLineNumbers();
- }
-
- /**
- * Ensures that the caret is visible by scrolling the text area if
- * necessary.
- * @return True if scrolling was actually performed, false if the
- * caret was already visible
- */
- public boolean scrollToCaret()
- {
- int line = getCaretLine();
- int lineStart = getLineStartOffset(line);
- int offset = Math.max(0,Math.min(getLineLength(line) - 1,
- getCaretPosition() - lineStart));
-
- return scrollTo(line,offset);
- }
-
- /**
- * Ensures that the specified line and offset is visible by scrolling
- * the text area if necessary.
- * @param line The line to scroll to
- * @param offset The offset in the line to scroll to
- * @return True if scrolling was actually performed, false if the
- * line and offset was already visible
- */
- public boolean scrollTo(int line, int offset)
- {
- // visibleLines == 0 before the component is realized
- // we can't do any proper scrolling then, so we have
- // this hack...
- if (visibleLines == 0) {
- setFirstLine(Math.max(0,line - electricScroll));
- return true;
- }
-
- int newFirstLine = firstLine;
- int newHorizontalOffset = horizontalOffset;
-
- if(line < firstLine + electricScroll) {
- newFirstLine = Math.max(0,line - electricScroll);
-
- } else if(line + electricScroll >= firstLine + visibleLines) {
- newFirstLine = (line - visibleLines) + electricScroll + 1;
- if(newFirstLine + visibleLines >= getLineCount())
- newFirstLine = getLineCount() - visibleLines;
- if(newFirstLine < 0)
- newFirstLine = 0;
- }
-
- int x = _offsetToX(line,offset);
- int width = painter.getFontMetrics().charWidth('w');
-
- if(x < 0) {
- newHorizontalOffset = Math.min(0,horizontalOffset - x + width + 5);
- } else if(x + width >= painter.getWidth()) {
- newHorizontalOffset = horizontalOffset +
- (painter.getWidth() - x) - width - 5;
- }
-
- return setOrigin(newFirstLine,newHorizontalOffset);
- }
-
- /**
- * Converts a line index to a y co-ordinate.
- * @param line The line
- */
- public int lineToY(int line)
- {
- FontMetrics fm = painter.getFontMetrics();
- return (line - firstLine) * fm.getHeight()
- - (fm.getLeading() + fm.getMaxDescent());
- }
-
- /**
- * Converts a y co-ordinate to a line index.
- * @param y The y co-ordinate
- */
- public int yToLine(int y)
- {
- FontMetrics fm = painter.getFontMetrics();
- int height = fm.getHeight();
- return Math.max(0,Math.min(getLineCount() - 1,
- y / height + firstLine));
- }
-
- /**
- * Converts an offset in a line into an x co-ordinate. This is a
- * slow version that can be used any time.
- * @param line The line
- * @param offset The offset, from the start of the line
- */
- public final int offsetToX(int line, int offset)
- {
- // don't use cached tokens
- painter.currentLineTokens = null;
- return _offsetToX(line,offset);
- }
-
- /**
- * Converts an offset in a line into an x co-ordinate. This is a
- * fast version that should only be used if no changes were made
- * to the text since the last repaint.
- * @param line The line
- * @param offset The offset, from the start of the line
- */
- public int _offsetToX(int line, int offset)
- {
- TokenMarker tokenMarker = getTokenMarker();
-
- /* Use painter's cached info for speed */
- FontMetrics fm = painter.getFontMetrics();
-
- getLineText(line,lineSegment);
-
- int segmentOffset = lineSegment.offset;
- int x = horizontalOffset;
-
- /* If syntax coloring is disabled, do simple translation */
- if(tokenMarker == null)
- {
- lineSegment.count = offset;
- return x + Utilities.getTabbedTextWidth(lineSegment,
- fm,x,painter,0);
- }
- /* If syntax coloring is enabled, we have to do this because
- * tokens can vary in width */
- else
- {
- Token tokens;
- if(painter.currentLineIndex == line
- && painter.currentLineTokens != null)
- tokens = painter.currentLineTokens;
- else
- {
- painter.currentLineIndex = line;
- tokens = painter.currentLineTokens
- = tokenMarker.markTokens(lineSegment,line);
- }
-
- //Toolkit toolkit = painter.getToolkit();
- Font defaultFont = painter.getFont();
- SyntaxStyle[] styles = painter.getStyles();
-
- for(;;)
- {
- byte id = tokens.id;
- if(id == Token.END)
- {
- return x;
- }
-
- if(id == Token.NULL)
- fm = painter.getFontMetrics();
- else
- fm = styles[id].getFontMetrics(defaultFont, this);
-
- int length = tokens.length;
-
- if(offset + segmentOffset < lineSegment.offset + length)
- {
- lineSegment.count = offset - (lineSegment.offset - segmentOffset);
- return x + Utilities.getTabbedTextWidth(
- lineSegment,fm,x,painter,0);
- }
- else
- {
- lineSegment.count = length;
- x += Utilities.getTabbedTextWidth(
- lineSegment,fm,x,painter,0);
- lineSegment.offset += length;
- }
- tokens = tokens.next;
- }
- }
- }
-
- /**
- * Converts an x co-ordinate to an offset within a line.
- * @param line The line
- * @param x The x co-ordinate
- */
- public int xToOffset(int line, int x)
- {
- TokenMarker tokenMarker = getTokenMarker();
-
- /* Use painter's cached info for speed */
- FontMetrics fm = painter.getFontMetrics();
-
- getLineText(line,lineSegment);
-
- char[] segmentArray = lineSegment.array;
- int segmentOffset = lineSegment.offset;
- int segmentCount = lineSegment.count;
-
- int width = horizontalOffset;
-
- if(tokenMarker == null)
- {
- for(int i = 0; i < segmentCount; i++)
- {
- char c = segmentArray[i + segmentOffset];
- int charWidth;
- if(c == '\t')
- charWidth = (int)painter.nextTabStop(width,i)
- - width;
- else
- charWidth = fm.charWidth(c);
-
- if(painter.isBlockCaretEnabled())
- {
- if(x - charWidth <= width)
- return i;
- }
- else
- {
- if(x - charWidth / 2 <= width)
- return i;
- }
-
- width += charWidth;
- }
-
- return segmentCount;
- }
- else
- {
- Token tokens;
- if(painter.currentLineIndex == line && painter
- .currentLineTokens != null)
- tokens = painter.currentLineTokens;
- else
- {
- painter.currentLineIndex = line;
- tokens = painter.currentLineTokens
- = tokenMarker.markTokens(lineSegment,line);
- }
-
- int offset = 0;
- //Toolkit toolkit = painter.getToolkit();
- Font defaultFont = painter.getFont();
- SyntaxStyle[] styles = painter.getStyles();
-
- for(;;)
- {
- byte id = tokens.id;
- if(id == Token.END)
- return offset;
-
- if(id == Token.NULL)
- fm = painter.getFontMetrics();
- else
- fm = styles[id].getFontMetrics(defaultFont, this);
-
- int length = tokens.length;
-
- for(int i = 0; i < length; i++)
- {
- char c = segmentArray[segmentOffset + offset + i];
- int charWidth;
- if(c == '\t')
- charWidth = (int)painter.nextTabStop(width,offset + i)
- - width;
- else
- charWidth = fm.charWidth(c);
-
- if(painter.isBlockCaretEnabled())
- {
- if(x - charWidth <= width)
- return offset + i;
- }
- else
- {
- if(x - charWidth / 2 <= width)
- return offset + i;
- }
-
- width += charWidth;
- }
-
- offset += length;
- tokens = tokens.next;
- }
- }
- }
-
- /**
- * Converts a point to an offset, from the start of the text.
- * @param x The x co-ordinate of the point
- * @param y The y co-ordinate of the point
- */
- public int xyToOffset(int x, int y)
- {
- int line = yToLine(y);
- int start = getLineStartOffset(line);
- return start + xToOffset(line,x);
- }
-
- /**
- * Returns the document this text area is editing.
- */
- public final SyntaxDocument getDocument()
- {
- return document;
- }
-
- /**
- * Sets the document this text area is editing.
- * @param document The document
- */
- public void setDocument(SyntaxDocument document) {
- if (this.document == document)
- return;
- if (this.document != null)
- this.document.removeDocumentListener(documentHandler);
- this.document = document;
-
- document.addDocumentListener(documentHandler);
-
- select(0, 0);
- updateScrollBars();
- repaintEditor();
- }
-
-
- /**
- * Set document with a twist, includes the old caret
- * and scroll positions, added for p5. [fry]
- */
- public void setDocument(SyntaxDocument document,
- int start, int stop, int scroll) {
- if (this.document == document)
- return;
- if (this.document != null)
- this.document.removeDocumentListener(documentHandler);
- this.document = document;
-
- document.addDocumentListener(documentHandler);
-
- select(start, stop);
- updateScrollBars();
- setScrollPosition(scroll);
- repaintEditor();
- }
-
-
- /**
- * Returns the document's token marker. Equivalent to calling
- * getDocument().getTokenMarker()
.
- */
- public final TokenMarker getTokenMarker()
- {
- return document.getTokenMarker();
- }
-
- /**
- * Sets the document's token marker. Equivalent to caling
- * getDocument().setTokenMarker()
.
- * @param tokenMarker The token marker
- */
- public final void setTokenMarker(TokenMarker tokenMarker)
- {
- document.setTokenMarker(tokenMarker);
- }
-
- /**
- * Returns the length of the document. Equivalent to calling
- * getDocument().getLength()
.
- */
- public final int getDocumentLength()
- {
- return document.getLength();
- }
-
- /**
- * Returns the number of lines in the document.
- */
- public final int getLineCount()
- {
- if (document != null) {
- return document.getDefaultRootElement().getElementCount();
- } else {
- return 0;
- }
- }
-
- /**
- * Returns the line containing the specified offset.
- * @param offset The offset
- */
- public final int getLineOfOffset(int offset)
- {
- return document.getDefaultRootElement().getElementIndex(offset);
- }
-
- /**
- * Returns the start offset of the specified line.
- * @param line The line
- * @return The start offset of the specified line, or -1 if the line is
- * invalid
- */
- public int getLineStartOffset(int line)
- {
- Element lineElement = document.getDefaultRootElement()
- .getElement(line);
- if(lineElement == null)
- return -1;
- else
- return lineElement.getStartOffset();
- }
-
- /**
- * Returns the end offset of the specified line.
- * @param line The line
- * @return The end offset of the specified line, or -1 if the line is
- * invalid.
- */
- public int getLineStopOffset(int line)
- {
- Element lineElement = document.getDefaultRootElement()
- .getElement(line);
- if(lineElement == null)
- return -1;
- else
- 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
- */
- public int getLineLength(int line)
- {
- Element lineElement = document.getDefaultRootElement()
- .getElement(line);
- if(lineElement == null)
- return -1;
- else
- return lineElement.getEndOffset()
- - lineElement.getStartOffset() - 1;
- }
-
- /**
- * Returns the entire text of this text area.
- */
- public String getText()
- {
- try
- {
- return document.getText(0,document.getLength());
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- return null;
- }
- }
-
-
- /**
- * Sets the entire text of this text area.
- */
- public void setText(String text)
- {
- try {
- document.beginCompoundEdit();
- document.remove(0,document.getLength());
- document.insertString(0,text,null);
-
- } catch (BadLocationException bl) {
- bl.printStackTrace();
-
- } finally {
- document.endCompoundEdit();
- }
- }
-
-
- /**
- * Returns the specified substring of the document.
- * @param start The start offset
- * @param len The length of the substring
- * @return The substring, or null if the offsets are invalid
- */
- public final String getText(int start, int len)
- {
- try
- {
- return document.getText(start,len);
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- return null;
- }
- }
-
- /**
- * Copies the specified substring of the document into a segment.
- * If the offsets are invalid, the segment will contain a null string.
- * @param start The start offset
- * @param len The length of the substring
- * @param segment The segment
- */
- public final void getText(int start, int len, Segment segment)
- {
- try
- {
- document.getText(start,len,segment);
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- segment.offset = segment.count = 0;
- }
- }
-
- /**
- * Returns the text on the specified line.
- * @param lineIndex The line
- * @return The text, or null if the line is invalid
- */
- public final String getLineText(int lineIndex)
- {
- int start = getLineStartOffset(lineIndex);
- return getText(start,getLineStopOffset(lineIndex) - start - 1);
- }
-
- /**
- * Copies the text on the specified line into a segment. If the line
- * is invalid, the segment will contain a null string.
- * @param lineIndex The line
- */
- public final void getLineText(int lineIndex, Segment segment)
- {
- int start = getLineStartOffset(lineIndex);
- getText(start,getLineStopOffset(lineIndex) - start - 1,segment);
- }
-
- /**
- * Returns the selection start offset.
- */
- public final int getSelectionStart()
- {
- return selectionStart;
- }
-
- /**
- * Returns the offset where the selection starts on the specified
- * line.
- */
- public int getSelectionStart(int line)
- {
- if(line == selectionStartLine)
- return selectionStart;
- else if(rectSelect)
- {
- Element map = document.getDefaultRootElement();
- int start = selectionStart - map.getElement(selectionStartLine)
- .getStartOffset();
-
- Element lineElement = map.getElement(line);
- int lineStart = lineElement.getStartOffset();
- int lineEnd = lineElement.getEndOffset() - 1;
- return Math.min(lineEnd,lineStart + start);
- }
- else
- return getLineStartOffset(line);
- }
-
- /**
- * Returns the selection start line.
- */
- public final int getSelectionStartLine()
- {
- return selectionStartLine;
- }
-
- /**
- * Sets the selection start. The new selection will be the new
- * selection start and the old selection end.
- * @param selectionStart The selection start
- * @see #select(int,int)
- */
- public final void setSelectionStart(int selectionStart)
- {
- select(selectionStart,selectionEnd);
- }
-
- /**
- * Returns the selection end offset.
- */
- public final int getSelectionStop()
- {
- return selectionEnd;
- }
-
- /**
- * Returns the offset where the selection ends on the specified
- * line.
- */
- public int getSelectionStop(int line)
- {
- if(line == selectionEndLine)
- return selectionEnd;
- else if(rectSelect)
- {
- Element map = document.getDefaultRootElement();
- int end = selectionEnd - map.getElement(selectionEndLine)
- .getStartOffset();
-
- Element lineElement = map.getElement(line);
- int lineStart = lineElement.getStartOffset();
- int lineEnd = lineElement.getEndOffset() - 1;
- return Math.min(lineEnd,lineStart + end);
- }
- else
- return getLineStopOffset(line) - 1;
- }
-
- /**
- * Returns the selection end line.
- */
- public final int getSelectionStopLine()
- {
- return selectionEndLine;
- }
-
- /**
- * Sets the selection end. The new selection will be the old
- * selection start and the bew selection end.
- * @param selectionEnd The selection end
- * @see #select(int,int)
- */
- public final void setSelectionEnd(int selectionEnd)
- {
- select(selectionStart,selectionEnd);
- }
-
-
- public final boolean isSelectionActive()
- {
- return(selectionStart != selectionEnd);
- }
-
- /**
- * Returns the caret position. This will either be the selection
- * start or the selection end, depending on which direction the
- * selection was made in.
- */
- public final int getCaretPosition()
- {
- return (biasLeft ? selectionStart : selectionEnd);
- }
-
- /**
- * Returns the caret line.
- */
- public final int getCaretLine()
- {
- return (biasLeft ? selectionStartLine : selectionEndLine);
- }
-
- /**
- * Returns the mark position. This will be the opposite selection
- * bound to the caret position.
- * @see #getCaretPosition()
- */
- public final int getMarkPosition()
- {
- return (biasLeft ? selectionEnd : selectionStart);
- }
-
- /**
- * Returns the mark line.
- */
- public final int getMarkLine()
- {
- return (biasLeft ? selectionEndLine : selectionStartLine);
- }
-
- /**
- * Sets the caret position. The new selection will consist of the
- * caret position only (hence no text will be selected)
- * @param caret The caret position
- * @see #select(int,int)
- */
- public final void setCaretPosition(int caret)
- {
- select(caret,caret);
- }
-
- /**
- * Selects all text in the document.
- */
- public final void selectAll()
- {
- select(0,getDocumentLength());
- }
-
- /**
- * Moves the mark to the caret position.
- */
- public final void selectNone()
- {
- select(getCaretPosition(),getCaretPosition());
- }
-
- /**
- * Selects from the start offset to the end offset. This is the
- * general selection method used by all other selecting methods.
- * The caret position will be start if start < end, and end
- * if end > start.
- * @param start The start offset
- * @param end The end offset
- */
- public void select(int start, int end)
- {
- int newStart, newEnd;
- boolean newBias;
- if(start <= end)
- {
- newStart = start;
- newEnd = end;
- newBias = false;
- }
- else
- {
- newStart = end;
- newEnd = start;
- newBias = true;
- }
-
- if (newEnd > getDocumentLength()) {
- newEnd = getDocumentLength();
- }
-
- if(newStart < 0)
- {
- throw new IllegalArgumentException("Bounds out of"
- + " range: " + newStart + "," +
- newEnd + " [" + getDocumentLength() + "]");
- }
-
- // If the new position is the same as the old, we don't
- // do all this crap, however we still do the stuff at
- // the end (clearing magic position, scrolling)
- if(newStart != selectionStart || newEnd != selectionEnd
- || newBias != biasLeft)
- {
- int newStartLine = getLineOfOffset(newStart);
- int newEndLine = getLineOfOffset(newEnd);
-
- if(painter.isBracketHighlightEnabled())
- {
- if(bracketLine != -1)
- painter.invalidateLine(bracketLine);
- updateBracketHighlight(end);
- if(bracketLine != -1)
- painter.invalidateLine(bracketLine);
- }
-
- painter.invalidateLineRange(selectionStartLine,selectionEndLine);
- painter.invalidateLineRange(newStartLine,newEndLine);
-
- document.addUndoableEdit(new CaretUndo(selectionStart,selectionEnd));
-
- selectionStart = newStart;
- selectionEnd = newEnd;
- selectionStartLine = newStartLine;
- selectionEndLine = newEndLine;
- biasLeft = newBias;
-
- if (newStart != newEnd) {
- Clipboard unixclipboard = getToolkit().getSystemSelection();
- if (unixclipboard != null) {
- String selection = getSelectedText();
- if (selection != null) {
- unixclipboard.setContents(new StringSelection(selection), null);
- }
- }
- }
-
- fireCaretEvent();
- }
-
- // When the user is typing, etc, we don't want the caret
- // to blink
- blink = true;
- caretTimer.restart();
-
- // Disable rectangle select if selection start = selection end
- if(selectionStart == selectionEnd)
- rectSelect = false;
-
- // Clear the `magic' caret position used by up/down
- magicCaret = -1;
-
- scrollToCaret();
-
- // notify the line number feller
- if (editorLineStatus != null) {
- editorLineStatus.set(selectionStartLine, selectionEndLine);
- //System.out.println("why " + selectionStartLine + " " + selectionEndLine);
- //System.out.println(getLineOfOffset(start) + " " +
- // 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;
- }
-
-
- /**
- * Returns the selected text, or null if no selection is active.
- */
- public final String getSelectedText()
- {
- if(selectionStart == selectionEnd)
- return null;
-
- if(rectSelect)
- {
- // Return each row of the selection on a new line
-
- Element map = document.getDefaultRootElement();
-
- int start = selectionStart - map.getElement(selectionStartLine)
- .getStartOffset();
- int end = selectionEnd - map.getElement(selectionEndLine)
- .getStartOffset();
-
- // Certain rectangles satisfy this condition...
- if(end < start)
- {
- int tmp = end;
- end = start;
- start = tmp;
- }
-
- StringBuffer buf = new StringBuffer();
- Segment seg = new Segment();
-
- for(int i = selectionStartLine; i <= selectionEndLine; i++)
- {
- Element lineElement = map.getElement(i);
- int lineStart = lineElement.getStartOffset();
- int lineEnd = lineElement.getEndOffset() - 1;
- int lineLen = lineEnd - lineStart;
-
- lineStart = Math.min(lineStart + start,lineEnd);
- lineLen = Math.min(end - start,lineEnd - lineStart);
-
- getText(lineStart,lineLen,seg);
- buf.append(seg.array,seg.offset,seg.count);
-
- if(i != selectionEndLine)
- buf.append('\n');
- }
-
- return buf.toString();
- }
- else
- {
- return getText(selectionStart,
- selectionEnd - selectionStart);
- }
- }
-
- /**
- * Replaces the selection with the specified text.
- * @param selectedText The replacement text for the selection
- */
- public void setSelectedText(String selectedText)
- {
- if(!editable)
- {
- throw new InternalError("Text component"
- + " read only");
- }
-
- document.beginCompoundEdit();
-
- try
- {
- if(rectSelect)
- {
- Element map = document.getDefaultRootElement();
-
- int start = selectionStart - map.getElement(selectionStartLine)
- .getStartOffset();
- int end = selectionEnd - map.getElement(selectionEndLine)
- .getStartOffset();
-
- // Certain rectangles satisfy this condition...
- if(end < start)
- {
- int tmp = end;
- end = start;
- start = tmp;
- }
-
- int lastNewline = 0;
- int currNewline = 0;
-
- for(int i = selectionStartLine; i <= selectionEndLine; i++)
- {
- Element lineElement = map.getElement(i);
- int lineStart = lineElement.getStartOffset();
- int lineEnd = lineElement.getEndOffset() - 1;
- int rectStart = Math.min(lineEnd,lineStart + start);
-
- document.remove(rectStart,Math.min(lineEnd - rectStart,
- end - start));
-
- if(selectedText == null)
- continue;
-
- currNewline = selectedText.indexOf('\n',lastNewline);
- if(currNewline == -1)
- currNewline = selectedText.length();
-
- document.insertString(rectStart,selectedText
- .substring(lastNewline,currNewline),null);
-
- lastNewline = Math.min(selectedText.length(),
- currNewline + 1);
- }
-
- if(selectedText != null &&
- currNewline != selectedText.length())
- {
- int offset = map.getElement(selectionEndLine)
- .getEndOffset() - 1;
- document.insertString(offset,"\n",null);
- document.insertString(offset + 1,selectedText
- .substring(currNewline + 1),null);
- }
- }
- else
- {
- document.remove(selectionStart,
- selectionEnd - selectionStart);
- if(selectedText != null)
- {
- document.insertString(selectionStart,
- selectedText,null);
- }
- }
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- throw new InternalError("Cannot replace"
- + " selection");
- }
- // No matter what happends... stops us from leaving document
- // in a bad state
- finally
- {
- document.endCompoundEdit();
- }
-
- setCaretPosition(selectionEnd);
- }
-
- /**
- * Returns true if this text area is editable, false otherwise.
- */
- public final boolean isEditable()
- {
- return editable;
- }
-
- /**
- * Sets if this component is editable.
- * @param editable True if this text area should be editable,
- * false otherwise
- */
- public final void setEditable(boolean editable)
- {
- this.editable = editable;
- }
-
- /**
- * Returns the right click popup menu.
- */
- public final JPopupMenu getRightClickPopup()
- {
- return popup;
- }
-
- /**
- * Sets the right click popup menu.
- * @param popup The popup
- */
- //public final void setRightClickPopup(EditPopupMenu popup)
- public final void setRightClickPopup(JPopupMenu popup)
- {
- this.popup = popup;
- }
-
-
- /**
- * Returns the `magic' caret position. This can be used to preserve
- * the column position when moving up and down lines.
- */
- public final int getMagicCaretPosition()
- {
- return magicCaret;
- }
-
- /**
- * Sets the `magic' caret position. This can be used to preserve
- * the column position when moving up and down lines.
- * @param magicCaret The magic caret position
- */
- public final void setMagicCaretPosition(int magicCaret)
- {
- this.magicCaret = magicCaret;
- }
-
- /**
- * Similar to setSelectedText()
, but overstrikes the
- * appropriate number of characters if overwrite mode is enabled.
- * @param str The string
- * @see #setSelectedText(String)
- * @see #isOverwriteEnabled()
- */
- public void overwriteSetSelectedText(String str)
- {
- // Don't overstrike if there is a selection
- if(!overwrite || selectionStart != selectionEnd)
- {
- setSelectedText(str);
- return;
- }
-
- // Don't overstrike if we're on the end of
- // the line
- int caret = getCaretPosition();
- int caretLineEnd = getLineStopOffset(getCaretLine());
- if(caretLineEnd - caret <= str.length())
- {
- setSelectedText(str);
- return;
- }
-
- document.beginCompoundEdit();
-
- try
- {
- document.remove(caret,str.length());
- document.insertString(caret,str,null);
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- }
- finally
- {
- document.endCompoundEdit();
- }
- }
-
- /**
- * Returns true if overwrite mode is enabled, false otherwise.
- */
- public final boolean isOverwriteEnabled()
- {
- return overwrite;
- }
-
- /**
- * Sets if overwrite mode should be enabled.
- * @param overwrite True if overwrite mode should be enabled,
- * false otherwise.
- */
- public final void setOverwriteEnabled(boolean overwrite)
- {
- this.overwrite = overwrite;
- painter.invalidateSelectedLines();
- }
-
- /**
- * Returns true if the selection is rectangular, false otherwise.
- */
- public final boolean isSelectionRectangular()
- {
- return rectSelect;
- }
-
- /**
- * Sets if the selection should be rectangular.
- * @param rectSelect True if the selection should be rectangular,
- * false otherwise.
- */
- public final void setSelectionRectangular(boolean rectSelect)
- {
- this.rectSelect = rectSelect;
- painter.invalidateSelectedLines();
- }
-
- /**
- * Returns the position of the highlighted bracket (the bracket
- * matching the one before the caret)
- */
- public final int getBracketPosition()
- {
- return bracketPosition;
- }
-
- /**
- * Returns the line of the highlighted bracket (the bracket
- * matching the one before the caret)
- */
- public final int getBracketLine()
- {
- return bracketLine;
- }
-
- /**
- * Adds a caret change listener to this text area.
- * @param listener The listener
- */
- public final void addCaretListener(CaretListener listener)
- {
- eventListenerList.add(CaretListener.class,listener);
- }
-
- /**
- * Removes a caret change listener from this text area.
- * @param listener The listener
- */
- public final void removeCaretListener(CaretListener listener)
- {
- eventListenerList.remove(CaretListener.class,listener);
- }
-
- /**
- * Deletes the selected text from the text area and places it
- * into the clipboard.
- */
- public void cut()
- {
- if(editable)
- {
- copy();
- setSelectedText("");
- }
- }
-
- /**
- * Places the selected text into the clipboard.
- */
- public void copy()
- {
- if(selectionStart != selectionEnd)
- {
- Clipboard clipboard = getToolkit().getSystemClipboard();
-
- String selection = getSelectedText();
-
- int repeatCount = inputHandler.getRepeatCount();
- StringBuffer buf = new StringBuffer();
- for(int i = 0; i < repeatCount; i++)
- buf.append(selection);
-
- Transferable t = new StringSelection(buf.toString());
- clipboard.setContents(t, null);
-
- Clipboard unixclipboard = getToolkit().getSystemSelection();
- if (unixclipboard != null) unixclipboard.setContents(t, null);
- }
- }
-
- /**
- * Inserts the clipboard contents into the text.
- */
- public void paste() {
- if (editable) {
- Clipboard clipboard = getToolkit().getSystemClipboard();
- try {
- // The MacOS MRJ doesn't convert \r to \n, so do it here
- String selection = ((String)clipboard.getContents(this).getTransferData(DataFlavor.stringFlavor)).replace('\r','\n');
-
- // particularly on macosx when pasting from safari,
- // replace unicode x00A0 (non-breaking space)
- // with just a plain space. [fry 030929]
- selection = selection.replace('\u00A0', ' ');
-
- int repeatCount = inputHandler.getRepeatCount();
- StringBuffer buf = new StringBuffer();
- for (int i = 0; i < repeatCount; i++)
- buf.append(selection);
- selection = buf.toString();
- setSelectedText(selection);
-
- } catch(Exception e) {
- getToolkit().beep();
- System.err.println("Clipboard does not contain a string");
- }
- }
- }
-
- /**
- * Called by the AWT when this component is removed from it's parent.
- * This stops clears the currently focused component.
- */
- public void removeNotify()
- {
- super.removeNotify();
- if(focusedComponent == this)
- focusedComponent = null;
- }
-
- /**
- * Forwards key events directly to the input handler.
- * This is slightly faster than using a KeyListener
- * because some Swing overhead is avoided.
- */
- public EditorListener editorListener;
-
- /**
- * The component that tracks the current line number.
- */
- public EditorLineStatus editorLineStatus;
-
-
- public void processKeyEvent(KeyEvent evt) {
- // this had to be added in Processing 007X, because the menu key
- // events weren't making it up to the frame.
- super.processKeyEvent(evt);
-
- //System.out.println("jedittextarea: " + evt);
- //System.out.println();
- if (inputHandler == null) return;
-
- switch(evt.getID()) {
- case KeyEvent.KEY_TYPED:
- if ((editorListener == null) || !editorListener.keyTyped(evt)) {
- inputHandler.keyTyped(evt);
- }
- break;
- case KeyEvent.KEY_PRESSED:
- if ((editorListener == null) || !editorListener.keyPressed(evt)) {
- inputHandler.keyPressed(evt);
- }
- break;
- case KeyEvent.KEY_RELEASED:
- inputHandler.keyReleased(evt);
- break;
- }
- }
-
- // protected members
- protected static String LEFT = "left";
- protected static String CENTER = "center";
- protected static String RIGHT = "right";
- protected static String BOTTOM = "bottom";
-
- protected static JEditTextArea focusedComponent;
- protected static Timer caretTimer;
-
- protected TextAreaPainter painter;
- protected TextAreaLineNumbers editorLineNumbers;
-
- //protected EditPopupMenu popup;
- protected JPopupMenu popup;
-
- protected EventListenerList eventListenerList;
- protected MutableCaretEvent caretEvent;
-
- protected boolean caretBlinks;
- protected boolean caretVisible;
- protected boolean blink;
-
- protected boolean editable;
-
- protected int firstLine;
- protected int visibleLines;
- protected int electricScroll;
-
- protected int horizontalOffset;
-
- protected JScrollBar vertical;
- protected JScrollBar horizontal;
- protected boolean scrollBarsInitialized;
-
- protected InputHandler inputHandler;
- protected SyntaxDocument document;
- protected DocumentHandler documentHandler;
-
- protected Segment lineSegment;
-
- protected int selectionStart;
- protected int selectionStartLine;
- 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;
-
- protected int magicCaret;
- protected boolean overwrite;
- protected boolean rectSelect;
-
-
- protected void fireCaretEvent()
- {
- Object[] listeners = eventListenerList.getListenerList();
- for(int i = listeners.length - 2; i >= 0; i--)
- {
- if(listeners[i] == CaretListener.class)
- {
- ((CaretListener)listeners[i+1]).caretUpdate(caretEvent);
- }
- }
- }
-
- protected void updateBracketHighlight(int newCaretPosition)
- {
- if(newCaretPosition == 0)
- {
- bracketPosition = bracketLine = -1;
- return;
- }
-
- try
- {
- int offset = TextUtilities.findMatchingBracket(
- document,newCaretPosition - 1);
- if(offset != -1)
- {
- bracketLine = getLineOfOffset(offset);
- bracketPosition = offset - getLineStartOffset(bracketLine);
- return;
- }
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- }
-
- bracketLine = bracketPosition = -1;
- }
-
- protected void documentChanged(DocumentEvent evt)
- {
- DocumentEvent.ElementChange ch =
- evt.getChange(document.getDefaultRootElement());
-
- int count;
- if(ch == null)
- count = 0;
- else
- count = ch.getChildrenAdded().length -
- ch.getChildrenRemoved().length;
-
- int line = getLineOfOffset(evt.getOffset());
- if(count == 0)
- {
- painter.invalidateLine(line);
- }
- // do magic stuff
- else if(line < firstLine)
- {
- setFirstLine(firstLine + count);
- }
- // end of magic stuff
- else
- {
- painter.invalidateLineRange(line,firstLine + visibleLines);
- updateScrollBars();
- }
- }
-
- class ScrollLayout implements LayoutManager
- {
- //final int LEFT_EXTRA = 5;
-
- public void addLayoutComponent(String name, Component comp)
- {
- if(name.equals(LEFT))
- left = comp;
- else if(name.equals(CENTER))
- center = comp;
- else if(name.equals(RIGHT))
- right = comp;
- else if(name.equals(BOTTOM))
- bottom = comp;
- else if(name.equals(LEFT_OF_SCROLLBAR))
- leftOfScrollBar.addElement(comp);
- }
-
- public void removeLayoutComponent(Component comp)
- {
- if(left == comp)
- left = null;
- if(center == comp)
- center = null;
- if(right == comp)
- right = null;
- if(bottom == comp)
- bottom = null;
- else
- leftOfScrollBar.removeElement(comp);
- }
-
- public Dimension preferredLayoutSize(Container parent)
- {
- Dimension dim = new Dimension();
- Insets insets = getInsets();
- dim.width = insets.left + insets.right;
- dim.height = insets.top + insets.bottom;
-
- Dimension centerPref = center.getPreferredSize();
- dim.width += centerPref.width;
- dim.height += centerPref.height;
- Dimension leftPref = left.getPreferredSize();
- dim.width += leftPref.width;
- Dimension rightPref = right.getPreferredSize();
- dim.width += rightPref.width;
- Dimension bottomPref = bottom.getPreferredSize();
- dim.height += bottomPref.height;
-
- return dim;
- }
-
- public Dimension minimumLayoutSize(Container parent)
- {
- Dimension dim = new Dimension();
- Insets insets = getInsets();
- dim.width = insets.left + insets.right;
- dim.height = insets.top + insets.bottom;
-
- Dimension centerPref = center.getMinimumSize();
- dim.width += centerPref.width;
- dim.height += centerPref.height;
- Dimension leftPref = left.getMinimumSize();
- dim.width += leftPref.width;
- Dimension rightPref = right.getMinimumSize();
- dim.width += rightPref.width;
- Dimension bottomPref = bottom.getMinimumSize();
- dim.height += bottomPref.height;
-
- dim.height += 5;
-
- return dim;
- }
-
- public void layoutContainer(Container parent)
- {
- Dimension size = parent.getSize();
- Insets insets = parent.getInsets();
- int itop = insets.top;
- int ileft = insets.left;
- int ibottom = insets.bottom;
- int iright = insets.right;
-
- int leftWidth = left.getSize().width;
- int rightWidth = right.getPreferredSize().width;
- int bottomHeight = bottom.getPreferredSize().height;
- int centerWidth = size.width - leftWidth - rightWidth - ileft - iright;
- int centerHeight = size.height - bottomHeight - itop - ibottom;
-
- left.setBounds(ileft,
- itop,
- leftWidth,
- centerHeight);
-
- ileft += leftWidth;
-
- center.setBounds(ileft, // + LEFT_EXTRA,
- itop,
- centerWidth, // - LEFT_EXTRA,
- centerHeight);
-
- right.setBounds(ileft + centerWidth,
- itop,
- rightWidth,
- centerHeight);
-
- // Lay out all status components, in order
- Enumeration status = leftOfScrollBar.elements();
- while (status.hasMoreElements()) {
- Component comp = (Component)status.nextElement();
- Dimension dim = comp.getPreferredSize();
- comp.setBounds(ileft,
- itop + centerHeight,
- dim.width,
- bottomHeight);
- ileft += dim.width;
- }
-
- bottom.setBounds(ileft,
- itop + centerHeight,
- size.width - rightWidth - ileft - iright,
- bottomHeight);
- }
-
- // private members
- private Component left;
- private Component center;
- private Component right;
- private Component bottom;
- private Vector leftOfScrollBar = new Vector();
- }
-
- static class CaretBlinker implements ActionListener
- {
- public void actionPerformed(ActionEvent evt)
- {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- if(focusedComponent != null
- && focusedComponent.hasFocus())
- focusedComponent.blinkCaret();
- }
- });
- }
- }
-
- class MutableCaretEvent extends CaretEvent
- {
- MutableCaretEvent()
- {
- super(JEditTextArea.this);
- }
-
- public int getDot()
- {
- return getCaretPosition();
- }
-
- public int getMark()
- {
- return getMarkPosition();
- }
- }
-
-/*
-#ifdef JDK14
- class WheelHandler implements MouseWheelListener {
-
- public void mouseWheelMoved(MouseWheelEvent e) {
- if (!scrollBarsInitialized) return;
-
- int amt = e.getWheelRotation();
- //System.out.println(amt);
- vertical.setValue(vertical.getValue() + amt * wheelMultiplier);
- }
- }
-#endif
-*/
-
- class AdjustHandler implements AdjustmentListener
- {
- public void adjustmentValueChanged(final AdjustmentEvent evt)
- {
- if(!scrollBarsInitialized)
- return;
-
- // If this is not done, mousePressed events accumilate
- // and the result is that scrolling doesn't stop after
- // the mouse is released
- SwingUtilities.invokeLater(new Runnable() {
- public void run()
- {
- if(evt.getAdjustable() == vertical)
- setFirstLine(vertical.getValue());
- else
- setHorizontalOffset(-horizontal.getValue());
- }
- });
- }
- }
-
- class ComponentHandler extends ComponentAdapter
- {
- public void componentResized(ComponentEvent evt)
- {
- recalculateVisibleLines();
- scrollBarsInitialized = true;
- }
- }
-
- class DocumentHandler implements DocumentListener
- {
- public void insertUpdate(DocumentEvent evt)
- {
- documentChanged(evt);
-
- int offset = evt.getOffset();
- int length = evt.getLength();
-
- int newStart;
- int newEnd;
-
- if (selectionStart > offset ||
- (selectionStart == selectionEnd && selectionStart == offset))
- newStart = selectionStart + length;
- else
- newStart = selectionStart;
-
- if(selectionEnd >= offset)
- newEnd = selectionEnd + length;
- else
- newEnd = selectionEnd;
-
- select(newStart,newEnd);
- }
-
- public void removeUpdate(DocumentEvent evt)
- {
- documentChanged(evt);
-
- int offset = evt.getOffset();
- int length = evt.getLength();
-
- int newStart;
- int newEnd;
-
- if(selectionStart > offset)
- {
- if(selectionStart > offset + length)
- newStart = selectionStart - length;
- else
- newStart = offset;
- }
- else
- newStart = selectionStart;
-
- if(selectionEnd > offset)
- {
- if(selectionEnd > offset + length)
- newEnd = selectionEnd - length;
- else
- newEnd = offset;
- }
- else
- newEnd = selectionEnd;
-
- select(newStart,newEnd);
- }
-
- public void changedUpdate(DocumentEvent evt)
- {
- }
- }
-
- class DragHandler implements MouseMotionListener
- {
- public void mouseDragged(MouseEvent evt)
- {
- if (popup != null && popup.isVisible()) return;
-
- 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);
- final Cursor handCursor = new Cursor(Cursor.HAND_CURSOR);
-
- public void mouseMoved(MouseEvent evt) {
- int line = yToLine(evt.getY());
- int offset = xToOffset(line, evt.getX());
- boolean wantHandCursor = checkClickedURL(getLineText(line), offset) != null;
- JComponent src = (JComponent) evt.getSource();
- if (wantHandCursor)
- src.setCursor(handCursor);
- else
- src.setCursor(normalCursor);
- }
- }
-
- class FocusHandler implements FocusListener
- {
- public void focusGained(FocusEvent evt)
- {
- //System.out.println("JEditTextArea: focusGained");
- setCaretVisible(true);
- focusedComponent = JEditTextArea.this;
- }
-
- public void focusLost(FocusEvent evt)
- {
- //System.out.println("JEditTextArea: focusLost");
- setCaretVisible(false);
- focusedComponent = null;
- }
- }
-
- public String checkClickedURL(String line, int offset) {
- String[] parse = SyntaxUtilities.parseCommentUrls(line);
- if (parse==null)
- return null;
- int start = parse[0].length();
- int stop = start + parse[1].length();
- if (offsetstop)
- return null;
- return parse[1];
- }
-
- class MouseHandler extends MouseAdapter
- {
- public void mousePressed(MouseEvent evt)
- {
- requestFocus();
-
- // Focus events not fired sometimes?
- setCaretVisible(true);
- focusedComponent = JEditTextArea.this;
-
- // isPopupTrigger wasn't working for danh on windows
- boolean trigger = (evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0;
- // but it's required for macosx, since control-click does
- // the same thing as a right-mouse click
- if (!trigger && evt.isPopupTrigger()) trigger = true;
-
- if (trigger && (popup != null)) {
- popup.show(painter,evt.getX(),evt.getY());
- return;
- }
-
- // on Linux, middle button pastes selected text
- if ((evt.getModifiers() & InputEvent.BUTTON2_MASK) != 0) {
- Clipboard unixclipboard = getToolkit().getSystemSelection();
- if (unixclipboard != null) {
- Transferable t = unixclipboard.getContents(null);
- if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor)) {
- try {
- String s = (String)t.getTransferData(DataFlavor.stringFlavor);
- s = s.replace('\u00A0', ' ');
- if (editable) setSelectedText(s);
- } catch (Exception e) {
- System.err.println(e);
- e.printStackTrace();
- }
- }
- return;
- }
- }
-
- int line = yToLine(evt.getY());
- int offset = xToOffset(line,evt.getX());
- int dot = getLineStartOffset(line) + offset;
-
- selectLine = false;
- selectWord = false;
-
- switch(evt.getClickCount()) {
-
- case 1:
- doSingleClick(evt,line,offset,dot);
- break;
-
- case 2:
- // It uses the bracket matching stuff, so
- // it can throw a BLE
- try {
- doDoubleClick(evt,line,offset,dot);
- } catch(BadLocationException bl) {
- bl.printStackTrace();
- }
- break;
-
- case 3:
- doTripleClick(evt,line,offset,dot);
- break;
- }
- }
-
-
- private void doSingleClick(MouseEvent evt, int line,
- int offset, int dot) {
- // Check for click on urls
- String clickedURL = checkClickedURL(getLineText(line), offset);
- if (clickedURL != null) {
- Base.openURL(clickedURL);
- return;
- }
-
- if ((evt.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
- rectSelect = (evt.getModifiers() & InputEvent.CTRL_MASK) != 0;
- select(getMarkPosition(),dot);
- } else {
- setCaretPosition(dot);
- }
- }
-
-
- private void doDoubleClick(MouseEvent evt, int line,
- int offset, int dot) throws BadLocationException
- {
- // Ignore empty lines
- if (getLineLength(line) == 0)
- return;
-
- try {
- int bracket = TextUtilities.findMatchingBracket(document,
- Math.max(0,dot - 1));
- if (bracket != -1) {
- int mark = getMarkPosition();
- // Hack
- if (bracket > mark) {
- bracket++;
- mark--;
- }
- select(mark,bracket);
- return;
- }
- } catch(BadLocationException bl) {
- bl.printStackTrace();
- }
-
- setNewSelectionWord( line, offset );
- select(newSelectionStart,newSelectionEnd);
- selectWord = true;
- selectionAncorStart = selectionStart;
- selectionAncorEnd = selectionEnd;
-
- /*
- String lineText = getLineText(line);
- String noWordSep = (String)document.getProperty("noWordSep");
- int wordStart = TextUtilities.findWordStart(lineText,offset,noWordSep);
- int wordEnd = TextUtilities.findWordEnd(lineText,offset,noWordSep);
-
- int lineStart = getLineStartOffset(line);
- select(lineStart + wordStart,lineStart + wordEnd);
- */
- }
-
- private void doTripleClick(MouseEvent evt, int line,
- int offset, int dot)
- {
- selectLine = true;
- select(getLineStartOffset(line),getSafeLineStopOffset(line));
- selectionAncorStart = selectionStart;
- selectionAncorEnd = selectionEnd;
- }
- }
-
- class CaretUndo extends AbstractUndoableEdit
- {
- private int start;
- private int end;
-
- CaretUndo(int start, int end)
- {
- this.start = start;
- this.end = end;
- }
-
- public boolean isSignificant()
- {
- return false;
- }
-
- public String getPresentationName()
- {
- return "caret move";
- }
-
- public void undo() throws CannotUndoException
- {
- super.undo();
-
- select(start,end);
- }
-
- public void redo() throws CannotRedoException
- {
- super.redo();
-
- select(start,end);
- }
-
- public boolean addEdit(UndoableEdit edit)
- {
- if(edit instanceof CaretUndo)
- {
- CaretUndo cedit = (CaretUndo)edit;
- start = cedit.start;
- end = cedit.end;
- cedit.die();
-
- return true;
- }
- else
- return false;
- }
- }
-
- static
- {
- caretTimer = new Timer(500,new CaretBlinker());
- caretTimer.setInitialDelay(500);
- caretTimer.start();
- }
-
- public void setDisplayLineNumbers(boolean displayLineNumbers) {
- editorLineNumbers.setDisplayLineNumbers(displayLineNumbers);
- }
-}
diff --git a/app/src/processing/app/syntax/KeywordMap.java b/app/src/processing/app/syntax/KeywordMap.java
deleted file mode 100644
index 27d225f8c..000000000
--- a/app/src/processing/app/syntax/KeywordMap.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * KeywordMap.java - Fast keyword->id map
- * Copyright (C) 1998, 1999 Slava Pestov
- * Copyright (C) 1999 Mike Dillon
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import javax.swing.text.Segment;
-
-/**
- * A KeywordMap
is similar to a hashtable in that it maps keys
- * to values. However, the `keys' are Swing segments. This allows lookups of
- * text substrings without the overhead of creating a new string object.
- *
- * This class is used by CTokenMarker
to map keywords to ids.
- *
- * @author Slava Pestov, Mike Dillon
- */
-public class KeywordMap
-{
- /**
- * Creates a new KeywordMap
.
- * @param ignoreCase True if keys are case insensitive
- */
- public KeywordMap(boolean ignoreCase)
- {
- this(ignoreCase, 52);
- this.ignoreCase = ignoreCase;
- }
-
- /**
- * Creates a new KeywordMap
.
- * @param ignoreCase True if the keys are case insensitive
- * @param mapLength The number of `buckets' to create.
- * A value of 52 will give good performance for most maps.
- */
- public KeywordMap(boolean ignoreCase, int mapLength)
- {
- this.mapLength = mapLength;
- this.ignoreCase = ignoreCase;
- map = new Keyword[mapLength];
- }
-
- /**
- * Looks up a key.
- * @param text The text segment
- * @param offset The offset of the substring within the text segment
- * @param length The length of the substring
- */
- public byte lookup(Segment text, int offset, int length)
- {
- if(length == 0)
- return Token.NULL;
- Keyword k = map[getSegmentMapKey(text, offset, length)];
- while(k != null)
- {
- if(length != k.keyword.length)
- {
- k = k.next;
- continue;
- }
- if(SyntaxUtilities.regionMatches(ignoreCase,text,offset,
- k.keyword))
- return k.id;
- k = k.next;
- }
- return Token.NULL;
- }
-
- /**
- * Adds a key-value mapping.
- * @param keyword The key
- * @param id The value
- */
- public void add(String keyword, byte id)
- {
- int key = getStringMapKey(keyword);
- map[key] = new Keyword(keyword.toCharArray(),id,map[key]);
- }
-
- /**
- * Returns true if the keyword map is set to be case insensitive,
- * false otherwise.
- */
- public boolean getIgnoreCase()
- {
- return ignoreCase;
- }
-
- /**
- * Sets if the keyword map should be case insensitive.
- * @param ignoreCase True if the keyword map should be case
- * insensitive, false otherwise
- */
- public void setIgnoreCase(boolean ignoreCase)
- {
- this.ignoreCase = ignoreCase;
- }
-
- // protected members
- protected int mapLength;
-
- protected int getStringMapKey(String s)
- {
- return (Character.toUpperCase(s.charAt(0)) +
- Character.toUpperCase(s.charAt(s.length()-1)))
- % mapLength;
- }
-
- protected int getSegmentMapKey(Segment s, int off, int len)
- {
- return (Character.toUpperCase(s.array[off]) +
- Character.toUpperCase(s.array[off + len - 1]))
- % mapLength;
- }
-
- // private members
- class Keyword
- {
- public Keyword(char[] keyword, byte id, Keyword next)
- {
- this.keyword = keyword;
- this.id = id;
- this.next = next;
- }
-
- public char[] keyword;
- public byte id;
- public Keyword next;
- }
-
- private Keyword[] map;
- private boolean ignoreCase;
-}
diff --git a/app/src/processing/app/syntax/PdeKeywords.java b/app/src/processing/app/syntax/PdeKeywords.java
index ccf52531c..3b5a575ce 100644
--- a/app/src/processing/app/syntax/PdeKeywords.java
+++ b/app/src/processing/app/syntax/PdeKeywords.java
@@ -24,106 +24,158 @@
package processing.app.syntax;
-import processing.app.*;
+import cc.arduino.contributions.libraries.ContributedLibrary;
+import org.fife.ui.rsyntaxtextarea.TokenMap;
+import org.fife.ui.rsyntaxtextarea.TokenTypes;
+import processing.app.Base;
+import processing.app.BaseNoGui;
import processing.app.legacy.PApplet;
-import processing.app.packages.Library;
-import java.io.*;
-import java.util.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
-public class PdeKeywords extends CTokenMarker {
+public class PdeKeywords {
- // lookup table for the TokenMarker subclass, handles coloring
- static KeywordMap keywordColoring;
+ private static final Map KNOWN_TOKEN_TYPES = new HashMap();
+ private static final Pattern ALPHA = Pattern.compile("\\w");
- // lookup table that maps keywords to their html reference pages
- static Hashtable keywordToReference;
-
-
- public PdeKeywords() {
- super(false, getKeywords());
+ static {
+ KNOWN_TOKEN_TYPES.put("RESERVED_WORD", TokenTypes.RESERVED_WORD);
+ KNOWN_TOKEN_TYPES.put("RESERVED_WORD_2", TokenTypes.RESERVED_WORD_2);
+ KNOWN_TOKEN_TYPES.put("VARIABLE", TokenTypes.VARIABLE);
+ KNOWN_TOKEN_TYPES.put("OPERATOR", TokenTypes.OPERATOR);
+ KNOWN_TOKEN_TYPES.put("DATA_TYPE", TokenTypes.DATA_TYPE);
+ KNOWN_TOKEN_TYPES.put("LITERAL_BOOLEAN", TokenTypes.LITERAL_BOOLEAN);
+ KNOWN_TOKEN_TYPES.put("LITERAL_CHAR", TokenTypes.LITERAL_CHAR);
}
+ // lookup table for the TokenMarker subclass, handles coloring
+ private final TokenMap keywordTokenType;
+ private final Map keywordOldToken;
+ private final Map keywordTokenTypeAsString;
+
+ // lookup table that maps keywords to their html reference pages
+ private final Map keywordToReference;
+
+ public PdeKeywords() {
+ this.keywordTokenType = new TokenMap();
+ this.keywordOldToken = new HashMap();
+ this.keywordTokenTypeAsString = new HashMap();
+ this.keywordToReference = new HashMap();
+ }
/**
* Handles loading of keywords file.
- *
+ *
* Uses getKeywords() method because that's part of the
* TokenMarker classes.
- *
+ *
* It is recommended that a # sign be used for comments
* inside keywords.txt.
*/
- static public KeywordMap getKeywords() {
- if (keywordColoring == null) {
- try {
- keywordColoring = new KeywordMap(false);
- keywordToReference = new Hashtable();
- getKeywords(Base.getLibStream("keywords.txt"));
- for (Library lib : Base.getLibraries()) {
- File keywords = new File(lib.getFolder(), "keywords.txt");
- if (keywords.exists()) getKeywords(new FileInputStream(keywords));
+ public void reload() {
+ try {
+ parseKeywordsTxt(new File(BaseNoGui.getContentFile("lib"), "keywords.txt"));
+ for (ContributedLibrary lib : Base.getLibraries()) {
+ File keywords = new File(lib.getInstalledFolder(), "keywords.txt");
+ if (keywords.exists()) {
+ parseKeywordsTxt(keywords);
}
- } catch (Exception e) {
- Base.showError("Problem loading keywords",
- "Could not load keywords.txt,\n" +
- "please re-install Arduino.", e);
- System.exit(1);
}
+ } catch (Exception e) {
+ Base.showError("Problem loading keywords", "Could not load keywords.txt,\nplease re-install Arduino.", e);
+ System.exit(1);
}
- return keywordColoring;
}
-
- static private void getKeywords(InputStream input) throws Exception {
- InputStreamReader isr = new InputStreamReader(input);
- BufferedReader reader = new BufferedReader(isr);
- String line = null;
- while ((line = reader.readLine()) != null) {
- //System.out.println("line is " + line);
- // in case there's any garbage on the line
- //if (line.trim().length() == 0) continue;
+ private void parseKeywordsTxt(File input) throws Exception {
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new InputStreamReader(new FileInputStream(input)));
- String pieces[] = PApplet.split(line, '\t');
- if (pieces.length >= 2) {
- //int tab = line.indexOf('\t');
- // any line with no tab is ignored
- // meaning that a comment is any line without a tab
- //if (tab == -1) continue;
+ String line;
+ while ((line = reader.readLine()) != null) {
+ //System.out.println("line is " + line);
+ // in case there's any garbage on the line
+ line = line.trim();
+ if (line.length() == 0 || line.startsWith("#")) {
+ continue;
+ }
+
+ String pieces[] = PApplet.split(line, '\t');
String keyword = pieces[0].trim();
- //String keyword = line.substring(0, tab).trim();
- //String second = line.substring(tab + 1);
- //tab = second.indexOf('\t');
- //String coloring = second.substring(0, tab).trim();
- //String htmlFilename = second.substring(tab + 1).trim();
- String coloring = pieces[1].trim();
- if (coloring.length() > 0 && Character.isDigit(coloring.charAt(coloring.length() - 1))) {
- // text will be KEYWORD or LITERAL
- boolean isKey = (coloring.charAt(0) == 'K');
- // KEYWORD1 -> 0, KEYWORD2 -> 1, etc
- int num = coloring.charAt(coloring.length() - 1) - '1';
- byte id = (byte)
- ((isKey ? Token.KEYWORD1 : Token.LITERAL1) + num);
- //System.out.println("got " + (isKey ? "keyword" : "literal") +
- // (num+1) + " for " + keyword);
- keywordColoring.add(keyword, id);
+ if (pieces.length >= 2) {
+ keywordOldToken.put(keyword, pieces[1]);
}
+
if (pieces.length >= 3) {
- String htmlFilename = pieces[2].trim();
- if (htmlFilename.length() > 0) {
- keywordToReference.put(keyword, htmlFilename);
- }
+ parseHTMLReferenceFileName(pieces[2], keyword);
+ }
+ if (pieces.length >= 4) {
+ parseRSyntaxTextAreaTokenType(pieces[3], keyword);
+ }
+ }
+
+ fillMissingTokenType();
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+
+ }
+
+ private void fillMissingTokenType() {
+ for (Map.Entry oldTokenEntry : keywordOldToken.entrySet()) {
+ String keyword = oldTokenEntry.getKey();
+ if (!keywordTokenTypeAsString.containsKey(keyword)) {
+ if ("KEYWORD1".equals(oldTokenEntry.getValue())) {
+ parseRSyntaxTextAreaTokenType("DATA_TYPE", keyword);
+ } else {
+ parseRSyntaxTextAreaTokenType("FUNCTION", keyword);
}
}
}
- reader.close();
}
+ private void parseRSyntaxTextAreaTokenType(String tokenTypeAsString, String keyword) {
+ if (!ALPHA.matcher(keyword).find()) {
+ return;
+ }
- static public String getReference(String keyword) {
- return (String) keywordToReference.get(keyword);
+ if (KNOWN_TOKEN_TYPES.containsKey(tokenTypeAsString)) {
+ keywordTokenType.put(keyword, KNOWN_TOKEN_TYPES.get(tokenTypeAsString));
+ keywordTokenTypeAsString.put(keyword, tokenTypeAsString);
+ } else {
+ keywordTokenType.put(keyword, TokenTypes.FUNCTION);
+ keywordTokenTypeAsString.put(keyword, "FUNCTION");
+ }
+ }
+
+ private void parseHTMLReferenceFileName(String piece, String keyword) {
+ String htmlFilename = piece.trim();
+ if (htmlFilename.length() > 0) {
+ keywordToReference.put(keyword, htmlFilename);
+ }
+ }
+
+ public String getReference(String keyword) {
+ return keywordToReference.get(keyword);
+ }
+
+ public String getTokenTypeAsString(String keyword) {
+ return keywordTokenTypeAsString.get(keyword);
+ }
+
+ public int getTokenType(char[] array, int start, int end) {
+ return keywordTokenType.get(array, start, end);
}
}
diff --git a/app/src/processing/app/syntax/PdeTextAreaDefaults.java b/app/src/processing/app/syntax/PdeTextAreaDefaults.java
deleted file mode 100644
index 2ff65afa8..000000000
--- a/app/src/processing/app/syntax/PdeTextAreaDefaults.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-
-/*
- PdeTextAreaDefaults - grabs font/color settings for the editor
- Part of the Processing project - http://processing.org
-
- Copyright (c) 2004-06 Ben Fry and Casey Reas
- Copyright (c) 2001-03 Massachusetts Institute of Technology
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-
-package processing.app.syntax;
-
-import processing.app.*;
-import processing.app.helpers.OSUtils;
-
-
-public class PdeTextAreaDefaults extends TextAreaDefaults {
-
- public PdeTextAreaDefaults() {
-
- inputHandler = new DefaultInputHandler();
- //inputHandler.addDefaultKeyBindings(); // 0122
-
- // use option on mac for text edit controls that are ctrl on windows/linux
- String mod = OSUtils.isMacOS() ? "A" : "C";
-
- // right now, ctrl-up/down is select up/down, but mod should be
- // used instead, because the mac expects it to be option(alt)
-
- inputHandler.addKeyBinding("BACK_SPACE", InputHandler.BACKSPACE);
- // for 0122, shift-backspace is delete, for 0176, it's now a preference,
- // to prevent holy warriors from attacking me for it.
- if (Preferences.getBoolean("editor.keys.shift_backspace_is_delete")) {
- inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.DELETE);
- } else {
- inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.BACKSPACE);
- }
-
- inputHandler.addKeyBinding("DELETE", InputHandler.DELETE);
- inputHandler.addKeyBinding("S+DELETE", InputHandler.DELETE);
-
- // the following two were changing for 0122 for better mac/pc compatability
- inputHandler.addKeyBinding(mod+"+BACK_SPACE", InputHandler.BACKSPACE_WORD);
- inputHandler.addKeyBinding(mod+"+DELETE", InputHandler.DELETE_WORD);
-
- // handled by listener, don't bother here
- //inputHandler.addKeyBinding("ENTER", InputHandler.INSERT_BREAK);
- //inputHandler.addKeyBinding("TAB", InputHandler.INSERT_TAB);
-
- inputHandler.addKeyBinding("INSERT", InputHandler.OVERWRITE);
-
- // http://dev.processing.org/bugs/show_bug.cgi?id=162
- // added for 0176, though the bindings do not appear relevant for osx
- if (Preferences.getBoolean("editor.keys.alternative_cut_copy_paste")) {
- inputHandler.addKeyBinding("C+INSERT", InputHandler.CLIPBOARD_COPY);
- inputHandler.addKeyBinding("S+INSERT", InputHandler.CLIPBOARD_PASTE);
- inputHandler.addKeyBinding("S+DELETE", InputHandler.CLIPBOARD_CUT);
- }
-
- // disabling for 0122, not sure what this does
- //inputHandler.addKeyBinding("C+\\", InputHandler.TOGGLE_RECT);
-
- // for 0122, these have been changed for better compatibility
- // HOME and END now mean the beginning/end of the document
- // for 0176 changed this to a preference so that the Mac OS X people
- // can get the "normal" behavior as well if they prefer.
- if (Preferences.getBoolean("editor.keys.home_and_end_travel_far")) {
- inputHandler.addKeyBinding("HOME", InputHandler.DOCUMENT_HOME);
- inputHandler.addKeyBinding("END", InputHandler.DOCUMENT_END);
- inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_DOC_HOME);
- inputHandler.addKeyBinding("S+END", InputHandler.SELECT_DOC_END);
- } else {
- // for 0123 added the proper windows defaults
- inputHandler.addKeyBinding("HOME", InputHandler.HOME);
- inputHandler.addKeyBinding("END", InputHandler.END);
- inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_HOME);
- inputHandler.addKeyBinding("S+END", InputHandler.SELECT_END);
- inputHandler.addKeyBinding("C+HOME", InputHandler.DOCUMENT_HOME);
- inputHandler.addKeyBinding("C+END", InputHandler.DOCUMENT_END);
- inputHandler.addKeyBinding("CS+HOME", InputHandler.SELECT_DOC_HOME);
- inputHandler.addKeyBinding("CS+END", InputHandler.SELECT_DOC_END);
- }
-
- if (OSUtils.isMacOS()) {
- inputHandler.addKeyBinding("M+LEFT", InputHandler.HOME);
- inputHandler.addKeyBinding("M+RIGHT", InputHandler.END);
- inputHandler.addKeyBinding("MS+LEFT", InputHandler.SELECT_HOME); // 0122
- inputHandler.addKeyBinding("MS+RIGHT", InputHandler.SELECT_END); // 0122
- } else {
- inputHandler.addKeyBinding("C+LEFT", InputHandler.HOME); // 0122
- inputHandler.addKeyBinding("C+RIGHT", InputHandler.END); // 0122
- inputHandler.addKeyBinding("CS+HOME", InputHandler.SELECT_HOME); // 0122
- inputHandler.addKeyBinding("CS+END", InputHandler.SELECT_END); // 0122
- }
-
- inputHandler.addKeyBinding("PAGE_UP", InputHandler.PREV_PAGE);
- inputHandler.addKeyBinding("PAGE_DOWN", InputHandler.NEXT_PAGE);
- inputHandler.addKeyBinding("S+PAGE_UP", InputHandler.SELECT_PREV_PAGE);
- inputHandler.addKeyBinding("S+PAGE_DOWN", InputHandler.SELECT_NEXT_PAGE);
-
- inputHandler.addKeyBinding("LEFT", InputHandler.PREV_CHAR);
- inputHandler.addKeyBinding("S+LEFT", InputHandler.SELECT_PREV_CHAR);
- inputHandler.addKeyBinding(mod + "+LEFT", InputHandler.PREV_WORD);
- inputHandler.addKeyBinding(mod + "S+LEFT", InputHandler.SELECT_PREV_WORD);
- inputHandler.addKeyBinding("RIGHT", InputHandler.NEXT_CHAR);
- inputHandler.addKeyBinding("S+RIGHT", InputHandler.SELECT_NEXT_CHAR);
- inputHandler.addKeyBinding(mod + "+RIGHT", InputHandler.NEXT_WORD);
- inputHandler.addKeyBinding(mod + "S+RIGHT", InputHandler.SELECT_NEXT_WORD);
-
- inputHandler.addKeyBinding("UP", InputHandler.PREV_LINE);
- inputHandler.addKeyBinding(mod + "+UP", InputHandler.PREV_LINE); // p5
- inputHandler.addKeyBinding("S+UP", InputHandler.SELECT_PREV_LINE);
- inputHandler.addKeyBinding("DOWN", InputHandler.NEXT_LINE);
- inputHandler.addKeyBinding(mod + "+DOWN", InputHandler.NEXT_LINE); // p5
- inputHandler.addKeyBinding("S+DOWN", InputHandler.SELECT_NEXT_LINE);
-
- inputHandler.addKeyBinding("MS+UP", InputHandler.SELECT_DOC_HOME);
- inputHandler.addKeyBinding("CS+UP", InputHandler.SELECT_DOC_HOME);
- inputHandler.addKeyBinding("MS+DOWN", InputHandler.SELECT_DOC_END);
- inputHandler.addKeyBinding("CS+DOWN", InputHandler.SELECT_DOC_END);
-
- inputHandler.addKeyBinding(mod + "+ENTER", InputHandler.REPEAT);
-
- document = new SyntaxDocument();
- editable = true;
- electricScroll = 3;
-
- cols = 80;
- rows = 15;
-
-
- // moved from SyntaxUtilities
- //DEFAULTS.styles = SyntaxUtilities.getDefaultSyntaxStyles();
-
- styles = new SyntaxStyle[Token.ID_COUNT];
-
- // comments
- styles[Token.COMMENT1] = Theme.getStyle("comment1");
- styles[Token.COMMENT2] = Theme.getStyle("comment2");
-
- // abstract, final, private
- styles[Token.KEYWORD1] = Theme.getStyle("keyword1");
-
- // beginShape, point, line
- styles[Token.KEYWORD2] = Theme.getStyle("keyword2");
-
- // byte, char, short, color
- styles[Token.KEYWORD3] = Theme.getStyle("keyword3");
-
- // constants: null, true, this, RGB, TWO_PI
- styles[Token.LITERAL1] = Theme.getStyle("literal1");
-
- // p5 built in variables: mouseX, width, pixels
- styles[Token.LITERAL2] = Theme.getStyle("literal2");
-
- // ??
- styles[Token.LABEL] = Theme.getStyle("label");
-
- // http://arduino.cc/
- styles[Token.URL] = Theme.getStyle("url");
-
- // + - = /
- styles[Token.OPERATOR] = Theme.getStyle("operator");
-
- // area that's not in use by the text (replaced with tildes)
- styles[Token.INVALID] = Theme.getStyle("invalid");
-
-
- // moved from TextAreaPainter
-
- font = Preferences.getFont("editor.font");
-
- fgcolor = Theme.getColor("editor.fgcolor");
- bgcolor = Theme.getColor("editor.bgcolor");
-
- caretVisible = true;
- caretBlinks = Preferences.getBoolean("editor.caret.blink");
- caretColor = Theme.getColor("editor.caret.color");
-
- selectionColor = Theme.getColor("editor.selection.color");
-
- lineHighlight =
- Theme.getBoolean("editor.linehighlight");
- lineHighlightColor =
- Theme.getColor("editor.linehighlight.color");
-
- bracketHighlight =
- Theme.getBoolean("editor.brackethighlight");
- bracketHighlightColor =
- Theme.getColor("editor.brackethighlight.color");
-
- eolMarkers = Theme.getBoolean("editor.eolmarkers");
- eolMarkerColor = Theme.getColor("editor.eolmarkers.color");
-
- paintInvalid = Theme.getBoolean("editor.invalid");
- }
-}
diff --git a/app/src/processing/app/syntax/SketchTextArea.java b/app/src/processing/app/syntax/SketchTextArea.java
new file mode 100644
index 000000000..580fe99f7
--- /dev/null
+++ b/app/src/processing/app/syntax/SketchTextArea.java
@@ -0,0 +1,474 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.syntax;
+
+import org.fife.ui.rsyntaxtextarea.*;
+import org.fife.ui.rsyntaxtextarea.Theme;
+import org.fife.ui.rsyntaxtextarea.Token;
+import org.fife.ui.rsyntaxtextarea.focusabletip.FocusableTip;
+import org.fife.ui.rtextarea.RTextArea;
+import org.fife.ui.rtextarea.RTextAreaUI;
+import org.fife.ui.rtextarea.RUndoManager;
+import processing.app.*;
+
+import javax.swing.*;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.event.HyperlinkListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Segment;
+import javax.swing.undo.UndoManager;
+import java.awt.*;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * Arduino Sketch code editor based on RSyntaxTextArea (http://fifesoft.com/rsyntaxtextarea)
+ *
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 20/04/2015
+ * @since 1.6.4
+ */
+public class SketchTextArea extends RSyntaxTextArea {
+
+ private final static Logger LOG = Logger.getLogger(SketchTextArea.class.getName());
+
+ /**
+ * The last docTooltip displayed.
+ */
+ private FocusableTip docTooltip;
+
+ private EditorListener editorListener;
+
+ private final PdeKeywords pdeKeywords;
+
+ public SketchTextArea(PdeKeywords pdeKeywords) throws IOException {
+ this.pdeKeywords = pdeKeywords;
+ installFeatures();
+ }
+
+ protected void installFeatures() throws IOException {
+ setTheme(PreferencesData.get("editor.syntax_theme", "default"));
+
+ setLinkGenerator(new DocLinkGenerator(pdeKeywords));
+
+ fixControlTab();
+
+ setSyntaxEditingStyle(SYNTAX_STYLE_CPLUSPLUS);
+ }
+
+ public void setTheme(String name) throws IOException {
+ FileInputStream defaultXmlInputStream = null;
+ try {
+ defaultXmlInputStream = new FileInputStream(new File(BaseNoGui.getContentFile("lib"), "theme/syntax/" + name + ".xml"));
+ Theme theme = Theme.load(defaultXmlInputStream);
+ theme.apply(this);
+ } finally {
+ if (defaultXmlInputStream != null) {
+ defaultXmlInputStream.close();
+ }
+ }
+
+ setForeground(processing.app.Theme.getColor("editor.fgcolor"));
+ setBackground(processing.app.Theme.getColor("editor.bgcolor"));
+ setCurrentLineHighlightColor(processing.app.Theme.getColor("editor.linehighlight.color"));
+ setCaretColor(processing.app.Theme.getColor("editor.caret.color"));
+ setSelectedTextColor(null);
+ setUseSelectedTextColor(false);
+ setSelectionColor(processing.app.Theme.getColor("editor.selection.color"));
+ setMatchedBracketBorderColor(processing.app.Theme.getColor("editor.brackethighlight.color"));
+ setHyperlinkForeground((Color) processing.app.Theme.getStyledFont("url", getFont()).get("color"));
+
+ setSyntaxTheme(TokenTypes.DATA_TYPE, "data_type");
+ setSyntaxTheme(TokenTypes.FUNCTION, "function");
+ setSyntaxTheme(TokenTypes.RESERVED_WORD, "reserved_word");
+ setSyntaxTheme(TokenTypes.RESERVED_WORD_2, "reserved_word_2");
+ setSyntaxTheme(TokenTypes.VARIABLE, "variable");
+ setSyntaxTheme(TokenTypes.OPERATOR, "operator");
+ setSyntaxTheme(TokenTypes.COMMENT_DOCUMENTATION, "comment1");
+ setSyntaxTheme(TokenTypes.COMMENT_EOL, "comment1");
+ setSyntaxTheme(TokenTypes.COMMENT_KEYWORD, "comment1");
+ setSyntaxTheme(TokenTypes.COMMENT_MARKUP, "comment1");
+ setSyntaxTheme(TokenTypes.LITERAL_CHAR, "literal_char");
+ setSyntaxTheme(TokenTypes.LITERAL_STRING_DOUBLE_QUOTE, "literal_string_double_quote");
+ }
+
+ private void setSyntaxTheme(int tokenType, String id) {
+ Style style = getSyntaxScheme().getStyle(tokenType);
+
+ Map styledFont = processing.app.Theme.getStyledFont(id, style.font);
+ style.foreground = (Color) styledFont.get("color");
+ style.font = (Font) styledFont.get("font");
+
+ getSyntaxScheme().setStyle(tokenType, style);
+ }
+
+ // Removing the default focus traversal keys
+ // This is because the DefaultKeyboardFocusManager handles the keypress and consumes the event
+ protected void fixControlTab() {
+ removeCTRLTabFromFocusTraversal();
+
+ removeCTRLSHIFTTabFromFocusTraversal();
+ }
+
+ private void removeCTRLSHIFTTabFromFocusTraversal() {
+ KeyStroke ctrlShiftTab = KeyStroke.getKeyStroke("ctrl shift TAB");
+ Set backwardKeys = new HashSet(this.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
+ backwardKeys.remove(ctrlShiftTab);
+ }
+
+ private void removeCTRLTabFromFocusTraversal() {
+ KeyStroke ctrlTab = KeyStroke.getKeyStroke("ctrl TAB");
+ Set forwardKeys = new HashSet(this.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
+ forwardKeys.remove(ctrlTab);
+ this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);
+ }
+
+
+ @Override
+ public void select(int selectionStart, int selectionEnd) {
+ super.select(selectionStart, selectionEnd);
+ }
+
+ public boolean isSelectionActive() {
+ return this.getSelectedText() != null;
+ }
+
+ public void setSelectedText(String text) {
+
+ int old = getTextMode();
+ setTextMode(OVERWRITE_MODE);
+ replaceSelection(text);
+ setTextMode(old);
+
+ }
+
+ public void processKeyEvent(KeyEvent evt) {
+
+ // this had to be added because the menu key events weren't making it up to the frame.
+
+ switch (evt.getID()) {
+ case KeyEvent.KEY_TYPED:
+ if (editorListener != null) editorListener.keyTyped(evt);
+ break;
+ case KeyEvent.KEY_PRESSED:
+ if (editorListener != null) editorListener.keyPressed(evt);
+ break;
+ case KeyEvent.KEY_RELEASED:
+ // inputHandler.keyReleased(evt);
+ break;
+ }
+
+ if (!evt.isConsumed()) {
+ super.processKeyEvent(evt);
+ }
+ }
+
+ public void switchDocument(Document document, UndoManager newUndo) {
+
+ // HACK: Dont discard changes on curret UndoManager.
+ // BUG: https://github.com/bobbylight/RSyntaxTextArea/issues/84
+ setUndoManager(null); // bypass reset current undo manager...
+
+ super.setDocument(document);
+
+ setUndoManager((RUndoManager) newUndo);
+
+ // HACK: Complement previous hack (hide code folding on switch) | Drawback: Lose folding state
+// if(sketch.getCodeCount() > 1 && textarea.isCodeFoldingEnabled()){
+// textarea.setCodeFoldingEnabled(false);
+// textarea.setCodeFoldingEnabled(true);
+// }
+
+
+ }
+
+ @Override
+ protected JPopupMenu createPopupMenu() {
+ JPopupMenu menu = super.createPopupMenu();
+ return menu;
+ }
+
+ @Override
+ protected void configurePopupMenu(JPopupMenu popupMenu) {
+ super.configurePopupMenu(popupMenu);
+ }
+
+ @Override
+ protected RTAMouseListener createMouseListener() {
+ return new SketchTextAreaMouseListener(this);
+ }
+
+ public void getTextLine(int line, Segment segment) {
+ try {
+ int offset = getLineStartOffset(line);
+ int end = getLineEndOffset(line);
+ getDocument().getText(offset, end - offset, segment);
+ } catch (BadLocationException e) {
+ }
+ }
+
+ public String getTextLine(int line) {
+ try {
+ int offset = getLineStartOffset(line);
+ int end = getLineEndOffset(line);
+ return getDocument().getText(offset, end - offset);
+ } catch (BadLocationException e) {
+ return null;
+ }
+ }
+
+
+ public void setEditorListener(EditorListener editorListener) {
+ this.editorListener = editorListener;
+ }
+
+ private static class DocLinkGenerator implements LinkGenerator {
+
+ private final PdeKeywords pdeKeywords;
+
+ public DocLinkGenerator(PdeKeywords pdeKeywords) {
+ this.pdeKeywords = pdeKeywords;
+ }
+
+ @Override
+ public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, final int offs) {
+
+ final Token token = textArea.modelToToken(offs);
+
+ final String reference = pdeKeywords.getReference(token.getLexeme());
+
+ // LOG.fine("reference: " + reference + ", match: " + (token.getType() == TokenTypes.DATA_TYPE || token.getType() == TokenTypes.VARIABLE || token.getType() == TokenTypes.FUNCTION));
+
+ if (token != null && (reference != null || (token.getType() == TokenTypes.DATA_TYPE || token.getType() == TokenTypes.VARIABLE || token.getType() == TokenTypes.FUNCTION))) {
+
+ LinkGeneratorResult generatorResult = new LinkGeneratorResult() {
+
+ @Override
+ public int getSourceOffset() {
+ return offs;
+ }
+
+ @Override
+ public HyperlinkEvent execute() {
+
+ LOG.fine("Open Reference: " + reference);
+
+ Base.showReference("Reference/" + reference);
+
+ return null;
+ }
+ };
+
+ return generatorResult;
+ }
+
+ return null;
+ }
+ }
+
+
+ /**
+ * Handles http hyperlinks.
+ * NOTE (@Ricardo JL Rufino): Workaround to enable hyperlinks by default: https://github.com/bobbylight/RSyntaxTextArea/issues/119
+ */
+ private class SketchTextAreaMouseListener extends RTextAreaMutableCaretEvent {
+
+ private Insets insets;
+ private boolean isScanningForLinks;
+ private int hoveredOverLinkOffset = -1;
+
+ protected SketchTextAreaMouseListener(RTextArea textArea) {
+ super(textArea);
+ insets = new Insets(0, 0, 0, 0);
+ }
+
+ /**
+ * Notifies all listeners that have registered interest for notification
+ * on this event type. The listener list is processed last to first.
+ *
+ * @param e The event to fire.
+ * @see EventListenerList
+ */
+ private void fireHyperlinkUpdate(HyperlinkEvent e) {
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length - 2; i >= 0; i -= 2) {
+ if (listeners[i] == HyperlinkListener.class) {
+ ((HyperlinkListener) listeners[i + 1]).hyperlinkUpdate(e);
+ }
+ }
+ }
+
+ private HyperlinkEvent createHyperlinkEvent(MouseEvent e) {
+ HyperlinkEvent he = null;
+
+ Token t = viewToToken(e.getPoint());
+ if (t != null) {
+ // Copy token, viewToModel() unfortunately modifies Token
+ t = new TokenImpl(t);
+ }
+
+ if (t != null && t.isHyperlink()) {
+ URL url = null;
+ String desc = null;
+ try {
+ String temp = t.getLexeme();
+ // URI's need "http://" prefix for web URL's to work.
+ if (temp.startsWith("www.")) {
+ temp = "http://" + temp;
+ }
+ url = new URL(temp);
+ } catch (MalformedURLException mue) {
+ desc = mue.getMessage();
+ }
+ he = new HyperlinkEvent(SketchTextArea.this, HyperlinkEvent.EventType.ACTIVATED, url, desc);
+ }
+
+ return he;
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (getHyperlinksEnabled()) {
+ HyperlinkEvent he = createHyperlinkEvent(e);
+ if (he != null) {
+ fireHyperlinkUpdate(he);
+ }
+ }
+ }
+
+ @Override
+ public void mouseMoved(MouseEvent e) {
+
+ super.mouseMoved(e);
+
+ if (!getHyperlinksEnabled()) {
+ return;
+ }
+
+// LinkGenerator linkGenerator = getLinkGenerator();
+
+ // GitHub issue RSyntaxTextArea/#25 - links identified at "edges" of editor
+ // should not be activated if mouse is in margin insets.
+ insets = getInsets(insets);
+ if (insets != null) {
+ int x = e.getX();
+ int y = e.getY();
+ if (x <= insets.left || y < insets.top) {
+ if (isScanningForLinks) {
+ stopScanningForLinks();
+ }
+ return;
+ }
+ }
+
+ isScanningForLinks = true;
+ Token t = viewToToken(e.getPoint());
+ if (t != null) {
+ // Copy token, viewToModel() unfortunately modifies Token
+ t = new TokenImpl(t);
+ }
+ Cursor c2 = null;
+ if (t != null && t.isHyperlink()) {
+ if (hoveredOverLinkOffset == -1 ||
+ hoveredOverLinkOffset != t.getOffset()) {
+ hoveredOverLinkOffset = t.getOffset();
+ repaint();
+ }
+ c2 = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
+ }
+// else if (t!=null && linkGenerator!=null) {
+// int offs = viewToModel(e.getPoint());
+// LinkGeneratorResult newResult = linkGenerator.
+// isLinkAtOffset(SketchTextArea.this, offs);
+// if (newResult!=null) {
+// // Repaint if we're at a new link now.
+// if (linkGeneratorResult==null ||
+// !equal(newResult, linkGeneratorResult)) {
+// repaint();
+// }
+// linkGeneratorResult = newResult;
+// hoveredOverLinkOffset = t.getOffset();
+// c2 = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
+// }
+// else {
+// // Repaint if we've moved off of a link.
+// if (linkGeneratorResult!=null) {
+// repaint();
+// }
+// c2 = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
+// hoveredOverLinkOffset = -1;
+// linkGeneratorResult = null;
+// }
+// }
+ else {
+ c2 = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
+ hoveredOverLinkOffset = -1;
+ // linkGeneratorResult = null;
+ }
+ if (getCursor() != c2) {
+ setCursor(c2);
+ // TODO: Repaint just the affected line(s).
+ repaint(); // Link either left or went into.
+ }
+ }
+
+ private void stopScanningForLinks() {
+ if (isScanningForLinks) {
+ Cursor c = getCursor();
+ isScanningForLinks = false;
+ if (c != null && c.getType() == Cursor.HAND_CURSOR) {
+ setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+ repaint(); // TODO: Repaint just the affected line.
+ }
+ }
+ }
+
+ }
+
+ @Override
+ protected RTextAreaUI createRTextAreaUI() {
+ return new SketchTextAreaUI(this);
+ }
+}
diff --git a/app/src/processing/app/syntax/SketchTextAreaDefaultInputMap.java b/app/src/processing/app/syntax/SketchTextAreaDefaultInputMap.java
new file mode 100644
index 000000000..5d806f4c9
--- /dev/null
+++ b/app/src/processing/app/syntax/SketchTextAreaDefaultInputMap.java
@@ -0,0 +1,43 @@
+package processing.app.syntax;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaDefaultInputMap;
+import org.fife.ui.rtextarea.RTextArea;
+import org.fife.ui.rtextarea.RTextAreaEditorKit;
+import processing.app.PreferencesData;
+
+import javax.swing.*;
+import javax.swing.text.DefaultEditorKit;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+public class SketchTextAreaDefaultInputMap extends RSyntaxTextAreaDefaultInputMap {
+
+ public SketchTextAreaDefaultInputMap() {
+ int defaultModifier = getDefaultModifier();
+ int alt = InputEvent.ALT_MASK;
+ boolean isOSX = RTextArea.isOSX();
+ int moveByWordMod = isOSX ? alt : defaultModifier;
+
+ remove(KeyStroke.getKeyStroke(KeyEvent.VK_K, defaultModifier));
+
+ if (PreferencesData.getBoolean("editor.advanced")) {
+ put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, alt), RTextAreaEditorKit.rtaLineDownAction);
+ put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, alt), RTextAreaEditorKit.rtaLineUpAction);
+ } else {
+ remove(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, alt));
+ remove(KeyStroke.getKeyStroke(KeyEvent.VK_UP, alt));
+ }
+
+ remove(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, defaultModifier));
+ put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, moveByWordMod), RTextAreaEditorKit.rtaDeletePrevWordAction);
+
+ if (isOSX) {
+ put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, defaultModifier), SketchTextAreaEditorKit.rtaDeleteLineToCursorAction);
+
+ put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, defaultModifier), DefaultEditorKit.beginAction);
+ put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, defaultModifier), DefaultEditorKit.endAction);
+
+ remove(KeyStroke.getKeyStroke(KeyEvent.VK_J, defaultModifier));
+ }
+ }
+}
diff --git a/app/src/processing/app/syntax/SketchTextAreaEditorKit.java b/app/src/processing/app/syntax/SketchTextAreaEditorKit.java
new file mode 100644
index 000000000..b31bfcb2e
--- /dev/null
+++ b/app/src/processing/app/syntax/SketchTextAreaEditorKit.java
@@ -0,0 +1,103 @@
+package processing.app.syntax;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
+import org.fife.ui.rtextarea.RTextArea;
+import org.fife.ui.rtextarea.RecordableTextAction;
+
+import javax.swing.*;
+import javax.swing.text.*;
+import java.awt.event.ActionEvent;
+
+public class SketchTextAreaEditorKit extends RSyntaxTextAreaEditorKit {
+
+ public static final String rtaDeleteNextWordAction = "RTA.DeleteNextWordAction";
+ public static final String rtaDeleteLineToCursorAction = "RTA.DeleteLineToCursorAction";
+
+ private static final Action[] defaultActions = {
+ new DeleteNextWordAction(),
+ new DeleteLineToCursorAction()
+ };
+
+ @Override
+ public Action[] getActions() {
+ return TextAction.augmentList(super.getActions(), SketchTextAreaEditorKit.defaultActions);
+ }
+
+ public static class DeleteNextWordAction extends RecordableTextAction {
+
+ public DeleteNextWordAction() {
+ super(rtaDeleteNextWordAction);
+ }
+
+ @Override
+ public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
+ if (!textArea.isEditable() || !textArea.isEnabled()) {
+ UIManager.getLookAndFeel().provideErrorFeedback(textArea);
+ return;
+ }
+ try {
+ int start = textArea.getSelectionStart();
+ int end = getNextWordStart(textArea, start);
+ if (end > start) {
+ textArea.getDocument().remove(start, end - start);
+ }
+ } catch (BadLocationException ex) {
+ UIManager.getLookAndFeel().provideErrorFeedback(textArea);
+ }
+ }
+
+ @Override
+ public String getMacroID() {
+ return rtaDeleteNextWordAction;
+ }
+
+ /**
+ * Returns the starting offset to delete. Exists so subclasses can
+ * override.
+ */
+ protected int getNextWordStart(RTextArea textArea, int end)
+ throws BadLocationException {
+ return Utilities.getNextWord(textArea, end);
+ }
+
+ }
+
+ public static class DeleteLineToCursorAction extends RecordableTextAction {
+
+ public DeleteLineToCursorAction() {
+ super(rtaDeleteLineToCursorAction);
+ }
+
+ @Override
+ public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
+ if (!textArea.isEditable() || !textArea.isEnabled()) {
+ UIManager.getLookAndFeel().provideErrorFeedback(textArea);
+ return;
+ }
+ try {
+
+ // We use the elements instead of calling getLineOfOffset(),
+ // etc. to speed things up just a tad (i.e. micro-optimize).
+ Document document = textArea.getDocument();
+ int caretPosition = textArea.getCaretPosition();
+ Element map = document.getDefaultRootElement();
+ int currentLineNum = map.getElementIndex(caretPosition);
+ Element currentLineElement = map.getElement(currentLineNum);
+ int currentLineStart = currentLineElement.getStartOffset();
+ if (caretPosition > currentLineStart) {
+ document.remove(currentLineStart, caretPosition - currentLineStart);
+ }
+
+ } catch (BadLocationException ble) {
+ ble.printStackTrace();
+ }
+ }
+
+ @Override
+ public String getMacroID() {
+ return rtaDeleteLineToCursorAction;
+ }
+
+ }
+
+}
diff --git a/app/src/processing/app/syntax/SketchTextAreaUI.java b/app/src/processing/app/syntax/SketchTextAreaUI.java
new file mode 100644
index 000000000..7ae86a102
--- /dev/null
+++ b/app/src/processing/app/syntax/SketchTextAreaUI.java
@@ -0,0 +1,21 @@
+package processing.app.syntax;
+
+import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaUI;
+
+import javax.swing.*;
+import javax.swing.text.EditorKit;
+import javax.swing.text.JTextComponent;
+
+public class SketchTextAreaUI extends RSyntaxTextAreaUI {
+
+ private static final EditorKit defaultKit = new SketchTextAreaEditorKit();
+
+ public SketchTextAreaUI(JComponent rSyntaxTextArea) {
+ super(rSyntaxTextArea);
+ }
+
+ @Override
+ public EditorKit getEditorKit(JTextComponent tc) {
+ return defaultKit;
+ }
+}
diff --git a/app/src/processing/app/syntax/SketchTokenMaker.java b/app/src/processing/app/syntax/SketchTokenMaker.java
new file mode 100644
index 000000000..92f105bc5
--- /dev/null
+++ b/app/src/processing/app/syntax/SketchTokenMaker.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.syntax;
+
+import org.fife.ui.rsyntaxtextarea.modes.CPlusPlusTokenMaker;
+
+import java.util.Arrays;
+
+/**
+ * Controls the syntax highlighting of {@link SketchTextArea} based on the {@link PdeKeywords}
+ *
+ * @author Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * @date 20/04/2015
+ * @since 1.6.4
+ */
+public class SketchTokenMaker extends CPlusPlusTokenMaker {
+
+ private final PdeKeywords pdeKeywords;
+
+ public SketchTokenMaker(PdeKeywords pdeKeywords) {
+ this.pdeKeywords = pdeKeywords;
+ }
+
+ @Override
+ public void addToken(char[] array, int start, int end, int tokenType, int startOffset, boolean hyperlink) {
+ // This assumes all of your extra tokens would normally be scanned as IDENTIFIER.
+ int newType = pdeKeywords.getTokenType(array, start, end);
+ if (newType > -1) {
+ tokenType = newType;
+ }
+ super.addToken(array, start, end, tokenType, startOffset, hyperlink);
+ }
+
+}
diff --git a/app/src/processing/app/syntax/SyntaxDocument.java b/app/src/processing/app/syntax/SyntaxDocument.java
deleted file mode 100644
index 2a1c3103c..000000000
--- a/app/src/processing/app/syntax/SyntaxDocument.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * SyntaxDocument.java - Document that can be tokenized
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import javax.swing.event.*;
-import javax.swing.text.*;
-import javax.swing.undo.UndoableEdit;
-
-/**
- * A document implementation that can be tokenized by the syntax highlighting
- * system.
- *
- * @author Slava Pestov
- */
-public class SyntaxDocument extends PlainDocument
-{
- /**
- * Returns the token marker that is to be used to split lines
- * of this document up into tokens. May return null if this
- * document is not to be colorized.
- */
- public TokenMarker getTokenMarker()
- {
- return tokenMarker;
- }
-
- /**
- * Sets the token marker that is to be used to split lines of
- * this document up into tokens. May throw an exception if
- * this is not supported for this type of document.
- * @param tm The new token marker
- */
- public void setTokenMarker(TokenMarker tm)
- {
- tokenMarker = tm;
- if(tm == null)
- return;
- tokenMarker.insertLines(0,getDefaultRootElement()
- .getElementCount());
- tokenizeLines();
- }
-
- /**
- * Reparses the document, by passing all lines to the token
- * marker. This should be called after the document is first
- * loaded.
- */
- public void tokenizeLines()
- {
- tokenizeLines(0,getDefaultRootElement().getElementCount());
- }
-
- /**
- * Reparses the document, by passing the specified lines to the
- * token marker. This should be called after a large quantity of
- * text is first inserted.
- * @param start The first line to parse
- * @param len The number of lines, after the first one to parse
- */
- public void tokenizeLines(int start, int len)
- {
- if(tokenMarker == null || !tokenMarker.supportsMultilineTokens())
- return;
-
- Segment lineSegment = new Segment();
- Element map = getDefaultRootElement();
-
- len += start;
-
- try
- {
- for(int i = start; i < len; i++)
- {
- Element lineElement = map.getElement(i);
- int lineStart = lineElement.getStartOffset();
- getText(lineStart,lineElement.getEndOffset()
- - lineStart - 1,lineSegment);
- tokenMarker.markTokens(lineSegment,i);
- }
- }
- catch(BadLocationException bl)
- {
- bl.printStackTrace();
- }
- }
-
- /**
- * Starts a compound edit that can be undone in one operation.
- * Subclasses that implement undo should override this method;
- * this class has no undo functionality so this method is
- * empty.
- */
- public void beginCompoundEdit() {}
-
- /**
- * Ends a compound edit that can be undone in one operation.
- * Subclasses that implement undo should override this method;
- * this class has no undo functionality so this method is
- * empty.
- */
- public void endCompoundEdit() {}
-
- /**
- * Adds an undoable edit to this document's undo list. The edit
- * should be ignored if something is currently being undone.
- * @param edit The undoable edit
- *
- * @since jEdit 2.2pre1
- */
- public void addUndoableEdit(UndoableEdit edit) {}
-
- // protected members
- protected TokenMarker tokenMarker;
-
- /**
- * We overwrite this method to update the token marker
- * state immediately so that any event listeners get a
- * consistent token marker.
- */
- protected void fireInsertUpdate(DocumentEvent evt)
- {
- if(tokenMarker != null)
- {
- DocumentEvent.ElementChange ch = evt.getChange(
- getDefaultRootElement());
- if(ch != null)
- {
- tokenMarker.insertLines(ch.getIndex() + 1,
- ch.getChildrenAdded().length -
- ch.getChildrenRemoved().length);
- }
- }
-
- super.fireInsertUpdate(evt);
- }
-
- /**
- * We overwrite this method to update the token marker
- * state immediately so that any event listeners get a
- * consistent token marker.
- */
- protected void fireRemoveUpdate(DocumentEvent evt)
- {
- if(tokenMarker != null)
- {
- DocumentEvent.ElementChange ch = evt.getChange(
- getDefaultRootElement());
- if(ch != null)
- {
- tokenMarker.deleteLines(ch.getIndex() + 1,
- ch.getChildrenRemoved().length -
- ch.getChildrenAdded().length);
- }
- }
-
- super.fireRemoveUpdate(evt);
- }
-}
diff --git a/app/src/processing/app/syntax/SyntaxStyle.java b/app/src/processing/app/syntax/SyntaxStyle.java
deleted file mode 100644
index 23a7c71b0..000000000
--- a/app/src/processing/app/syntax/SyntaxStyle.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * SyntaxStyle.java - A simple text style class
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import java.awt.*;
-import java.awt.font.TextAttribute;
-import java.util.Hashtable;
-import java.util.Map;
-
-import javax.swing.JComponent;
-
-
-/**
- * A simple text style class. It can specify the color, italic flag,
- * and bold flag of a run of text.
- * @author Slava Pestov
- */
-public class SyntaxStyle
-{
- /**
- * Creates a new SyntaxStyle.
- * @param color The text color
- * @param italic True if the text should be italics
- * @param bold True if the text should be bold
- */
- public SyntaxStyle(Color color, boolean italic, boolean bold, boolean underlined)
- {
- this.color = color;
- this.italic = italic;
- this.bold = bold;
- this.underlined = underlined;
- }
-
- /**
- * Returns the color specified in this style.
- */
- public Color getColor()
- {
- return color;
- }
-
- /**
- * Returns true if no font styles are enabled.
- */
- public boolean isPlain()
- {
- return !(bold || italic || underlined);
- }
-
- /**
- * Returns true if italics is enabled for this style.
- */
- public boolean isItalic()
- {
- return italic;
- }
-
- /**
- * Returns true if boldface is enabled for this style.
- */
- public boolean isBold()
- {
- return bold;
- }
-
- /**
- * @return true if underline is enabled for this style.
- */
- public boolean isUnderlined() {
- return underlined;
- }
-
- /**
- * Returns the specified font, but with the style's bold, underline and
- * italic flags applied.
- */
- public Font getStyledFont(Font font)
- {
- if(font == null)
- throw new NullPointerException("font param must not"
- + " be null");
- if(font.equals(lastFont))
- return lastStyledFont;
- lastFont = font;
-
- lastStyledFont = new Font(font.getFamily(),
- (bold ? Font.BOLD : 0)
- | (italic ? Font.ITALIC : 0),
- font.getSize());
- if (underlined) {
- Map attr = new Hashtable();
- attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
- lastStyledFont = lastStyledFont.deriveFont(attr);
- }
- return lastStyledFont;
- }
-
- /**
- * Returns the font metrics for the styled font.
- */
- public FontMetrics getFontMetrics(Font font, JComponent comp)
- {
- if(font == null)
- throw new NullPointerException("font param must not"
- + " be null");
- if(font.equals(lastFont) && fontMetrics != null)
- return fontMetrics;
- lastFont = font;
- lastStyledFont = new Font(font.getFamily(),
- (bold ? Font.BOLD : 0)
- | (italic ? Font.ITALIC : 0),
- font.getSize());
- if (underlined) {
- Map attr = new Hashtable();
- attr.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
- lastStyledFont = lastStyledFont.deriveFont(attr);
- }
- //fontMetrics = Toolkit.getDefaultToolkit().getFontMetrics(lastStyledFont);
- fontMetrics = comp.getFontMetrics(lastStyledFont);
- return fontMetrics;
- }
-
- /**
- * Sets the foreground color and font of the specified graphics
- * context to that specified in this style.
- * @param gfx The graphics context
- * @param font The font to add the styles to
- */
- public void setGraphicsFlags(Graphics gfx, Font font)
- {
- Font _font = getStyledFont(font);
- gfx.setFont(_font);
- gfx.setColor(color);
- }
-
- /**
- * Returns a string representation of this object.
- */
- public String toString()
- {
- return getClass().getName() + "[color=" + color +
- (italic ? ",italic" : "") +
- (bold ? ",bold" : "") +
- (underlined ? ",underlined" : "") +
- "]";
- }
-
- // private members
- private Color color;
- private boolean italic;
- private boolean bold;
- private boolean underlined;
- private Font lastFont;
- private Font lastStyledFont;
- private FontMetrics fontMetrics;
-}
diff --git a/app/src/processing/app/syntax/SyntaxUtilities.java b/app/src/processing/app/syntax/SyntaxUtilities.java
deleted file mode 100644
index 6eef977a0..000000000
--- a/app/src/processing/app/syntax/SyntaxUtilities.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * SyntaxUtilities.java - Utility functions used by syntax colorizing
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import javax.swing.text.*;
-import java.awt.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-
-/**
- * Class with several utility functions used by jEdit's syntax colorizing
- * subsystem.
- *
- * @author Slava Pestov
- */
-public class SyntaxUtilities
-{
- /**
- * Checks if a subregion of a Segment
is equal to a
- * string.
- * @param ignoreCase True if case should be ignored, false otherwise
- * @param text The segment
- * @param offset The offset into the segment
- * @param match The string to match
- */
- public static boolean regionMatches(boolean ignoreCase, Segment text,
- int offset, String match)
- {
- int length = offset + match.length();
- char[] textArray = text.array;
- if(length > text.offset + text.count)
- return false;
- for(int i = offset, j = 0; i < length; i++, j++)
- {
- char c1 = textArray[i];
- char c2 = match.charAt(j);
- if(ignoreCase)
- {
- c1 = Character.toUpperCase(c1);
- c2 = Character.toUpperCase(c2);
- }
- if(c1 != c2)
- return false;
- }
- return true;
- }
-
-
- /**
- * Checks if a subregion of a Segment
is equal to a
- * character array.
- * @param ignoreCase True if case should be ignored, false otherwise
- * @param text The segment
- * @param offset The offset into the segment
- * @param match The character array to match
- */
- public static boolean regionMatches(boolean ignoreCase, Segment text,
- int offset, char[] match)
- {
- int length = offset + match.length;
- char[] textArray = text.array;
- if(length > text.offset + text.count)
- return false;
- for(int i = offset, j = 0; i < length; i++, j++)
- {
- char c1 = textArray[i];
- char c2 = match[j];
- if(ignoreCase)
- {
- c1 = Character.toUpperCase(c1);
- c2 = Character.toUpperCase(c2);
- }
- if(c1 != c2)
- return false;
- }
- return true;
- }
-
-
- /**
- * Returns the default style table. This can be passed to the
- * setStyles()
method of SyntaxDocument
- * to use the default syntax styles.
- */
- public static SyntaxStyle[] getDefaultSyntaxStyles()
- {
- SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT];
-
- styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false,false);
- styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false,false);
- styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true,false);
- styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false,false);
- styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false,false);
- styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false,false);
- styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true,false);
- styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true,false);
- styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true,false);
- styles[Token.URL] = new SyntaxStyle(Color.blue,true,false,false);
- styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true,false);
-
- return styles;
- }
-
-
- /**
- * Paints the specified line onto the graphics context. Note that this
- * method munges the offset and count values of the segment.
- * @param line The line segment
- * @param tokens The token list for the line
- * @param styles The syntax style list
- * @param expander The tab expander used to determine tab stops. May
- * be null
- * @param gfx The graphics context
- * @param x The x co-ordinate
- * @param y The y co-ordinate
- * @return The x co-ordinate, plus the width of the painted string
- */
- public static int paintSyntaxLine(Segment line, Token tokens,
- SyntaxStyle[] styles,
- TabExpander expander, Graphics gfx,
- int x, int y)
- {
- Font defaultFont = gfx.getFont();
- Color defaultColor = gfx.getColor();
-
- for(;;)
- {
- byte id = tokens.id;
- if(id == Token.END)
- break;
-
- int length = tokens.length;
- if(id == Token.NULL)
- {
- if(!defaultColor.equals(gfx.getColor()))
- gfx.setColor(defaultColor);
- if(!defaultFont.equals(gfx.getFont()))
- gfx.setFont(defaultFont);
- }
- else
- styles[id].setGraphicsFlags(gfx,defaultFont);
-
- line.count = length;
- if (id == Token.COMMENT1 || id == Token.COMMENT2)
- x = drawTabbedCommentsText(line, x, y, gfx, expander, styles, styles[id]);
- else
- x = Utilities.drawTabbedText(line, x, y, gfx, expander, 0);
- line.offset += length;
-
- tokens = tokens.next;
- }
-
- return x;
- }
-
- /**
- * Parse comments and identify "@schematics <something>" pattern.
- *
- * @param line
- * A string to parse
- * @return null if the pattern is not found, otherwise an array of
- * String is returned: the elements with index 0, 1 and 2 are
- * respectively the preamble, the <something> stuff, and
- * the remaining part of the string.
- */
- public static String[] parseCommentUrls(String line) {
- Matcher m = urlPattern.matcher(line.toString());
- if (!m.find())
- return null;
-
- String res[] = new String[3];
- res[0] = line.substring(0, m.start(1));
- res[1] = line.substring(m.start(1), m.end(1));
- res[2] = line.substring(m.end(1));
- // System.out.println("0 =>"+res[0]+"<\n1 =>"+res[1]+"< \n2 =>"+res[2]+"<");
- return res;
- }
-
- static private Pattern urlPattern = Pattern.compile(
- "((?:https?|ftp)://" + // ( Protocol
- "(?:(?:[\\w_\\-]+:)?[\\w_\\-]+@)?" + // Username and password
- "(?:[\\w_\\-]+\\.)+[\\w_\\-]+" + // Domain name
- "(?::[0-9]{1,5})?" + // Port
- "(?:/[\\w_\\-./?%&=+]*)?)" + // Path )
- "(?:\\s|$)"); // whitespace or EOL
-
- public static Segment stringToSegment(String v) {
- return new Segment(v.toCharArray(), 0, v.length());
- }
-
- private static int drawTabbedCommentsText(Segment line, int x, int y,
- Graphics gfx, TabExpander expander, SyntaxStyle[] styles,
- SyntaxStyle commentStyle) {
-
- String parse[] = parseCommentUrls(line.toString());
- if (parse == null)
- // Revert to plain writing.
- return Utilities.drawTabbedText(line, x, y, gfx, expander, 0);
- Segment pre = stringToSegment(parse[0]);
- Segment tag = stringToSegment(parse[1]);
- Segment post = stringToSegment(parse[2]);
-
- if (pre.count>0)
- x = Utilities.drawTabbedText(pre, x, y, gfx, expander, 0);
-
- Font f = gfx.getFont();
- styles[Token.URL].setGraphicsFlags(gfx, f);
- x = Utilities.drawTabbedText(tag, x, y, gfx, expander, 0);
-
- commentStyle.setGraphicsFlags(gfx, f);
- if (post.count>0)
- x = Utilities.drawTabbedText(post, x, y, gfx, expander, 0);
- return x;
- }
-
- // private members
- private SyntaxUtilities() {}
-}
diff --git a/app/src/processing/app/syntax/TextAreaDefaults.java b/app/src/processing/app/syntax/TextAreaDefaults.java
deleted file mode 100644
index c2e878578..000000000
--- a/app/src/processing/app/syntax/TextAreaDefaults.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * TextAreaDefaults.java - Encapsulates default values for various settings
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import java.awt.*;
-//import javax.swing.JPopupMenu;
-
-/**
- * Encapsulates default settings for a text area. This can be passed
- * to the constructor once the necessary fields have been filled out.
- * The advantage of doing this over calling lots of set() methods after
- * creating the text area is that this method is faster.
- */
-public class TextAreaDefaults
-{
- private static TextAreaDefaults DEFAULTS;
-
- public InputHandler inputHandler;
- public SyntaxDocument document;
- public boolean editable;
-
- public boolean caretVisible;
- public boolean caretBlinks;
- public boolean blockCaret;
- public int electricScroll;
-
- public int cols;
- public int rows;
- public SyntaxStyle[] styles;
- public Color caretColor;
- public Color selectionColor;
- public Color lineHighlightColor;
- public boolean lineHighlight;
- public Color bracketHighlightColor;
- public boolean bracketHighlight;
- public Color eolMarkerColor;
- public boolean eolMarkers;
- public boolean paintInvalid;
-
-
- // moved from TextAreaPainter [fry]
- public Font font;
- public Color fgcolor;
- public Color bgcolor;
-
- //public JPopupMenu popup;
-
-
- /**
- * Returns a new TextAreaDefaults object with the default values filled
- * in.
- */
- public static TextAreaDefaults getDefaults()
- {
- if (DEFAULTS == null) {
- DEFAULTS = new TextAreaDefaults();
-
- DEFAULTS.inputHandler = new DefaultInputHandler();
- DEFAULTS.inputHandler.addDefaultKeyBindings();
- DEFAULTS.document = new SyntaxDocument();
- DEFAULTS.editable = true;
-
- DEFAULTS.caretVisible = true;
- DEFAULTS.caretBlinks = true;
- DEFAULTS.electricScroll = 3;
-
- DEFAULTS.cols = 80;
- DEFAULTS.rows = 25;
- DEFAULTS.styles = SyntaxUtilities.getDefaultSyntaxStyles();
- DEFAULTS.caretColor = Color.red;
- DEFAULTS.selectionColor = new Color(0xccccff);
- DEFAULTS.lineHighlightColor = new Color(0xe0e0e0);
- DEFAULTS.lineHighlight = true;
- DEFAULTS.bracketHighlightColor = Color.black;
- DEFAULTS.bracketHighlight = true;
- DEFAULTS.eolMarkerColor = new Color(0x009999);
- DEFAULTS.eolMarkers = true;
- DEFAULTS.paintInvalid = true;
- }
-
- return DEFAULTS;
- }
-}
diff --git a/app/src/processing/app/syntax/TextAreaLineNumbers.java b/app/src/processing/app/syntax/TextAreaLineNumbers.java
deleted file mode 100644
index 39f7438f2..000000000
--- a/app/src/processing/app/syntax/TextAreaLineNumbers.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * TextAreaLineNumbers.java - Show line numbers for the open file in the editor
- * Copyright (C) 2013 Cayci Gorlitsky
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.Rectangle;
-
-import javax.swing.border.MatteBorder;
-
-public class TextAreaLineNumbers extends TextAreaPainter {
-
- private final int LEFT_INDENT = 6;
- private final int RIGHT_INDENT = 6;
- private final int RIGHT_BORDER_WIDTH = 1;
- private final int PADDING_WIDTH = LEFT_INDENT + RIGHT_INDENT + RIGHT_BORDER_WIDTH;
-
- private final int MIN_WIDTH;
- private final int DIGIT_WIDTH;
- private final int MIN_NUM_DIGITS = 2;
-
- private int currStartNum = 0;
- private int currEndNum = 0;
- private int currNumDigits = MIN_NUM_DIGITS;
-
-
-
- public TextAreaLineNumbers(JEditTextArea textArea, TextAreaDefaults defaults) {
- super(textArea, defaults);
- DIGIT_WIDTH = getFontMetrics(getFont()).stringWidth("0");
- MIN_WIDTH = DIGIT_WIDTH * MIN_NUM_DIGITS + PADDING_WIDTH;
- setEnabled(false);
- setBorder(new MatteBorder(0, 0, 0, RIGHT_BORDER_WIDTH, new Color(240, 240, 240)));
- }
-
- public void updateLineNumbers(int startNum, int endNum) {
- if (currStartNum == startNum && currEndNum == endNum) {
- return;
- }
- currStartNum = startNum;
- currEndNum = endNum;
-
- invalidate();
- repaint();
- }
-
- @Override
- public void paint(Graphics gfx) {
- super.paint(gfx);
- getBorder().paintBorder(this, gfx, 0, 0, getSize().width, getSize().height);
- }
-
- @Override
- protected void paintLine(Graphics gfx, TokenMarker tokenMarker,
- int line, int x)
- {
- currentLineIndex = line;
- gfx.setFont(getFont());
- gfx.setColor(Color.GRAY);
- int y = textArea.lineToY(line);
- int startX = getBounds().x + getBounds().width;
- if (line >= 0 && line < textArea.getLineCount()) {
- String lineNumberString = String.valueOf(line+1);
- int lineStartX = startX - RIGHT_BORDER_WIDTH - RIGHT_INDENT - fm.stringWidth(lineNumberString);
- gfx.drawString(lineNumberString,lineStartX,y + fm.getHeight());
- }
- }
-
- public void updateWidthForNumDigits(int numDigits) {
- if (currNumDigits == numDigits) {
- return;
- }
- currNumDigits = numDigits;
-
- if (isVisible()) {
- updateBounds();
- invalidate();
- repaint();
- }
- }
-
- public void setDisplayLineNumbers(boolean displayLineNumbers) {
- setVisible(displayLineNumbers);
- if (displayLineNumbers) {
- updateBounds();
- } else {
- setBounds(new Rectangle(0, getHeight()));
- }
- invalidate();
- repaint();
- }
-
- private void updateBounds() {
- if (isVisible()) {
- setBounds(new Rectangle(Math.max(MIN_WIDTH, DIGIT_WIDTH * currNumDigits + PADDING_WIDTH), getHeight()));
- textArea.validate();
- }
- }
-}
diff --git a/app/src/processing/app/syntax/TextAreaPainter.java b/app/src/processing/app/syntax/TextAreaPainter.java
deleted file mode 100644
index e99329526..000000000
--- a/app/src/processing/app/syntax/TextAreaPainter.java
+++ /dev/null
@@ -1,787 +0,0 @@
-/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-
-/*
- * TextAreaPainter.java - Paints the text area
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import processing.app.*;
-import processing.app.syntax.im.CompositionTextPainter;
-
-import javax.swing.ToolTipManager;
-import javax.swing.text.*;
-import javax.swing.JComponent;
-import java.awt.event.MouseEvent;
-import java.awt.*;
-import java.awt.print.*;
-
-/**
- * The text area repaint manager. It performs double buffering and paints
- * lines of text.
- * @author Slava Pestov
- */
-public class TextAreaPainter extends JComponent
-implements TabExpander, Printable
-{
- /** True if inside printing, will handle disabling the highlight */
- boolean printing;
- /** Current setting for editor.antialias preference */
- boolean antialias;
-
- /** A specific painter composed by the InputMethod.*/
- protected CompositionTextPainter compositionTextPainter;
-
- /**
- * Creates a new repaint manager. This should be not be called
- * directly.
- */
- public TextAreaPainter(JEditTextArea textArea, TextAreaDefaults defaults)
- {
- this.textArea = textArea;
-
- setAutoscrolls(true);
- setDoubleBuffered(true);
- setOpaque(true);
-
- ToolTipManager.sharedInstance().registerComponent(this);
-
- currentLine = new Segment();
- currentLineIndex = -1;
-
- setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
-
- setFont(defaults.font);
- setForeground(defaults.fgcolor);
- setBackground(defaults.bgcolor);
-
- antialias = Preferences.getBoolean("editor.antialias");
-
- blockCaret = defaults.blockCaret;
- styles = defaults.styles;
- cols = defaults.cols;
- rows = defaults.rows;
- caretColor = defaults.caretColor;
- selectionColor = defaults.selectionColor;
- lineHighlightColor = defaults.lineHighlightColor;
- lineHighlight = defaults.lineHighlight;
- bracketHighlightColor = defaults.bracketHighlightColor;
- bracketHighlight = defaults.bracketHighlight;
- paintInvalid = defaults.paintInvalid;
- eolMarkerColor = defaults.eolMarkerColor;
- eolMarkers = defaults.eolMarkers;
- }
-
- /**
- * Get CompositionTextPainter. if CompositionTextPainter is not created, create it.
- */
- public CompositionTextPainter getCompositionTextpainter(){
- if(compositionTextPainter == null){
- compositionTextPainter = new CompositionTextPainter(textArea);
- }
- return compositionTextPainter;
- }
-
- /**
- * Returns if this component can be traversed by pressing the
- * Tab key. This returns false.
- */
-// public final boolean isManagingFocus()
-// {
-// return false;
-// }
-
- /**
- * Returns the syntax styles used to paint colorized text. Entry n
- * will be used to paint tokens with id = n.
- * @see processing.app.syntax.Token
- */
- public final SyntaxStyle[] getStyles()
- {
- return styles;
- }
-
- /**
- * Sets the syntax styles used to paint colorized text. Entry n
- * will be used to paint tokens with id = n.
- * @param styles The syntax styles
- * @see processing.app.syntax.Token
- */
- public final void setStyles(SyntaxStyle[] styles)
- {
- this.styles = styles;
- repaint();
- }
-
- /**
- * Returns the caret color.
- */
- public final Color getCaretColor()
- {
- return caretColor;
- }
-
- /**
- * Sets the caret color.
- * @param caretColor The caret color
- */
- public final void setCaretColor(Color caretColor)
- {
- this.caretColor = caretColor;
- invalidateSelectedLines();
- }
-
- /**
- * Returns the selection color.
- */
- public final Color getSelectionColor()
- {
- return selectionColor;
- }
-
- /**
- * Sets the selection color.
- * @param selectionColor The selection color
- */
- public final void setSelectionColor(Color selectionColor)
- {
- this.selectionColor = selectionColor;
- invalidateSelectedLines();
- }
-
- /**
- * Returns the line highlight color.
- */
- public final Color getLineHighlightColor()
- {
- return lineHighlightColor;
- }
-
- /**
- * Sets the line highlight color.
- * @param lineHighlightColor The line highlight color
- */
- public final void setLineHighlightColor(Color lineHighlightColor)
- {
- this.lineHighlightColor = lineHighlightColor;
- invalidateSelectedLines();
- }
-
- /**
- * Returns true if line highlight is enabled, false otherwise.
- */
- public final boolean isLineHighlightEnabled()
- {
- return lineHighlight;
- }
-
- /**
- * Enables or disables current line highlighting.
- * @param lineHighlight True if current line highlight
- * should be enabled, false otherwise
- */
- public final void setLineHighlightEnabled(boolean lineHighlight)
- {
- this.lineHighlight = lineHighlight;
- invalidateSelectedLines();
- }
-
- /**
- * Returns the bracket highlight color.
- */
- public final Color getBracketHighlightColor()
- {
- return bracketHighlightColor;
- }
-
- /**
- * Sets the bracket highlight color.
- * @param bracketHighlightColor The bracket highlight color
- */
- public final void setBracketHighlightColor(Color bracketHighlightColor)
- {
- this.bracketHighlightColor = bracketHighlightColor;
- invalidateLine(textArea.getBracketLine());
- }
-
- /**
- * Returns true if bracket highlighting is enabled, false otherwise.
- * When bracket highlighting is enabled, the bracket matching the
- * one before the caret (if any) is highlighted.
- */
- public final boolean isBracketHighlightEnabled()
- {
- return bracketHighlight;
- }
-
- /**
- * Enables or disables bracket highlighting.
- * When bracket highlighting is enabled, the bracket matching the
- * one before the caret (if any) is highlighted.
- * @param bracketHighlight True if bracket highlighting should be
- * enabled, false otherwise
- */
- public final void setBracketHighlightEnabled(boolean bracketHighlight)
- {
- this.bracketHighlight = bracketHighlight;
- invalidateLine(textArea.getBracketLine());
- }
-
- /**
- * Returns true if the caret should be drawn as a block, false otherwise.
- */
- public final boolean isBlockCaretEnabled()
- {
- return blockCaret;
- }
-
- /**
- * Sets if the caret should be drawn as a block, false otherwise.
- * @param blockCaret True if the caret should be drawn as a block,
- * false otherwise.
- */
- public final void setBlockCaretEnabled(boolean blockCaret)
- {
- this.blockCaret = blockCaret;
- invalidateSelectedLines();
- }
-
- /**
- * Returns the EOL marker color.
- */
- public final Color getEOLMarkerColor()
- {
- return eolMarkerColor;
- }
-
- /**
- * Sets the EOL marker color.
- * @param eolMarkerColor The EOL marker color
- */
- public final void setEOLMarkerColor(Color eolMarkerColor)
- {
- this.eolMarkerColor = eolMarkerColor;
- repaint();
- }
-
- /**
- * Returns true if EOL markers are drawn, false otherwise.
- */
- public final boolean getEOLMarkersPainted()
- {
- return eolMarkers;
- }
-
- /**
- * Sets if EOL markers are to be drawn.
- * @param eolMarkers True if EOL markers should be drawn, false otherwise
- */
- public final void setEOLMarkersPainted(boolean eolMarkers)
- {
- this.eolMarkers = eolMarkers;
- repaint();
- }
-
- /**
- * Returns true if invalid lines are painted as red tildes (~),
- * false otherwise.
- */
- public boolean getInvalidLinesPainted()
- {
- return paintInvalid;
- }
-
- /**
- * Sets if invalid lines are to be painted as red tildes.
- * @param paintInvalid True if invalid lines should be drawn, false otherwise
- */
- public void setInvalidLinesPainted(boolean paintInvalid)
- {
- this.paintInvalid = paintInvalid;
- }
-
- /**
- * Adds a custom highlight painter.
- * @param highlight The highlight
- */
- public void addCustomHighlight(Highlight highlight)
- {
- highlight.init(textArea,highlights);
- highlights = highlight;
- }
-
- /**
- * Highlight interface.
- */
- public interface Highlight
- {
- /**
- * Called after the highlight painter has been added.
- * @param textArea The text area
- * @param next The painter this one should delegate to
- */
- void init(JEditTextArea textArea, Highlight next);
-
- /**
- * This should paint the highlight and delgate to the
- * next highlight painter.
- * @param gfx The graphics context
- * @param line The line number
- * @param y The y co-ordinate of the line
- */
- void paintHighlight(Graphics gfx, int line, int y);
-
- /**
- * Returns the tool tip to display at the specified
- * location. If this highlighter doesn't know what to
- * display, it should delegate to the next highlight
- * painter.
- * @param evt The mouse event
- */
- String getToolTipText(MouseEvent evt);
- }
-
- /**
- * Returns the tool tip to display at the specified location.
- * @param evt The mouse event
- */
- public String getToolTipText(MouseEvent evt)
- {
- if(highlights != null)
- return highlights.getToolTipText(evt);
- else
- return null;
- }
-
- /**
- * Returns the font metrics used by this component.
- */
- public FontMetrics getFontMetrics()
- {
- return fm;
- }
-
- /**
- * Sets the font for this component. This is overridden to update the
- * cached font metrics and to recalculate which lines are visible.
- * @param font The font
- */
- public void setFont(Font font)
- {
- super.setFont(font);
- fm = super.getFontMetrics(font);
- textArea.recalculateVisibleLines();
- }
-
- /**
- * Repaints the text.
- * @param gfx The graphics context
- */
- public void paint(Graphics gfx)
- {
- Graphics2D g2 = (Graphics2D) gfx;
- g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
- antialias ?
- RenderingHints.VALUE_TEXT_ANTIALIAS_ON :
- RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
-
- tabSize = fm.charWidth(' ') * ((Integer)textArea.getDocument().getProperty(PlainDocument.tabSizeAttribute)).intValue();
-
- Rectangle clipRect = gfx.getClipBounds();
-
- gfx.setColor(getBackground());
- gfx.fillRect(clipRect.x,clipRect.y,clipRect.width,clipRect.height);
-
- // We don't use yToLine() here because that method doesn't
- // return lines past the end of the document
- int height = fm.getHeight();
- int firstLine = textArea.getFirstLine();
- int firstInvalid = firstLine + clipRect.y / height;
- // Because the clipRect's height is usually an even multiple
- // of the font height, we subtract 1 from it, otherwise one
- // too many lines will always be painted.
- int lastInvalid = firstLine + (clipRect.y + clipRect.height - 1) / height;
-
- try {
- TokenMarker tokenMarker = textArea.getDocument().getTokenMarker();
- int x = textArea.getHorizontalOffset();
-
- for (int line = firstInvalid; line <= lastInvalid; line++) {
- paintLine(gfx,tokenMarker,line,x);
- }
-
- if (tokenMarker != null && tokenMarker.isNextLineRequested()) {
- int h = clipRect.y + clipRect.height;
- repaint(0,h,getWidth(),getHeight() - h);
- }
- } catch (Exception e) {
- System.err.println("Error repainting line"
- + " range {" + firstInvalid + ","
- + lastInvalid + "}:");
- e.printStackTrace();
- }
- }
-
-
- public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
- int lineHeight = fm.getHeight();
- int linesPerPage = (int) (pageFormat.getImageableHeight() / lineHeight);
- int lineCount = textArea.getLineCount();
- int lastPage = lineCount / linesPerPage;
-
- if (pageIndex > lastPage) {
- return NO_SUCH_PAGE;
-
- } else {
- Graphics2D g2d = (Graphics2D)g;
- TokenMarker tokenMarker = textArea.getDocument().getTokenMarker();
- int firstLine = pageIndex*linesPerPage;
- g2d.translate(Math.max(54, pageFormat.getImageableX()),
- pageFormat.getImageableY() - firstLine*lineHeight);
- printing = true;
- for (int line = firstLine; line < firstLine + linesPerPage; line++) {
- paintLine(g2d, tokenMarker, line, 0);
- }
- printing = false;
- return PAGE_EXISTS;
- }
- }
-
-
- /**
- * Marks a line as needing a repaint.
- * @param line The line to invalidate
- */
- public final void invalidateLine(int line)
- {
- repaint(0,textArea.lineToY(line) + fm.getMaxDescent() + fm.getLeading(),
- getWidth(),fm.getHeight());
- }
-
- /**
- * Marks a range of lines as needing a repaint.
- * @param firstLine The first line to invalidate
- * @param lastLine The last line to invalidate
- */
- public final void invalidateLineRange(int firstLine, int lastLine)
- {
- repaint(0,textArea.lineToY(firstLine) +
- fm.getMaxDescent() + fm.getLeading(),
- getWidth(),(lastLine - firstLine + 1) * fm.getHeight());
- }
-
- /**
- * Repaints the lines containing the selection.
- */
- public final void invalidateSelectedLines()
- {
- invalidateLineRange(textArea.getSelectionStartLine(),
- textArea.getSelectionStopLine());
- }
-
- /**
- * Implementation of TabExpander interface. Returns next tab stop after
- * a specified point.
- * @param x The x co-ordinate
- * @param tabOffset Ignored
- * @return The next tab stop after x
- */
- public float nextTabStop(float x, int tabOffset)
- {
- int offset = textArea.getHorizontalOffset();
- int ntabs = ((int)x - offset) / tabSize;
- return (ntabs + 1) * tabSize + offset;
- }
-
- /**
- * Returns the painter's preferred size.
- */
- public Dimension getPreferredSize()
- {
- Dimension dim = new Dimension();
- dim.width = fm.charWidth('w') * cols;
- dim.height = fm.getHeight() * rows;
- return dim;
- }
-
-
- /**
- * Returns the painter's minimum size.
- */
- public Dimension getMinimumSize()
- {
- Dimension dim = new Dimension();
- dim.width = fm.charWidth('w') * 10;
- dim.height = fm.getHeight() * 4;
- return dim;
- }
-
- // package-private members
- int currentLineIndex;
- Token currentLineTokens;
- Segment currentLine;
-
- /**
- * Accessor used by tools that want to hook in and grab the formatting.
- */
- public int getCurrentLineIndex() {
- return currentLineIndex;
- }
-
- /**
- * Accessor used by tools that want to hook in and grab the formatting.
- */
- public void setCurrentLineIndex(int what) {
- currentLineIndex = what;
- }
-
- /**
- * Accessor used by tools that want to hook in and grab the formatting.
- */
- public Token getCurrentLineTokens() {
- return currentLineTokens;
- }
-
- /**
- * Accessor used by tools that want to hook in and grab the formatting.
- */
- public void setCurrentLineTokens(Token tokens) {
- currentLineTokens = tokens;
- }
-
- /**
- * Accessor used by tools that want to hook in and grab the formatting.
- */
- public Segment getCurrentLine() {
- return currentLine;
- }
-
-
- // protected members
- protected JEditTextArea textArea;
-
- protected SyntaxStyle[] styles;
- protected Color caretColor;
- protected Color selectionColor;
- protected Color lineHighlightColor;
- protected Color bracketHighlightColor;
- protected Color eolMarkerColor;
-
- protected boolean blockCaret;
- protected boolean lineHighlight;
- protected boolean bracketHighlight;
- protected boolean paintInvalid;
- protected boolean eolMarkers;
- protected int cols;
- protected int rows;
-
- protected int tabSize;
- protected FontMetrics fm;
-
- protected Highlight highlights;
-
- protected void paintLine(Graphics gfx, TokenMarker tokenMarker,
- int line, int x)
- {
- Font defaultFont = getFont();
- Color defaultColor = getForeground();
-
- currentLineIndex = line;
- int y = textArea.lineToY(line);
-
- if (line < 0 || line >= textArea.getLineCount()) {
- if (paintInvalid) {
- paintHighlight(gfx,line,y);
- styles[Token.INVALID].setGraphicsFlags(gfx,defaultFont);
- gfx.drawString("~",0,y + fm.getHeight());
- }
- } else if(tokenMarker == null) {
- paintPlainLine(gfx,line,defaultFont,defaultColor,x,y);
- } else {
- paintSyntaxLine(gfx,tokenMarker,line,defaultFont,
- defaultColor,x,y);
- }
- }
-
- protected void paintPlainLine(Graphics gfx, int line, Font defaultFont,
- Color defaultColor, int x, int y)
- {
- paintHighlight(gfx,line,y);
- textArea.getLineText(line,currentLine);
-
- gfx.setFont(defaultFont);
- gfx.setColor(defaultColor);
-
- y += fm.getHeight();
- x = Utilities.drawTabbedText(currentLine,x,y,gfx,this,0);
- /*
- * Draw characters via input method.
- */
- if (compositionTextPainter != null && compositionTextPainter.hasComposedTextLayout()) {
- compositionTextPainter.draw(gfx, lineHighlightColor);
- }
- if (eolMarkers) {
- gfx.setColor(eolMarkerColor);
- gfx.drawString(".",x,y);
- }
- }
-
- protected void paintSyntaxLine(Graphics gfx, TokenMarker tokenMarker,
- int line, Font defaultFont,
- Color defaultColor, int x, int y)
- {
- textArea.getLineText(currentLineIndex,currentLine);
- currentLineTokens = tokenMarker.markTokens(currentLine,
- currentLineIndex);
-
- paintHighlight(gfx,line,y);
-
- gfx.setFont(defaultFont);
- gfx.setColor(defaultColor);
- y += fm.getHeight();
- x = SyntaxUtilities.paintSyntaxLine(currentLine,
- currentLineTokens,
- styles, this, gfx, x, y);
- /*
- * Draw characters via input method.
- */
- if (compositionTextPainter != null && compositionTextPainter.hasComposedTextLayout()) {
- compositionTextPainter.draw(gfx, lineHighlightColor);
- }
- if (eolMarkers) {
- gfx.setColor(eolMarkerColor);
- gfx.drawString(".",x,y);
- }
- }
-
- protected void paintHighlight(Graphics gfx, int line, int y)
- {
- if (!printing) {
- if (line >= textArea.getSelectionStartLine()
- && line <= textArea.getSelectionStopLine())
- paintLineHighlight(gfx,line,y);
-
- if (highlights != null)
- highlights.paintHighlight(gfx,line,y);
-
- if (bracketHighlight && line == textArea.getBracketLine())
- paintBracketHighlight(gfx,line,y);
-
- if (line == textArea.getCaretLine())
- paintCaret(gfx,line,y);
- }
- }
-
- protected void paintLineHighlight(Graphics gfx, int line, int y)
- {
- int height = fm.getHeight();
- y += fm.getLeading() + fm.getMaxDescent();
-
- int selectionStart = textArea.getSelectionStart();
- int selectionEnd = textArea.getSelectionStop();
-
- if (selectionStart == selectionEnd) {
- if (lineHighlight) {
- gfx.setColor(lineHighlightColor);
- gfx.fillRect(0,y,getWidth(),height);
- }
- } else {
- gfx.setColor(selectionColor);
-
- int selectionStartLine = textArea.getSelectionStartLine();
- int selectionEndLine = textArea.getSelectionStopLine();
- int lineStart = textArea.getLineStartOffset(line);
-
- int x1, x2;
- if (textArea.isSelectionRectangular()) {
- int lineLen = textArea.getLineLength(line);
- x1 = textArea._offsetToX(line,Math.min(lineLen, selectionStart - textArea.getLineStartOffset(selectionStartLine)));
- x2 = textArea._offsetToX(line,Math.min(lineLen, selectionEnd - textArea.getLineStartOffset(selectionEndLine)));
- if (x1 == x2)
- x2++;
- } else if(selectionStartLine == selectionEndLine) {
- x1 = textArea._offsetToX(line, selectionStart - lineStart);
- x2 = textArea._offsetToX(line, selectionEnd - lineStart);
- } else if(line == selectionStartLine) {
- x1 = textArea._offsetToX(line, selectionStart - lineStart);
- x2 = getWidth();
- } else if(line == selectionEndLine) {
- //x1 = 0;
- // hack from stendahl to avoid doing weird side selection thing
- x1 = textArea._offsetToX(line, 0);
- // attempt at getting the gutter too, but doesn't seem to work
- //x1 = textArea._offsetToX(line, -textArea.getHorizontalOffset());
- x2 = textArea._offsetToX(line, selectionEnd - lineStart);
- } else {
- //x1 = 0;
- // hack from stendahl to avoid doing weird side selection thing
- x1 = textArea._offsetToX(line, 0);
- // attempt at getting the gutter too, but doesn't seem to work
- //x1 = textArea._offsetToX(line, -textArea.getHorizontalOffset());
- x2 = getWidth();
- }
-
- // "inlined" min/max()
- gfx.fillRect(x1 > x2 ? x2 : x1,y,x1 > x2 ?
- (x1 - x2) : (x2 - x1),height);
- }
-
- }
-
- protected void paintBracketHighlight(Graphics gfx, int line, int y)
- {
- int position = textArea.getBracketPosition();
- if(position == -1)
- return;
- y += fm.getLeading() + fm.getMaxDescent();
- int x = textArea._offsetToX(line,position);
- gfx.setColor(bracketHighlightColor);
- // Hack!!! Since there is no fast way to get the character
- // from the bracket matching routine, we use ( since all
- // brackets probably have the same width anyway
- gfx.drawRect(x,y,fm.charWidth('(') - 1,
- fm.getHeight() - 1);
- }
-
- protected void paintCaret(Graphics gfx, int line, int y)
- {
- //System.out.println("painting caret " + line + " " + y);
- if (textArea.isCaretVisible()) {
- //System.out.println("caret is visible");
- int offset =
- textArea.getCaretPosition() - textArea.getLineStartOffset(line);
- int caretX = textArea._offsetToX(line, offset);
- int caretWidth = ((blockCaret ||
- textArea.isOverwriteEnabled()) ?
- fm.charWidth('w') : 1);
- y += fm.getLeading() + fm.getMaxDescent();
- int height = fm.getHeight();
-
- //System.out.println("caretX, width = " + caretX + " " + caretWidth);
-
- gfx.setColor(caretColor);
-
- if (textArea.isOverwriteEnabled()) {
- gfx.fillRect(caretX,y + height - 1, caretWidth,1);
-
- } else {
- // some machines don't like the drawRect for the single
- // pixel caret.. this caused a lot of hell because on that
- // minority of machines, the caret wouldn't show up past
- // the first column. the fix is to use drawLine() in
- // those cases, as a workaround.
- if (caretWidth == 1) {
- gfx.drawLine(caretX, y, caretX, y + height - 1);
- } else {
- gfx.drawRect(caretX, y, caretWidth - 1, height - 1);
- }
- //gfx.drawRect(caretX, y, caretWidth, height - 1);
- }
- }
- }
-}
diff --git a/app/src/processing/app/syntax/TextUtilities.java b/app/src/processing/app/syntax/TextUtilities.java
deleted file mode 100644
index f009cd051..000000000
--- a/app/src/processing/app/syntax/TextUtilities.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * TextUtilities.java - Utility functions used by the text area classes
- * Copyright (C) 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import javax.swing.text.*;
-
-/**
- * Class with several utility functions used by the text area component.
- * @author Slava Pestov
- */
-public class TextUtilities
-{
- /**
- * Returns the offset of the bracket matching the one at the
- * specified offset of the document, or -1 if the bracket is
- * unmatched (or if the character is not a bracket).
- * @param doc The document
- * @param offset The offset
- * @exception BadLocationException If an out-of-bounds access
- * was attempted on the document text
- */
- public static int findMatchingBracket(Document doc, int offset)
- throws BadLocationException
- {
- if(doc.getLength() == 0)
- return -1;
- char c = doc.getText(offset,1).charAt(0);
- char cprime; // c` - corresponding character
- boolean direction; // true = back, false = forward
-
- switch(c)
- {
- case '(': cprime = ')'; direction = false; break;
- case ')': cprime = '('; direction = true; break;
- case '[': cprime = ']'; direction = false; break;
- case ']': cprime = '['; direction = true; break;
- case '{': cprime = '}'; direction = false; break;
- case '}': cprime = '{'; direction = true; break;
- default: return -1;
- }
-
- int count;
-
- // How to merge these two cases is left as an exercise
- // for the reader.
-
- // Go back or forward
- if(direction)
- {
- // Count is 1 initially because we have already
- // `found' one closing bracket
- count = 1;
-
- // Get text[0,offset-1];
- String text = doc.getText(0,offset);
-
- // Scan backwards
- for(int i = offset - 1; i >= 0; i--)
- {
- // If text[i] == c, we have found another
- // closing bracket, therefore we will need
- // two opening brackets to complete the
- // match.
- char x = text.charAt(i);
- if(x == c)
- count++;
-
- // If text[i] == cprime, we have found a
- // opening bracket, so we return i if
- // --count == 0
- else if(x == cprime)
- {
- if(--count == 0)
- return i;
- }
- }
- }
- else
- {
- // Count is 1 initially because we have already
- // `found' one opening bracket
- count = 1;
-
- // So we don't have to + 1 in every loop
- offset++;
-
- // Number of characters to check
- int len = doc.getLength() - offset;
-
- // Get text[offset+1,len];
- String text = doc.getText(offset,len);
-
- // Scan forwards
- for(int i = 0; i < len; i++)
- {
- // If text[i] == c, we have found another
- // opening bracket, therefore we will need
- // two closing brackets to complete the
- // match.
- char x = text.charAt(i);
-
- if(x == c)
- count++;
-
- // If text[i] == cprime, we have found an
- // closing bracket, so we return i if
- // --count == 0
- else if(x == cprime)
- {
- if(--count == 0)
- return i + offset;
- }
- }
- }
-
- // Nothing found
- return -1;
- }
-
- /**
- * Locates the start of the word at the specified position.
- * @param line The text
- * @param pos The position
- */
- public static int findWordStart(String line, int pos, String noWordSep)
- {
- char ch = line.charAt(pos - 1);
-
- if(noWordSep == null)
- noWordSep = "";
- boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
- && noWordSep.indexOf(ch) == -1);
-
- int wordStart = 0;
- for(int i = pos - 1; i >= 0; i--)
- {
- ch = line.charAt(i);
- if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
- noWordSep.indexOf(ch) == -1))
- {
- wordStart = i + 1;
- break;
- }
- }
-
- return wordStart;
- }
-
- /**
- * Locates the end of the word at the specified position.
- * @param line The text
- * @param pos The position
- */
- public static int findWordEnd(String line, int pos, String noWordSep)
- {
- char ch = line.charAt(pos);
-
- if(noWordSep == null)
- noWordSep = "";
- boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
- && noWordSep.indexOf(ch) == -1);
-
- int wordEnd = line.length();
- for(int i = pos; i < line.length(); i++)
- {
- ch = line.charAt(i);
- if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
- noWordSep.indexOf(ch) == -1))
- {
- wordEnd = i;
- break;
- }
- }
- return wordEnd;
- }
-}
diff --git a/app/src/processing/app/syntax/TokenMarker.java b/app/src/processing/app/syntax/TokenMarker.java
deleted file mode 100644
index 9244556d3..000000000
--- a/app/src/processing/app/syntax/TokenMarker.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * TokenMarker.java - Generic token marker
- * Copyright (C) 1998, 1999 Slava Pestov
- *
- * You may use and modify this package for any purpose. Redistribution is
- * permitted, in both source and binary form, provided that this notice
- * remains intact in all source distributions of this package.
- */
-
-package processing.app.syntax;
-
-import javax.swing.text.Segment;
-
-/**
- * A token marker that splits lines of text into tokens. Each token carries
- * a length field and an indentification tag that can be mapped to a color
- * for painting that token.
- *
- * For performance reasons, the linked list of tokens is reused after each
- * line is tokenized. Therefore, the return value of markTokens
- * should only be used for immediate painting. Notably, it cannot be
- * cached.
- *
- * @author Slava Pestov
- */
-public abstract class TokenMarker
-{
- /**
- * A wrapper for the lower-level markTokensImpl
method
- * that is called to split a line up into tokens.
- * @param line The line
- * @param lineIndex The line number
- */
- public Token markTokens(Segment line, int lineIndex)
- {
- if(lineIndex >= length)
- {
- throw new IllegalArgumentException("Tokenizing invalid line: "
- + lineIndex);
- }
-
- lastToken = null;
-
- LineInfo info = lineInfo[lineIndex];
- LineInfo prev;
- if(lineIndex == 0)
- prev = null;
- else
- prev = lineInfo[lineIndex - 1];
-
- byte oldToken = info.token;
- byte token = markTokensImpl(prev == null ?
- Token.NULL : prev.token,line,lineIndex);
-
- info.token = token;
-
- /*
- * This is a foul hack. It stops nextLineRequested
- * from being cleared if the same line is marked twice.
- *
- * Why is this necessary? It's all JEditTextArea's fault.
- * When something is inserted into the text, firing a
- * document event, the insertUpdate() method shifts the
- * caret (if necessary) by the amount inserted.
- *
- * All caret movement is handled by the select() method,
- * which eventually pipes the new position to scrollTo()
- * and calls repaint().
- *
- * Note that at this point in time, the new line hasn't
- * yet been painted; the caret is moved first.
- *
- * scrollTo() calls offsetToX(), which tokenizes the line
- * unless it is being called on the last line painted
- * (in which case it uses the text area's painter cached
- * token list). What scrollTo() does next is irrelevant.
- *
- * After scrollTo() has done it's job, repaint() is
- * called, and eventually we end up in paintLine(), whose
- * job is to paint the changed line. It, too, calls
- * markTokens().
- *
- * The problem was that if the line started a multiline
- * token, the first markTokens() (done in offsetToX())
- * would set nextLineRequested (because the line end
- * token had changed) but the second would clear it
- * (because the line was the same that time) and therefore
- * paintLine() would never know that it needed to repaint
- * subsequent lines.
- *
- * This bug took me ages to track down, that's why I wrote
- * all the relevant info down so that others wouldn't
- * duplicate it.
- */
- if(!(lastLine == lineIndex && nextLineRequested))
- nextLineRequested = (oldToken != token);
-
- lastLine = lineIndex;
-
- addToken(0,Token.END);
-
- return firstToken;
- }
-
- /**
- * An abstract method that splits a line up into tokens. It
- * should parse the line, and call addToken()
to
- * add syntax tokens to the token list. Then, it should return
- * the initial token type for the next line.
- *
- * For example if the current line contains the start of a
- * multiline comment that doesn't end on that line, this method
- * should return the comment token type so that it continues on
- * the next line.
- *
- * @param token The initial token type for this line
- * @param line The line to be tokenized
- * @param lineIndex The index of the line in the document,
- * starting at 0
- * @return The initial token type for the next line
- */
- protected abstract byte markTokensImpl(byte token, Segment line,
- int lineIndex);
-
- /**
- * Returns if the token marker supports tokens that span multiple
- * lines. If this is true, the object using this token marker is
- * required to pass all lines in the document to the
- * markTokens()
method (in turn).
- *
- * The default implementation returns true; it should be overridden
- * to return false on simpler token markers for increased speed.
- */
- public boolean supportsMultilineTokens()
- {
- return true;
- }
-
- /**
- * Informs the token marker that lines have been inserted into
- * the document. This inserts a gap in the lineInfo
- * array.
- * @param index The first line number
- * @param lines The number of lines
- */
- public void insertLines(int index, int lines)
- {
- if(lines <= 0)
- return;
- length += lines;
- ensureCapacity(length);
- int len = index + lines;
- System.arraycopy(lineInfo,index,lineInfo,len,
- lineInfo.length - len);
-
- for(int i = index + lines - 1; i >= index; i--)
- {
- lineInfo[i] = new LineInfo();
- }
- }
-
- /**
- * Informs the token marker that line have been deleted from
- * the document. This removes the lines in question from the
- * lineInfo
array.
- * @param index The first line number
- * @param lines The number of lines
- */
- public void deleteLines(int index, int lines)
- {
- if (lines <= 0)
- return;
- int len = index + lines;
- length -= lines;
- System.arraycopy(lineInfo,len,lineInfo,
- index,lineInfo.length - len);
- }
-
- /**
- * Returns the number of lines in this token marker.
- */
- public int getLineCount()
- {
- return length;
- }
-
- /**
- * Returns true if the next line should be repainted. This
- * will return true after a line has been tokenized that starts
- * a multiline token that continues onto the next line.
- */
- public boolean isNextLineRequested()
- {
- return nextLineRequested;
- }
-
- // protected members
-
- /**
- * The first token in the list. This should be used as the return
- * value from markTokens()
.
- */
- protected Token firstToken;
-
- /**
- * The last token in the list. New tokens are added here.
- * This should be set to null before a new line is to be tokenized.
- */
- protected Token lastToken;
-
- /**
- * An array for storing information about lines. It is enlarged and
- * shrunk automatically by the insertLines()
and
- * deleteLines()
methods.
- */
- protected LineInfo[] lineInfo;
-
- /**
- * The number of lines in the model being tokenized. This can be
- * less than the length of the lineInfo
array.
- */
- protected int length;
-
- /**
- * The last tokenized line.
- */
- protected int lastLine;
-
- /**
- * True if the next line should be painted.
- */
- protected boolean nextLineRequested;
-
- /**
- * Creates a new TokenMarker
. This DOES NOT create
- * a lineInfo array; an initial call to insertLines()
- * does that.
- */
- protected TokenMarker()
- {
- lastLine = -1;
- }
-
- /**
- * Ensures that the lineInfo
array can contain the
- * specified index. This enlarges it if necessary. No action is
- * taken if the array is large enough already.
- *
- * It should be unnecessary to call this under normal
- * circumstances; insertLine()
should take care of
- * enlarging the line info array automatically.
- *
- * @param index The array index
- */
- protected void ensureCapacity(int index)
- {
- if(lineInfo == null)
- lineInfo = new LineInfo[index + 1];
- else if(lineInfo.length <= index)
- {
- LineInfo[] lineInfoN = new LineInfo[(index + 1) * 2];
- System.arraycopy(lineInfo,0,lineInfoN,0,
- lineInfo.length);
- lineInfo = lineInfoN;
- }
- }
-
- /**
- * Adds a token to the token list.
- * @param length The length of the token
- * @param id The id of the token
- */
- protected void addToken(int length, byte id)
- {
- if(id >= Token.INTERNAL_FIRST && id <= Token.INTERNAL_LAST)
- throw new InternalError("Invalid id: " + id);
-
- if(length == 0 && id != Token.END)
- return;
-
- if(firstToken == null)
- {
- firstToken = new Token(length,id);
- lastToken = firstToken;
- }
- else if(lastToken == null)
- {
- lastToken = firstToken;
- firstToken.length = length;
- firstToken.id = id;
- }
- else if(lastToken.next == null)
- {
- lastToken.next = new Token(length,id);
- lastToken = lastToken.next;
- }
- else
- {
- lastToken = lastToken.next;
- lastToken.length = length;
- lastToken.id = id;
- }
- }
-
- /**
- * Inner class for storing information about tokenized lines.
- */
- public class LineInfo
- {
- /**
- * Creates a new LineInfo object with token = Token.NULL
- * and obj = null.
- */
- public LineInfo()
- {
- }
-
- /**
- * Creates a new LineInfo object with the specified
- * parameters.
- */
- public LineInfo(byte token, Object obj)
- {
- this.token = token;
- this.obj = obj;
- }
-
- /**
- * The id of the last token of the line.
- */
- public byte token;
-
- /**
- * This is for use by the token marker implementations
- * themselves. It can be used to store anything that
- * is an object and that needs to exist on a per-line
- * basis.
- */
- public Object obj;
- }
-}
diff --git a/app/src/processing/app/syntax/im/CompositionTextManager.java b/app/src/processing/app/syntax/im/CompositionTextManager.java
deleted file mode 100644
index ba9ee155f..000000000
--- a/app/src/processing/app/syntax/im/CompositionTextManager.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package processing.app.syntax.im;
-
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.font.FontRenderContext;
-import java.awt.font.TextAttribute;
-import java.awt.font.TextLayout;
-import java.text.AttributedCharacterIterator;
-import java.text.AttributedString;
-
-import javax.swing.text.BadLocationException;
-
-import processing.app.syntax.JEditTextArea;
-import processing.app.syntax.TextAreaPainter;
-
-/**
- * This class Manage texts from input method
- * by begin-process-end steps.
- *
- * First, if a user start inputing via input method,
- * beginCompositionText is called from InputMethodSupport.
- * Second, the user continues from input method, processCompositionText is called
- * and reflect user inputs to text area.
- * Finally the user try to commit text, endCompositionText is called.
- *
- * @author Takashi Maekawa (takachin@generative.info)
- */
-
-public class CompositionTextManager {
- private JEditTextArea textArea;
- private String prevComposeString;
- private int prevCommittedCount;
- private boolean isInputProcess;
- private int initialCaretPosition;
- public static final int COMPOSING_UNDERBAR_HEIGHT = 5;
-
- /**
- * Create text manager class with a textarea.
- * @param textArea texarea component for PDE.
- */
- public CompositionTextManager(JEditTextArea textArea) {
- this.textArea = textArea;
- prevComposeString = "";
- isInputProcess = false;
- prevCommittedCount = 0;
- }
-
- /**
- * Get this text manager is whether in input process or not.
- */
- public boolean getIsInputProcess() {
- return isInputProcess;
- }
- /**
- * Insert full width space
- */
- public void insertFullWidthSpace() {
- initialCaretPosition = textArea.getCaretPosition();
- int layoutCaretPosition = initialCaretPosition;
- try {
- textArea.getDocument().insertString(layoutCaretPosition, "\u3000", null);
- } catch (BadLocationException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Called when a user begins input from input method.
- * This method initializes text manager.
- *
- * @param text Text from InputMethodEvent.
- * @param commited_count Numbers of committed characters in text.
- */
- public void beginCompositionText(AttributedCharacterIterator text, int committed_count) {
- isInputProcess = true;
- prevComposeString = "";
- initialCaretPosition = textArea.getCaretPosition();
- processCompositionText(text, committed_count);
- }
-
- /**
- * Called when a user processing input characters and
- * select candidates from input method.
- *
- * @param text Text from InputMethodEvent.
- * @param commited_count Numbers of committed characters in text.
- */
- public void processCompositionText(AttributedCharacterIterator text, int committed_count) {
- int layoutCaretPosition = initialCaretPosition + committed_count;
- CompositionTextPainter compositionPainter = textArea.getPainter().getCompositionTextpainter();
- compositionPainter.setComposedTextLayout(getTextLayout(text, committed_count), layoutCaretPosition);
- int textLength = text.getEndIndex() - text.getBeginIndex() - committed_count;
- StringBuffer unCommitedStringBuf = new StringBuffer(textLength);
- char c;
- for (c = text.setIndex(committed_count); c != AttributedCharacterIterator.DONE
- && textLength > 0; c = text.next(), --textLength) {
- unCommitedStringBuf.append(c);
- }
- String unCommittedString = unCommitedStringBuf.toString();
- try {
- if(canRemovePreviousInput(committed_count)){
- textArea.getDocument().remove(layoutCaretPosition, prevComposeString.length());
- }
- textArea.getDocument().insertString(layoutCaretPosition, unCommittedString, null);
- if(committed_count > 0){
- initialCaretPosition = initialCaretPosition + committed_count;
- }
- prevComposeString = unCommittedString;
- prevCommittedCount = committed_count;
- } catch (BadLocationException e) {
- e.printStackTrace();
- }
- }
-
- private boolean canRemovePreviousInput(int committed_count){
- return (prevCommittedCount == committed_count || prevCommittedCount > committed_count);
- }
-
- /**
- * Called when a user fixed text from input method or delete all
- * composition text. This method resets CompositionTextPainter.
- *
- * @param text Text from InputMethodEvent.
- * @param commited_count Numbers of committed characters in text.
- */
- public void endCompositionText(AttributedCharacterIterator text, int committed_count) {
- /*
- * If there are no committed characters, remove it all from textarea.
- * This case will happen if a user delete all composing characters by backspace or delete key.
- * If it does, these previous characters are needed to be deleted.
- */
- if(committed_count == 0){
- removeNotCommittedText(text);
- }
- CompositionTextPainter compositionPainter = textArea.getPainter().getCompositionTextpainter();
- compositionPainter.invalidateComposedTextLayout(initialCaretPosition + committed_count);
- prevComposeString = "";
- isInputProcess = false;
- }
-
- private void removeNotCommittedText(AttributedCharacterIterator text){
- if (prevComposeString.length() == 0) {
- return;
- }
- try {
- textArea.getDocument().remove(initialCaretPosition, prevComposeString.length());
- } catch (BadLocationException e) {
- e.printStackTrace();
- }
- }
-
- private TextLayout getTextLayout(AttributedCharacterIterator text, int committed_count) {
- AttributedString composed = new AttributedString(text, committed_count, text.getEndIndex());
- Font font = textArea.getPainter().getFont();
- FontRenderContext context = ((Graphics2D) (textArea.getPainter().getGraphics())).getFontRenderContext();
- composed.addAttribute(TextAttribute.FONT, font);
- TextLayout layout = new TextLayout(composed.getIterator(), context);
- return layout;
- }
-
- private Point getCaretLocation() {
- Point loc = new Point();
- TextAreaPainter painter = textArea.getPainter();
- FontMetrics fm = painter.getFontMetrics();
- int offsetY = fm.getHeight() - COMPOSING_UNDERBAR_HEIGHT;
- int lineIndex = textArea.getCaretLine();
- loc.y = lineIndex * fm.getHeight() + offsetY;
- int offsetX = textArea.getCaretPosition()
- - textArea.getLineStartOffset(lineIndex);
- loc.x = textArea.offsetToX(lineIndex, offsetX);
- return loc;
- }
-
- public Rectangle getTextLocation() {
- Point caret = getCaretLocation();
- return getCaretRectangle(caret.x, caret.y);
- }
-
- private Rectangle getCaretRectangle(int x, int y) {
- TextAreaPainter painter = textArea.getPainter();
- Point origin = painter.getLocationOnScreen();
- int height = painter.getFontMetrics().getHeight();
- return new Rectangle(origin.x + x, origin.y + y, 0, height);
- }
-
- public AttributedCharacterIterator getCommittedText(int beginIndex, int endIndex) {
- int length = endIndex - beginIndex;
- String textAreaString = textArea.getText(beginIndex, length);
- return new AttributedString(textAreaString).getIterator();
- }
-
- public int getInsertPositionOffset() {
- return textArea.getCaretPosition() * -1;
- }
-}
diff --git a/app/src/processing/app/syntax/im/CompositionTextPainter.java b/app/src/processing/app/syntax/im/CompositionTextPainter.java
deleted file mode 100644
index 0084f491f..000000000
--- a/app/src/processing/app/syntax/im/CompositionTextPainter.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package processing.app.syntax.im;
-
-import java.awt.Color;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.font.TextLayout;
-
-import processing.app.syntax.JEditTextArea;
-import processing.app.syntax.TextAreaPainter;
-
-/**
- * Paint texts from input method. Text via input method are transmitted by
- * AttributedCaharacterIterator. This class helps the PDE's TextAreaPainter
- * to handle AttributedCaharacterIterator.
- *
- * For practical purposes, paint to textarea is done by TextLayout class.
- * Because TextLayout class is easy to draw composing texts. (For example,
- * draw underline composing texts, focus when select from candidates text.)
- *
- * @author Takashi Maekawa (takachin@generative.info)
- */
-public class CompositionTextPainter {
- private TextLayout composedTextLayout;
- private int composedBeginCaretPosition = 0;
- private JEditTextArea textArea;
-
- /**
- * Constructor for painter.
- * @param textarea textarea used by PDE.
- */
- public CompositionTextPainter(JEditTextArea textArea) {
- this.textArea = textArea;
- composedTextLayout = null;
- }
-
- /**
- * Check the painter has TextLayout.
- * If a user input via InputMethod, this result will return true.
- * @param textarea textarea used by PDE.
- */
- public boolean hasComposedTextLayout() {
- return (composedTextLayout != null);
- }
-
- /**
- * Set TextLayout to the painter.
- * TextLayout will be created and set by CompositionTextManager.
- *
- * @see CompositionTextManager
- * @param textarea textarea used by PDE.
- */
- public void setComposedTextLayout(TextLayout composedTextLayout, int composedStartCaretPosition) {
- this.composedTextLayout = composedTextLayout;
- this.composedBeginCaretPosition = composedStartCaretPosition;
- }
-
- /**
- * Invalidate this TextLayout to set null.
- * If a user end input via InputMethod, this method will called from CompositionTextManager.endCompositionText
- */
- public void invalidateComposedTextLayout(int composedEndCaretPosition) {
- this.composedTextLayout = null;
- this.composedBeginCaretPosition = composedEndCaretPosition;
- //this.composedBeginCaretPosition = textArea.getCaretPosition();
- }
-
- /**
- * Draw text via input method with composed text information.
- * This method can draw texts with some underlines to illustrate converting characters.
- *
- * This method is workaround for TextAreaPainter.
- * Because, TextAreaPainter can't treat AttributedCharacterIterator directly.
- * AttributedCharacterIterator has very important information when composing text.
- * It has a map where are converted characters and committed characters.
- * Ideally, changing TextAreaPainter method can treat AttributedCharacterIterator is better. But it's very tough!!
- * So I choose to write some code as a workaround.
- *
- * This draw method is proceeded with the following steps.
- * 1. Original TextAreaPainter draws characters.
- * 2. This refillComposedArea method erase previous paint characters by textarea's background color.
- * The refill area is only square that width and height defined by characters with input method.
- * 3. CompositionTextPainter.draw method paints composed text. It was actually drawn by TextLayout.
- *
- * @param gfx set TextAreaPainter's Graphics object.
- * @param fillBackGroundColor set textarea's background.
- */
- public void draw(Graphics gfx, Color fillBackGroundColor) {
- assert(composedTextLayout != null);
- Point composedLoc = getCaretLocation();
- refillComposedArea(fillBackGroundColor, composedLoc.x, composedLoc.y);
- composedTextLayout.draw((Graphics2D) gfx, composedLoc.x, composedLoc.y);
- }
-
- /**
- * Fill color to erase characters drawn by original TextAreaPainter.
- *
- * @param fillColor fill color to erase characters drawn by original TextAreaPainter method.
- * @param x x-coordinate where to fill.
- * @param y y-coordinate where to fill.
- */
- private void refillComposedArea(Color fillColor, int x, int y) {
- Graphics gfx = textArea.getPainter().getGraphics();
- gfx.setColor(fillColor);
- FontMetrics fm = textArea.getPainter().getFontMetrics();
- int newY = y - (fm.getHeight() - CompositionTextManager.COMPOSING_UNDERBAR_HEIGHT);
- int paintHeight = fm.getHeight();
- int paintWidth = (int) composedTextLayout.getBounds().getWidth();
- gfx.fillRect(x, newY, paintWidth, paintHeight);
- }
-
- private Point getCaretLocation() {
- Point loc = new Point();
- TextAreaPainter painter = textArea.getPainter();
- FontMetrics fm = painter.getFontMetrics();
- int offsetY = fm.getHeight() - CompositionTextManager.COMPOSING_UNDERBAR_HEIGHT;
- int lineIndex = textArea.getCaretLine();
- loc.y = lineIndex * fm.getHeight() + offsetY;
- int offsetX = composedBeginCaretPosition - textArea.getLineStartOffset(lineIndex);
- loc.x = textArea.offsetToX(lineIndex, offsetX);
- return loc;
- }
-}
diff --git a/app/src/processing/app/syntax/im/InputMethodSupport.java b/app/src/processing/app/syntax/im/InputMethodSupport.java
deleted file mode 100644
index 461be3d16..000000000
--- a/app/src/processing/app/syntax/im/InputMethodSupport.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package processing.app.syntax.im;
-
-import java.awt.Rectangle;
-import java.awt.event.InputMethodEvent;
-import java.awt.event.InputMethodListener;
-import java.awt.font.TextHitInfo;
-import java.awt.im.InputMethodRequests;
-import java.text.AttributedCharacterIterator;
-
-import processing.app.syntax.JEditTextArea;
-
-/**
- * Support in-line Japanese input for PDE. (Maybe Chinese, Korean and more)
- * This class is implemented by Java Input Method Framework and handles
- * If you would like to know more about Java Input Method Framework,
- * Please see http://java.sun.com/j2se/1.5.0/docs/guide/imf/
- *
- * This class is implemented to fix Bug #854.
- * http://dev.processing.org/bugs/show_bug.cgi?id=854
- *
- * @author Takashi Maekawa (takachin@generative.info)
- */
-public class InputMethodSupport implements InputMethodRequests,
- InputMethodListener {
-
- private int committed_count = 0;
- private CompositionTextManager textManager;
-
- public InputMethodSupport(JEditTextArea textArea) {
- textManager = new CompositionTextManager(textArea);
- textArea.enableInputMethods(true);
- textArea.addInputMethodListener(this);
- }
-
- public Rectangle getTextLocation(TextHitInfo offset) {
- return textManager.getTextLocation();
- }
-
- public TextHitInfo getLocationOffset(int x, int y) {
- return null;
- }
-
- public int getInsertPositionOffset() {
- return textManager.getInsertPositionOffset();
- }
-
- public AttributedCharacterIterator getCommittedText(int beginIndex,
- int endIndex, AttributedCharacterIterator.Attribute[] attributes) {
- return textManager.getCommittedText(beginIndex, endIndex);
- }
-
- public int getCommittedTextLength() {
- return committed_count;
- }
-
- public AttributedCharacterIterator cancelLatestCommittedText(
- AttributedCharacterIterator.Attribute[] attributes) {
- return null;
- }
-
- public AttributedCharacterIterator getSelectedText(
- AttributedCharacterIterator.Attribute[] attributes) {
- return null;
- }
-
- /**
- * Handles events from InputMethod.
- * This method judges whether beginning of input or
- * progress of input or end and call related method.
- *
- * @param event event from Input Method.
- */
- public void inputMethodTextChanged(InputMethodEvent event) {
- AttributedCharacterIterator text = event.getText();
- committed_count = event.getCommittedCharacterCount();
- if(isFullWidthSpaceInput(text)){
- textManager.insertFullWidthSpace();
- caretPositionChanged(event);
- return;
- }
- if(isBeginInputProcess(text, textManager)){
- textManager.beginCompositionText(text, committed_count);
- caretPositionChanged(event);
- return;
- }
- if (isInputProcess(text)){
- textManager.processCompositionText(text, committed_count);
- caretPositionChanged(event);
- return;
- }
- textManager.endCompositionText(text, committed_count);
- caretPositionChanged(event);
- }
-
- private boolean isFullWidthSpaceInput(AttributedCharacterIterator text){
- if(text == null)
- return false;
- if(textManager.getIsInputProcess())
- return false;
- return (String.valueOf(text.first()).equals("\u3000"));
- }
-
- private boolean isBeginInputProcess(AttributedCharacterIterator text, CompositionTextManager textManager){
- if(text == null)
- return false;
- if(textManager.getIsInputProcess())
- return false;
- return (isInputProcess(text));
- }
-
- private boolean isInputProcess(AttributedCharacterIterator text){
- if(text == null)
- return false;
- return (text.getEndIndex() - (text.getBeginIndex() + committed_count) > 0);
- }
-
- public void caretPositionChanged(InputMethodEvent event) {
- event.consume();
- }
-}
diff --git a/app/src/processing/app/syntax/readme.txt b/app/src/processing/app/syntax/readme.txt
deleted file mode 100644
index 07a825cd7..000000000
--- a/app/src/processing/app/syntax/readme.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-OLDSYNTAX PACKAGE README
-
-I am placing the jEdit 2.2.1 syntax highlighting package in the public
-domain. This means it can be integrated into commercial programs, etc.
-
-This package requires at least Java 1.1 and Swing 1.1. Syntax
-highlighting for the following file types is supported:
-
-- C++, C
-- CORBA IDL
-- Eiffel
-- HTML
-- Java
-- Java properties
-- JavaScript
-- MS-DOS INI
-- MS-DOS batch files
-- Makefile
-- PHP
-- Perl
-- Python
-- TeX
-- Transact-SQL
-- Unix patch/diff
-- Unix shell script
-- XML
-
-This package is undocumented; read the source (start by taking a look at
-JEditTextArea.java) to find out how to use it; it's really simple. Feel
-free to e-mail questions, queries, etc. to me, but keep in mind that
-this code is very old and I no longer maintain it. So if you find a bug,
-don't bother me about it; fix it yourself.
-
-* Copyright
-
-The jEdit 2.2.1 syntax highlighting package contains code that is
-Copyright 1998-1999 Slava Pestov, Artur Biesiadowski, Clancy Malcolm,
-Jonathan Revusky, Juha Lindfors and Mike Dillon.
-
-You may use and modify this package for any purpose. Redistribution is
-permitted, in both source and binary form, provided that this notice
-remains intact in all source distributions of this package.
-
--- Slava Pestov
-25 September 2000
-
diff --git a/app/src/processing/app/tools/AutoFormat.java b/app/src/processing/app/tools/AutoFormat.java
index 572ea692c..f855400b1 100644
--- a/app/src/processing/app/tools/AutoFormat.java
+++ b/app/src/processing/app/tools/AutoFormat.java
@@ -440,7 +440,7 @@ public class AutoFormat implements Tool {
// Adding an additional newline as a hack around other errors
String originalText = editor.getText() + "\n";
strOut = new StringBuffer();
- indentValue = Preferences.getInteger("editor.tabs.size");
+ indentValue = PreferencesData.getInteger("editor.tabs.size");
indentChar = new String(" ");
lineNumber = 0;
diff --git a/app/src/processing/app/tools/DiscourseFormat.java b/app/src/processing/app/tools/DiscourseFormat.java
index a4a381c5a..75240cb69 100644
--- a/app/src/processing/app/tools/DiscourseFormat.java
+++ b/app/src/processing/app/tools/DiscourseFormat.java
@@ -25,11 +25,14 @@ package processing.app.tools;
import java.awt.*;
import java.awt.datatransfer.*;
+
+import javax.swing.text.BadLocationException;
import javax.swing.text.Segment;
+import org.fife.ui.rsyntaxtextarea.Token;
+
import processing.app.*;
import processing.app.syntax.*;
-import processing.app.legacy.PApplet;
/**
* Format for Discourse Tool
@@ -44,6 +47,8 @@ import processing.app.legacy.PApplet;
*
* Updated for 0144 to only format the selected lines.
*
+ * Updated for 1.5.8 - Simplification, using RSyntaxTextArea TokenImpl formatter (08 dec 2014 - Ricardo JL Rufino)
+ *
* Notes from the original source:
* Discourse.java This is a dirty-mix source.
* NOTE that: No macs and no keyboard. Unreliable source.
@@ -54,7 +59,7 @@ public class DiscourseFormat {
private Editor editor;
// JTextArea of the actual Editor
- private JEditTextArea textarea;
+ private SketchTextArea textarea;
private boolean html;
@@ -78,10 +83,16 @@ public class DiscourseFormat {
StringBuilder cf = new StringBuilder(html ? "\n" : "[code]\n");
int selStart = textarea.getSelectionStart();
- int selStop = textarea.getSelectionStop();
+ int selStop = textarea.getSelectionEnd();
- int startLine = textarea.getSelectionStartLine();
- int stopLine = textarea.getSelectionStopLine();
+ int startLine;
+ int stopLine;
+ try {
+ startLine = textarea.getLineOfOffset(selStart);
+ stopLine = textarea.getLineOfOffset(selStop);
+ } catch (BadLocationException e) {
+ return;
+ }
// If no selection, convert all the lines
if (selStart == selStop) {
@@ -89,8 +100,11 @@ public class DiscourseFormat {
stopLine = textarea.getLineCount() - 1;
} else {
// Make sure the selection doesn't end at the beginning of the last line
- if (textarea.getLineStartOffset(stopLine) == selStop) {
- stopLine--;
+ try {
+ if (textarea.getLineStartOffset(stopLine) == selStop) {
+ stopLine--;
+ }
+ } catch (BadLocationException e) {
}
}
@@ -139,23 +153,15 @@ public class DiscourseFormat {
public void appendFormattedLine(StringBuilder cf, int line) {
Segment segment = new Segment();
- TextAreaPainter painter = textarea.getPainter();
- TokenMarker tokenMarker = textarea.getTokenMarker();
-
- // Use painter's cached info for speed
-// FontMetrics fm = painter.getFontMetrics();
-
// get line text from parent text area
- textarea.getLineText(line, segment);
-
+ textarea.getTextLine(line, segment);
+
char[] segmentArray = segment.array;
- int limit = segment.getEndIndex();
int segmentOffset = segment.offset;
int segmentCount = segment.count;
// int width = 0;
- // If syntax coloring is disabled, do simple translation
- if (tokenMarker == null) {
+ if (!html) {
for (int j = 0; j < segmentCount; j++) {
char c = segmentArray[j + segmentOffset];
appendToHTML(c, cf);
@@ -169,82 +175,19 @@ public class DiscourseFormat {
}
} else {
- // If syntax coloring is enabled, we have to do this
- // because tokens can vary in width
- Token tokens;
- if ((painter.getCurrentLineIndex() == line) &&
- (painter.getCurrentLineTokens() != null)) {
- tokens = painter.getCurrentLineTokens();
-
- } else {
- painter.setCurrentLineIndex(line);
- painter.setCurrentLineTokens(tokenMarker.markTokens(segment, line));
- tokens = painter.getCurrentLineTokens();
- }
-
- int offset = 0;
-// Font defaultFont = painter.getFont();
- SyntaxStyle[] styles = painter.getStyles();
-
- for (;;) {
- byte id = tokens.id;
- if (id == Token.END) {
- char c = segmentArray[segmentOffset + offset];
- if (segmentOffset + offset < limit) {
- appendToHTML(c, cf);
- } else {
- cf.append('\n');
- }
- return; // cf.toString();
- }
- if (id == Token.NULL) {
-// fm = painter.getFontMetrics();
- } else {
- // Place open tags []
- if (html) {
- cf.append("");
- }
-
- if (html && styles[id].isBold())
- cf.append("");
-
-// fm = styles[id].getFontMetrics(defaultFont);
- }
- int length = tokens.length;
-
- for (int j = 0; j < length; j++) {
- char c = segmentArray[segmentOffset + offset + j];
- if (offset == 0 && c == ' ') {
- // Works on Safari but not Camino 1.6.3 or Firefox 2.x on OS X.
- cf.append(html ? " " : '\u00A0'); //
-// if ((j % 2) == 1) {
-// cf.append("[b]\u00A0[/b]");
-// } else {
-// cf.append(' ');
-// }
- } else {
- appendToHTML(c, cf);
- }
- // Place close tags [/]
- if (html && j == (length - 1) && id != Token.NULL && styles[id].isBold())
- cf.append("");
- if (html && j == (length - 1) && id != Token.NULL)
- cf.append("");
-// int charWidth;
-// if (c == '\t') {
-// charWidth = (int) painter
-// .nextTabStop(width, offset + j)
-// - width;
-// } else {
-// charWidth = fm.charWidth(c);
-// }
-// width += charWidth;
- }
- offset += length;
- tokens = tokens.next;
+
+ Token tokenList = textarea.getTokenListForLine(line);
+
+ while(tokenList != null){
+ if(tokenList.getType() == Token.NULL){
+ cf.append('\n');
+ }else if(tokenList.isPaintable()){
+ tokenList.appendHTMLRepresentation(cf, textarea, false);
+ }
+
+ tokenList = tokenList.getNextToken();
}
+
}
}
}
diff --git a/app/test/cc/arduino/packages/contributions/GPGDetachedSignatureVerifierTest.java b/app/test/cc/arduino/packages/contributions/GPGDetachedSignatureVerifierTest.java
new file mode 100644
index 000000000..c4b4c8633
--- /dev/null
+++ b/app/test/cc/arduino/packages/contributions/GPGDetachedSignatureVerifierTest.java
@@ -0,0 +1,66 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package cc.arduino.packages.contributions;
+
+import cc.arduino.contributions.GPGDetachedSignatureVerifier;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class GPGDetachedSignatureVerifierTest {
+
+ private GPGDetachedSignatureVerifier GPGDetachedSignatureVerifier;
+
+ @Before
+ public void setUp() throws Exception {
+ GPGDetachedSignatureVerifier = new GPGDetachedSignatureVerifier();
+ }
+
+ @Test
+ public void testSignatureSuccessfulVerification() throws Exception {
+ File signedFile = new File(GPGDetachedSignatureVerifierTest.class.getResource("./package_index.json").getFile());
+ File sign = new File(GPGDetachedSignatureVerifierTest.class.getResource("./package_index.json.sig").getFile());
+ File publickKey = new File(GPGDetachedSignatureVerifierTest.class.getResource("./public.gpg.key").getFile());
+ assertTrue(GPGDetachedSignatureVerifier.verify(signedFile, sign, publickKey));
+ }
+
+ @Test
+ public void testSignatureFailingVerification() throws Exception {
+ File fakeSignedFile = File.createTempFile("fakeSigned", "txt");
+ fakeSignedFile.deleteOnExit();
+ File sign = new File(GPGDetachedSignatureVerifierTest.class.getResource("./package_index.json.sig").getFile());
+ File publickKey = new File(GPGDetachedSignatureVerifierTest.class.getResource("./public.gpg.key").getFile());
+ assertFalse(GPGDetachedSignatureVerifier.verify(fakeSignedFile, sign, publickKey));
+ }
+}
diff --git a/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionStub.java b/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionStub.java
new file mode 100644
index 000000000..b751d261f
--- /dev/null
+++ b/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionStub.java
@@ -0,0 +1,65 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package cc.arduino.packages.contributions;
+
+import cc.arduino.contributions.packages.HostDependentDownloadableContribution;
+
+public class HostDependentDownloadableContributionStub extends HostDependentDownloadableContribution {
+
+ @Override
+ public String getVersion() {
+ return null;
+ }
+
+ @Override
+ public String getHost() {
+ return null;
+ }
+
+ @Override
+ public String getUrl() {
+ return null;
+ }
+
+ @Override
+ public String getChecksum() {
+ return null;
+ }
+
+ @Override
+ public long getSize() {
+ return 0;
+ }
+
+ @Override
+ public String getArchiveFileName() {
+ return null;
+ }
+}
diff --git a/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionTest.java b/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionTest.java
new file mode 100644
index 000000000..8174f26d6
--- /dev/null
+++ b/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionTest.java
@@ -0,0 +1,112 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package cc.arduino.packages.contributions;
+
+import org.junit.Test;
+import processing.app.Platform;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class HostDependentDownloadableContributionTest {
+
+ @Test
+ public void macOsXPositiveTest() {
+ HostDependentDownloadableContributionStub contribution = new HostDependentDownloadableContributionStub() {
+ @Override
+ public String getHost() {
+ return "x86_64-apple-darwin";
+ }
+ };
+
+ Platform platform = new Platform() {
+ @Override
+ public String getOsName() {
+ return "Mac OS X";
+ }
+
+ @Override
+ public String getOsArch() {
+ return "x86_64";
+ }
+ };
+
+ assertTrue(contribution.isCompatible(platform));
+ }
+
+ @Test
+ public void macOsXNegativeTest() {
+ HostDependentDownloadableContributionStub contribution = new HostDependentDownloadableContributionStub() {
+ @Override
+ public String getHost() {
+ return "x86_64-apple-darwin";
+ }
+ };
+
+ Platform platform = new Platform() {
+ @Override
+ public String getOsName() {
+ return "Linux";
+ }
+
+ @Override
+ public String getOsArch() {
+ return "amd64";
+ }
+ };
+
+ assertFalse(contribution.isCompatible(platform));
+ }
+
+ @Test
+ public void macOsXNegativeTest2() {
+ HostDependentDownloadableContributionStub contribution = new HostDependentDownloadableContributionStub() {
+ @Override
+ public String getHost() {
+ return "x86_64-apple-darwin";
+ }
+ };
+
+ Platform platform = new Platform() {
+ @Override
+ public String getOsName() {
+ return "Mac OS X";
+ }
+
+ @Override
+ public String getOsArch() {
+ return "i686";
+ }
+ };
+
+ assertFalse(contribution.isCompatible(platform));
+ }
+
+}
diff --git a/app/test/cc/arduino/packages/contributions/package_index.json b/app/test/cc/arduino/packages/contributions/package_index.json
new file mode 100644
index 000000000..7b0cb6781
--- /dev/null
+++ b/app/test/cc/arduino/packages/contributions/package_index.json
@@ -0,0 +1,757 @@
+{
+ "packages": [
+ {
+ "name": "arduino",
+ "maintainer": "Arduino",
+ "websiteURL": "http://www.arduino.cc/",
+ "email": "packages@arduino.cc",
+ "help": {
+ "online": "http://arduino.cc/en/Reference/HomePage"
+ },
+ "platforms": [
+ {
+ "name": "Arduino AVR Boards",
+ "architecture": "avr",
+ "version": "1.6.2",
+ "category": "Arduino",
+ "url": "http://downloads.arduino.cc/cores/avr-1.6.2.tar.bz2",
+ "archiveFileName": "avr-1.6.2.tar.bz2",
+ "checksum": "SHA-256:2909a4c6dd6d7497e7e1b5fcaa2f66a100271417510f3a68593b65af8ff78c1c",
+ "size": "4877442",
+ "boards": [
+ {"name": "Arduino Yún"},
+ {"name": "Arduino Uno"},
+ {"name": "Arduino Diecimila"},
+ {"name": "Arduino Nano"},
+ {"name": "Arduino Mega"},
+ {"name": "Arduino MegaADK"},
+ {"name": "Arduino Leonardo"},
+ {"name": "Arduino Micro"},
+ {"name": "Arduino Esplora"},
+ {"name": "Arduino Mini"},
+ {"name": "Arduino Ethernet"},
+ {"name": "Arduino Fio"},
+ {"name": "Arduino BT"},
+ {"name": "Arduino LilyPadUSB"},
+ {"name": "Arduino Lilypad"},
+ {"name": "Arduino Pro"},
+ {"name": "Arduino ATMegaNG"},
+ {"name": "Arduino Robot Control"},
+ {"name": "Arduino Robot Motor"}
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "arduino",
+ "name": "avr-gcc",
+ "version": "4.8.1-arduino2"
+ },
+ {
+ "packager": "arduino",
+ "name": "avrdude",
+ "version": "6.0.1-arduino2"
+ }
+ ]
+ },
+ {
+ "name": "Arduino AVR Boards",
+ "architecture": "avr",
+ "version": "1.6.3",
+ "category": "Arduino",
+ "help": {
+ "online": "http://arduino.cc/en/Reference/HomePage"
+ },
+ "url": "http://downloads.arduino.cc/cores/avr-1.6.3.tar.bz2",
+ "archiveFileName": "avr-1.6.3.tar.bz2",
+ "checksum": "SHA-256:c30033ba70cbb2d46ee0901a331b0f83be082f9110eda0464b624fdbb51b3c7b",
+ "size": "4876816",
+ "boards": [
+ {"name": "Arduino Yún"},
+ {"name": "Arduino Uno"},
+ {"name": "Arduino Diecimila"},
+ {"name": "Arduino Nano"},
+ {"name": "Arduino Mega"},
+ {"name": "Arduino MegaADK"},
+ {"name": "Arduino Leonardo"},
+ {"name": "Arduino Micro"},
+ {"name": "Arduino Esplora"},
+ {"name": "Arduino Mini"},
+ {"name": "Arduino Ethernet"},
+ {"name": "Arduino Fio"},
+ {"name": "Arduino BT"},
+ {"name": "Arduino LilyPadUSB"},
+ {"name": "Arduino Lilypad"},
+ {"name": "Arduino Pro"},
+ {"name": "Arduino ATMegaNG"},
+ {"name": "Arduino Robot Control"},
+ {"name": "Arduino Robot Motor"}
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "arduino",
+ "name": "avr-gcc",
+ "version": "4.8.1-arduino3"
+ },
+ {
+ "packager": "arduino",
+ "name": "avrdude",
+ "version": "6.0.1-arduino3"
+ }
+ ]
+ },
+ {
+ "name": "Arduino AVR Boards",
+ "architecture": "avr",
+ "version": "1.6.4",
+ "category": "Arduino",
+ "help": {
+ "online": "http://arduino.cc/en/Reference/HomePage"
+ },
+ "url": "http://downloads.arduino.cc/cores/avr-1.6.4.tar.bz2",
+ "archiveFileName": "avr-1.6.4.tar.bz2",
+ "checksum": "SHA-256:8a243410aeded6dbcbc4b134ba10be5c2562d137bfcf3ac97abdc5844933b363",
+ "size": "4780884",
+ "boards": [
+ {"name": "Arduino Yún"},
+ {"name": "Arduino Uno"},
+ {"name": "Arduino Diecimila"},
+ {"name": "Arduino Nano"},
+ {"name": "Arduino Mega"},
+ {"name": "Arduino MegaADK"},
+ {"name": "Arduino Leonardo"},
+ {"name": "Arduino Micro"},
+ {"name": "Arduino Esplora"},
+ {"name": "Arduino Mini"},
+ {"name": "Arduino Ethernet"},
+ {"name": "Arduino Fio"},
+ {"name": "Arduino BT"},
+ {"name": "Arduino LilyPadUSB"},
+ {"name": "Arduino Lilypad"},
+ {"name": "Arduino Pro"},
+ {"name": "Arduino ATMegaNG"},
+ {"name": "Arduino Robot Control"},
+ {"name": "Arduino Robot Motor"}
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "arduino",
+ "name": "avr-gcc",
+ "version": "4.8.1-arduino5"
+ },
+ {
+ "packager": "arduino",
+ "name": "avrdude",
+ "version": "6.0.1-arduino5"
+ }
+ ]
+ },
+ {
+ "name": "Arduino AVR Boards",
+ "architecture": "avr",
+ "version": "1.6.5",
+ "category": "Arduino",
+ "help": {
+ "online": "http://arduino.cc/en/Reference/HomePage"
+ },
+ "url": "http://downloads.arduino.cc/cores/avr-1.6.5.tar.bz2",
+ "archiveFileName": "avr-1.6.5.tar.bz2",
+ "checksum": "SHA-256:c72d890aa605add677634c6b25ebc3b2ed9e44c38805b95c47eab17a1ca72db6",
+ "size": "4876957",
+ "boards": [
+ {"name": "Arduino Yún"},
+ {"name": "Arduino Uno"},
+ {"name": "Arduino Diecimila"},
+ {"name": "Arduino Nano"},
+ {"name": "Arduino Mega"},
+ {"name": "Arduino MegaADK"},
+ {"name": "Arduino Leonardo"},
+ {"name": "Arduino Micro"},
+ {"name": "Arduino Esplora"},
+ {"name": "Arduino Mini"},
+ {"name": "Arduino Ethernet"},
+ {"name": "Arduino Fio"},
+ {"name": "Arduino BT"},
+ {"name": "Arduino LilyPadUSB"},
+ {"name": "Arduino Lilypad"},
+ {"name": "Arduino Pro"},
+ {"name": "Arduino ATMegaNG"},
+ {"name": "Arduino Robot Control"},
+ {"name": "Arduino Robot Motor"}
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "arduino",
+ "name": "avr-gcc",
+ "version": "4.8.1-arduino5"
+ },
+ {
+ "packager": "arduino",
+ "name": "avrdude",
+ "version": "6.0.1-arduino5"
+ }
+ ]
+ },
+ {
+ "name": "Arduino AVR Boards",
+ "architecture": "avr",
+ "version": "1.6.6",
+ "category": "Arduino",
+ "help": {
+ "online": "http://arduino.cc/en/Reference/HomePage"
+ },
+ "url": "http://downloads.arduino.cc/cores/avr-1.6.6.tar.bz2",
+ "archiveFileName": "avr-1.6.6.tar.bz2",
+ "checksum": "SHA-256:08ad5db4978ebea22344edc5d77dce0923d8a644da7a14dc8072e883c76058d8",
+ "size": "4876916",
+ "boards": [
+ {"name": "Arduino Yún"},
+ {"name": "Arduino Uno"},
+ {"name": "Arduino Diecimila"},
+ {"name": "Arduino Nano"},
+ {"name": "Arduino Mega"},
+ {"name": "Arduino MegaADK"},
+ {"name": "Arduino Leonardo"},
+ {"name": "Arduino Micro"},
+ {"name": "Arduino Esplora"},
+ {"name": "Arduino Mini"},
+ {"name": "Arduino Ethernet"},
+ {"name": "Arduino Fio"},
+ {"name": "Arduino BT"},
+ {"name": "Arduino LilyPadUSB"},
+ {"name": "Arduino Lilypad"},
+ {"name": "Arduino Pro"},
+ {"name": "Arduino ATMegaNG"},
+ {"name": "Arduino Robot Control"},
+ {"name": "Arduino Robot Motor"}
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "arduino",
+ "name": "avr-gcc",
+ "version": "4.8.1-arduino5"
+ },
+ {
+ "packager": "arduino",
+ "name": "avrdude",
+ "version": "6.0.1-arduino5"
+ }
+ ]
+ },
+ {
+ "name": "Arduino SAM Boards (32-bits ARM Cortex-M3)",
+ "architecture": "sam",
+ "version": "1.6.2",
+ "category": "Arduino",
+ "url": "http://downloads.arduino.cc/cores/sam-1.6.2.tar.bz2",
+ "archiveFileName": "sam-1.6.2.tar.bz2",
+ "checksum": "SHA-256:2d3c8a90bc214947cff1b816d0c2706441398efc78af7984d5250f2e50eddd5f",
+ "size": "16174730",
+ "boards": [
+ {"name": "Arduino Due"}
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "arduino",
+ "name": "arm-none-eabi-gcc",
+ "version": "4.8.3-2014q1"
+ },
+ {
+ "packager": "arduino",
+ "name": "bossac",
+ "version": "1.3a-arduino"
+ }
+ ]
+ },
+ {
+ "name": "Arduino SAM Boards (32-bits ARM Cortex-M3)",
+ "architecture": "sam",
+ "version": "1.6.3",
+ "category": "Arduino",
+ "url": "http://downloads.arduino.cc/cores/sam-1.6.3.tar.bz2",
+ "archiveFileName": "sam-1.6.3.tar.bz2",
+ "checksum": "SHA-256:0a6e1d5542790e38ba454c796aabbd0e48b07635a5b4d8adc044a4eba959ca27",
+ "size": "16174017",
+ "boards": [
+ {"name": "Arduino Due"}
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "arduino",
+ "name": "arm-none-eabi-gcc",
+ "version": "4.8.3-2014q1"
+ },
+ {
+ "packager": "arduino",
+ "name": "bossac",
+ "version": "1.3a-arduino"
+ }
+ ]
+ },
+ {
+ "name": "Arduino SAM Boards (32-bits ARM Cortex-M3)",
+ "architecture": "sam",
+ "version": "1.6.4",
+ "category": "Arduino",
+ "url": "http://downloads.arduino.cc/cores/sam-1.6.4.tar.bz2",
+ "archiveFileName": "sam-1.6.4.tar.bz2",
+ "checksum": "SHA-256:e0dc94d8ad0756b79838e99ad7409b08b07e40ed667ebe86eae11644ef7bec0d",
+ "size": "16174992",
+ "boards": [
+ {"name": "Arduino Due"}
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "arduino",
+ "name": "arm-none-eabi-gcc",
+ "version": "4.8.3-2014q1"
+ },
+ {
+ "packager": "arduino",
+ "name": "bossac",
+ "version": "1.3a-arduino"
+ }
+ ]
+ }
+ ],
+ "tools": [
+ {
+ "name": "arm-none-eabi-gcc",
+ "version": "4.8.3-2014q1",
+ "systems": [
+ {
+ "host": "i686-mingw32",
+ "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-windows.tar.gz",
+ "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-windows.tar.gz",
+ "checksum": "SHA-256:fd8c111c861144f932728e00abd3f7d1107e186eb9cd6083a54c7236ea78b7c2",
+ "size": "84537449"
+ },
+ {
+ "host": "x86_64-apple-darwin",
+ "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-mac.tar.gz",
+ "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-mac.tar.gz",
+ "checksum": "SHA-256:3598acf21600f17a8e4a4e8e193dc422b894dc09384759b270b2ece5facb59c2",
+ "size": "52518522"
+ },
+ {
+ "host": "x86_64-pc-linux-gnu",
+ "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-linux64.tar.gz",
+ "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-linux64.tar.gz",
+ "checksum": "SHA-256:d23f6626148396d6ec42a5b4d928955a703e0757829195fa71a939e5b86eecf6",
+ "size": "51395093"
+ },
+ {
+ "host": "i686-pc-linux-gnu",
+ "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-linux32.tar.gz",
+ "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-linux32.tar.gz",
+ "checksum": "SHA-256:ba1994235f69c526c564f65343f22ddbc9822b2ea8c5ee07dd79d89f6ace2498",
+ "size": "51029223"
+ }
+ ]
+ },
+ {
+ "name": "bossac",
+ "version": "1.3a-arduino",
+ "systems": [
+ {
+ "host": "i686-linux-gnu",
+ "url": "http://downloads.arduino.cc/tools/bossac-1.3a-arduino-i686-linux-gnu.tar.bz2",
+ "archiveFileName": "bossac-1.3a-arduino-i686-linux-gnu.tar.bz2",
+ "checksum": "SHA-256:d6d10362f40729a7877e43474fcf02ad82cf83321cc64ca931f5c82b2d25d24f",
+ "size": "147359"
+ },
+ {
+ "host": "x86_64-pc-linux-gnu",
+ "url": "http://downloads.arduino.cc/tools/bossac-1.3a-arduino-x86_64-pc-linux-gnu.tar.bz2",
+ "archiveFileName": "bossac-1.3a-arduino-x86_64-pc-linux-gnu.tar.bz2",
+ "checksum": "SHA-256:c1daed033251296768fa8b63ad283e053da93427c0f3cd476a71a9188e18442c",
+ "size": "26179"
+ },
+ {
+ "host": "i686-mingw32",
+ "url": "http://downloads.arduino.cc/tools/bossac-1.3a-arduino-i686-mingw32.tar.bz2",
+ "archiveFileName": "bossac-1.3a-arduino-i686-mingw32.tar.bz2",
+ "checksum": "SHA-256:a37727622e0f86cb4f2856ad0209568a5d804234dba3dc0778829730d61a5ec7",
+ "size": "265647"
+ },
+ {
+ "host": "i386-apple-darwin11",
+ "url": "http://downloads.arduino.cc/tools/bossac-1.3a-arduino-i386-apple-darwin11.tar.bz2",
+ "archiveFileName": "bossac-1.3a-arduino-i386-apple-darwin11.tar.bz2",
+ "checksum": "SHA-256:40770b225753e7a52bb165e8f37e6b760364f5c5e96048168d0178945bd96ad6",
+ "size": "39475"
+ }
+ ]
+ },
+ {
+ "name": "avr-gcc",
+ "version": "4.8.1-arduino2",
+ "systems": [
+ {
+ "size": "24443285",
+ "checksum": "SHA-256:c19a7526235c364d7f62ec1a993d9b495973ba1813869ccf0241c65905896852",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "avr-gcc-4.8.1-arduino2-i386-apple-darwin11.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino2-i386-apple-darwin11.tar.bz2"
+ },
+ {
+ "size": "27152002",
+ "checksum": "SHA-256:24a931877bee5f36dc00a88877219a6d2f6a1fb7abb989fd04556b8432d2e14e",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "avr-gcc-4.8.1-arduino2-x86_64-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino2-x86_64-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "25876628",
+ "checksum": "SHA-256:2d701b4efbc8cec62dc299cde01730c5eebcf23d7e4393db8cf7744a9bf1d3de",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "avr-gcc-4.8.1-arduino2-i686-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino2-i686-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "46046691",
+ "checksum": "SHA-256:2eafb49fb803fa4d2c32d35e24c0b372fcd520ca0a790fa537a847179e382000",
+ "host": "i686-mingw32",
+ "archiveFileName": "avr-gcc-4.8.1-arduino2-i686-mingw32.zip",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino2-i686-mingw32.zip"
+ }
+ ]
+ },
+ {
+ "name": "avrdude",
+ "version": "6.0.1-arduino2",
+ "systems": [
+ {
+ "size": "264965",
+ "checksum": "SHA-256:71117cce0096dad6c091e2c34eb0b9a3386d3aec7d863d2da733d9e5eac3a6b1",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "avrdude-6.0.1-arduino2-i386-apple-darwin11.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i386-apple-darwin11.tar.bz2"
+ },
+ {
+ "size": "292541",
+ "checksum": "SHA-256:2489004d1d98177eaf69796760451f89224007c98b39ebb5577a9a34f51425f1",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "avrdude-6.0.1-arduino2-x86_64-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-x86_64-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "283209",
+ "checksum": "SHA-256:6f633dd6270ad0d9ef19507bcbf8697b414a15208e4c0f71deec25ef89cdef3f",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "avrdude-6.0.1-arduino2-i686-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i686-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "241618",
+ "checksum": "SHA-256:6c5483800ba753c80893607e30cade8ab77b182808fcc5ea15fa3019c63d76ae",
+ "host": "i686-mingw32",
+ "archiveFileName": "avrdude-6.0.1-arduino2-i686-mingw32.zip",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i686-mingw32.zip"
+ }
+ ]
+ },
+ {
+ "name": "avr-gcc",
+ "version": "4.8.1-arduino3",
+ "systems": [
+ {
+ "size": "24447175",
+ "checksum": "SHA-256:28e207c66b3dc405367d0c5e68ce3c278e5ec3abb0e4974e7927fe0f9a532c40",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "avr-gcc-4.8.1-arduino3-i386-apple-darwin11.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino3-i386-apple-darwin11.tar.bz2"
+ },
+ {
+ "size": "30556996",
+ "checksum": "SHA-256:028340abec6eb3085b82404dfc7ed143e1bb05b2da961b539ddcdba4a6f65533",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "avr-gcc-4.8.1-arduino3-x86_64-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino3-x86_64-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "28768022",
+ "checksum": "SHA-256:37796548ba9653267568f959cd8c7ebfe5b4bce4599898cf9f876d64e616cb87",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "avr-gcc-4.8.1-arduino3-i686-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino3-i686-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "46046917",
+ "checksum": "SHA-256:d6f0527793f9800f060408392a99eb290ed205730edbae43a1a25cbf6b6b588f",
+ "host": "i686-mingw32",
+ "archiveFileName": "avr-gcc-4.8.1-arduino3-i686-mingw32.zip",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino3-i686-mingw32.zip"
+ }
+ ]
+ },
+ {
+ "name": "avrdude",
+ "version": "6.0.1-arduino3",
+ "systems": [
+ {
+ "size": "264682",
+ "checksum": "SHA-256:df7cd4a76e45ab3767eb964f845f4d5e9d643df950ec32812923da1e9843d072",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "avrdude-6.0.1-arduino3-i386-apple-darwin11.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino3-i386-apple-darwin11.tar.bz2"
+ },
+ {
+ "size": "748634",
+ "checksum": "SHA-256:bb7bff48f20a68e1fe559c3f3f644574df12ab5c98eb6a1491079f3c760434ad",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "avrdude-6.0.1-arduino3-x86_64-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino3-x86_64-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "495482",
+ "checksum": "SHA-256:96a0cfb83fe0452366159e3bf4e19ff10906a8957d1feafd3d98b49ab4b14405",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "avrdude-6.0.1-arduino3-i686-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino3-i686-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "241619",
+ "checksum": "SHA-256:ea59bfc2ee85039c85318b2ba52c47ef0573513444a785b72f59b22586a950f9",
+ "host": "i686-mingw32",
+ "archiveFileName": "avrdude-6.0.1-arduino3-i686-mingw32.zip",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino3-i686-mingw32.zip"
+ }
+ ]
+ },
+ {
+ "name": "avr-gcc",
+ "version": "4.8.1-arduino5",
+ "systems": [
+ {
+ "size": "24437400",
+ "checksum": "SHA-256:111b3ef00d737d069eb237a8933406cbb928e4698689e24663cffef07688a901",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "avr-gcc-4.8.1-arduino5-i386-apple-darwin11.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-i386-apple-darwin11.tar.bz2"
+ },
+ {
+ "size": "27093036",
+ "checksum": "SHA-256:9054fcc174397a419ba56c4ce1bfcbcad275a6a080cc144905acc9b0351ee9cc",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "avr-gcc-4.8.1-arduino5-x86_64-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-x86_64-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "25882375",
+ "checksum": "SHA-256:7648b7f549b37191da0b0be53bae791b652f82ac3cb4e7877f85075aaf32141f",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "avr-gcc-4.8.1-arduino5-i686-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-i686-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "46044779",
+ "checksum": "SHA-256:d4303226a7b41d3c445d901b5aa5903458def3fc7b7ff4ffef37cabeb37d424d",
+ "host": "i686-mingw32",
+ "archiveFileName": "avr-gcc-4.8.1-arduino5-i686-mingw32.zip",
+ "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-i686-mingw32.zip"
+ }
+ ]
+ },
+ {
+ "name": "avrdude",
+ "version": "6.0.1-arduino5",
+ "systems": [
+ {
+ "size": "264894",
+ "checksum": "SHA-256:41af8d3b0a586853c8317b4fb5163ca0db594a1870ddf680fd988c42166fc3e5",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "avrdude-6.0.1-arduino5-i386-apple-darwin11.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-i386-apple-darwin11.tar.bz2"
+ },
+ {
+ "size": "292629",
+ "checksum": "SHA-256:d826cca7383461f7e8adde686372cf900e9cb3afd639555cf2d6c645b283a476",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "avrdude-6.0.1-arduino5-x86_64-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-x86_64-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "283121",
+ "checksum": "SHA-256:5933d66927bce46ababa9b68a8b7f1d53f68c4f3ff7a5ce4b85d7cf4e6c6bfee",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "avrdude-6.0.1-arduino5-i686-pc-linux-gnu.tar.bz2",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-i686-pc-linux-gnu.tar.bz2"
+ },
+ {
+ "size": "241634",
+ "checksum": "SHA-256:41f667f1f6a0ab8df46b4ffacd023176dcdef331d6db3b74bddd37d18cca0a44",
+ "host": "i686-mingw32",
+ "archiveFileName": "avrdude-6.0.1-arduino5-i686-mingw32.zip",
+ "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-i686-mingw32.zip"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "email": "support@intel.com",
+ "maintainer": "Intel",
+ "websiteURL": "http://www.intel.com/",
+ "name": "Intel",
+ "platforms": [
+ {
+ "name": "Intel i586 Boards",
+ "version": "1.6.2+1.0",
+ "category": "Arduino Certified",
+ "architecture": "i586",
+ "url": "https://github.com/01org/corelibs-galileo/archive/1.6.2+1.0.tar.gz",
+ "archiveFileName": "corelibs-galileo-1.6.2.tar.gz",
+ "checksum": "SHA-256:e20d62b0dccf0d68dbb61d70b866d77134b770b226d6046a61c7e8d55e64e53a",
+ "size": "272961",
+ "boards": [
+ {
+ "name": "Galileo"
+ }
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "Intel",
+ "name": "i586-poky-linux-uclibc",
+ "version": "1.6.2+1.0"
+ },
+ {
+ "packager": "Intel",
+ "name": "sketchUploader",
+ "version": "1.6.2+1.0"
+ }
+ ]
+ },
+ {
+ "name": "Intel i686 Boards",
+ "version": "1.6.2+1.0",
+ "category": "Arduino Certified",
+ "architecture": "i686",
+ "url": "https://github.com/01org/corelibs-edison/archive/1.6.2+1.0.tar.gz",
+ "archiveFileName": "corelibs-edison-1.6.2.tar.gz",
+ "checksum": "SHA-256:538ab8553f832f56b04df80d44992ecc994b9c296f3fce6902832d97f99811a8",
+ "size": "271420",
+ "boards": [
+ {
+ "name": "Edison"
+ }
+ ],
+ "toolsDependencies": [
+ {
+ "packager": "Intel",
+ "name": "core2-32-poky-linux",
+ "version": "1.6.2+1.0"
+ },
+ {
+ "packager": "Intel",
+ "name": "sketchUploader",
+ "version": "1.6.2+1.0"
+ }
+ ]
+ }
+ ],
+ "tools": [
+ {
+ "name": "i586-poky-linux-uclibc",
+ "version": "1.6.2+1.0",
+ "systems": [
+ {
+ "size": "30587705",
+ "checksum": "SHA-256:5b705d26dc1d8ca8953df6e0c08dcc8584d5be77b584d561f631360fd166677c",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "galileo-toolchain-20150323-osx.tar.bz2",
+ "url": "http://downloadmirror.intel.com/24806/eng/galileo-toolchain-osx-1.6.2-1.0.tar.bz2"
+ },
+ {
+ "size": "45948648",
+ "checksum": "SHA-256:821eb290d7c668c1caa74da30903c13843edc746d41508b35161622ae6279b56",
+ "host": "i686-mingw32",
+ "archiveFileName": "galileo-toolchain-20150323-windows.zip",
+ "url": "http://downloadmirror.intel.com/24806/eng/galileo-toolchain-windows-1.6.2-1.0.zip"
+ },
+ {
+ "size": "56227185",
+ "checksum": "SHA-256:935ccad3eaaec34f5de76eceb0f0ecd1372bdab0b7dc8f4241e8260c6f827b72",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "galileo-toolchain-20150316-linux64.tar.bz2",
+ "url": "http://downloadmirror.intel.com/24806/eng/galileo-toolchain-linux64-1.6.2-1.0.tar.bz2"
+ },
+ {
+ "size": "55098166",
+ "checksum": "SHA-256:1dab7f21e10d0208a6dd2897c36c6f5f55f9372b947225d2b59c3c4ab4777d03",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "galileo-toolchain-20150316-linux32.tar.bz2",
+ "url": "http://downloadmirror.intel.com/24806/eng/galileo-toolchain-linux32-1.6.2-1.0.tar.bz2"
+ }
+ ]
+ },
+ {
+ "name": "core2-32-poky-linux",
+ "version": "1.6.2+1.0",
+ "systems": [
+ {
+ "size": "42720934",
+ "checksum": "SHA-256:fac0b3f00a33ee0531ea0da6d517c170409e25bd5e59f6f3db9506974336375d",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "edison-toolchain-20150323-osx.tar.bz2",
+ "url": "http://downloadmirror.intel.com/24806/eng/edison-toolchain-osx-1.6.2-1.0.tar.bz2"
+ },
+ {
+ "size": "56683094",
+ "checksum": "SHA-256:5a9a1b51f0fa18bf21e1dcf1332d34331dd435c5ca0d1fe008e68e13cb3255e5",
+ "host": "i686-mingw32",
+ "archiveFileName": "edison-toolchain-20150323-windows.zip",
+ "url": "http://downloadmirror.intel.com/24806/eng/edison-toolchain-windows-1.6.2-1.0.zip"
+ },
+ {
+ "size": "78998436",
+ "checksum": "SHA-256:e3443e7832732f2189fd424e4868d2ebb563e823addb2321a6e8a86a9fced193",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "edison-toolchain-20150316-linux64.tar.bz2",
+ "url": "http://downloadmirror.intel.com/24806/eng/edison-toolchain-linux64-1.6.2-1.0.tar.bz2"
+ },
+ {
+ "size": "76488215",
+ "checksum": "SHA-256:014d1bdc40bb080987c736d04ffd42cdc0d2c3cad001891fb01555dac04296f7",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "edison-toolchain-20150316-linux32.tar.bz2",
+ "url": "http://downloadmirror.intel.com/24806/eng/edison-toolchain-linux32-1.6.2-1.0.tar.bz2"
+ }
+ ]
+ },
+ {
+ "name": "sketchUploader",
+ "version": "1.6.2+1.0",
+ "systems": [
+ {
+ "size": "61789",
+ "checksum": "SHA-256:8395ccb57c627f997fe01170df4613de906f48c6ce99623b9ca42806079c28ad",
+ "host": "i386-apple-darwin11",
+ "archiveFileName": "intel-arduino-tools-20150316-osx.tar.gz",
+ "url": "https://github.com/01org/intel-arduino-tools/archive/1.6.2+1.0-osx.tar.gz"
+ },
+ {
+ "size": "2534586",
+ "checksum": "SHA-256:47f0b1558653d09f6f1e5d21a9cdef379be96c9147711cf54f013f73e4deed11",
+ "host": "i686-mingw32",
+ "archiveFileName": "intel-arduino-tools-20150316-windows.zip",
+ "url": "https://github.com/01org/intel-arduino-tools/archive/1.6.2+1.0-windows.zip"
+ },
+ {
+ "size": "178239",
+ "checksum": "SHA-256:2876db4153db22609d2f6c9c3bfb198efbb9d9574edad579aca7d58cff9d2cca",
+ "host": "x86_64-linux-gnu",
+ "archiveFileName": "intel-arduino-tools-20150316-linux64.tar.gz",
+ "url": "https://github.com/01org/intel-arduino-tools/archive/1.6.2+1.0-linux64.tar.gz"
+ },
+ {
+ "size": "187995",
+ "checksum": "SHA-256:20d87602d0194be626f592d3f2bdc9566a5a897786b042393482ef4c26ae158c",
+ "host": "i686-linux-gnu",
+ "archiveFileName": "intel-arduino-tools-20150316-linux32.tar.gz",
+ "url": "https://github.com/01org/intel-arduino-tools/archive/1.6.2+1.0-linux32.tar.gz"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/app/test/cc/arduino/packages/contributions/package_index.json.sig b/app/test/cc/arduino/packages/contributions/package_index.json.sig
new file mode 100644
index 000000000..10c7ff659
Binary files /dev/null and b/app/test/cc/arduino/packages/contributions/package_index.json.sig differ
diff --git a/app/test/cc/arduino/packages/contributions/public.gpg.key b/app/test/cc/arduino/packages/contributions/public.gpg.key
new file mode 100644
index 000000000..5de39fed1
Binary files /dev/null and b/app/test/cc/arduino/packages/contributions/public.gpg.key differ
diff --git a/app/test/processing/app/AbstractGUITest.java b/app/test/processing/app/AbstractGUITest.java
index b5a209bb0..b4fe19db0 100644
--- a/app/test/processing/app/AbstractGUITest.java
+++ b/app/test/processing/app/AbstractGUITest.java
@@ -1,5 +1,35 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
+import cc.arduino.files.DeleteFilesOnShutdown;
import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
import org.fest.swing.edt.GuiActionRunner;
import org.fest.swing.edt.GuiQuery;
@@ -15,6 +45,9 @@ public abstract class AbstractGUITest {
@Before
public void startUpTheIDE() throws Exception {
+ System.setProperty("mrj.version", "whynot"); //makes sense only on osx. See https://github.com/alexruiz/fest-swing-1.x/issues/2#issuecomment-86532042
+ Runtime.getRuntime().addShutdownHook(new Thread(DeleteFilesOnShutdown.INSTANCE));
+
FailOnThreadViolationRepaintManager.install();
Base.initPlatform();
@@ -23,7 +56,7 @@ public abstract class AbstractGUITest {
Theme.init();
Base.getPlatform().setLookAndFeel();
Base.untitledFolder = Base.createTempFolder("untitled");
- Base.untitledFolder.deleteOnExit();
+ DeleteFilesOnShutdown.add(Base.untitledFolder);
window = GuiActionRunner.execute(new GuiQuery() {
@Override
diff --git a/app/test/processing/app/AbstractWithPreferencesTest.java b/app/test/processing/app/AbstractWithPreferencesTest.java
index ca07ec385..7ee6e2195 100644
--- a/app/test/processing/app/AbstractWithPreferencesTest.java
+++ b/app/test/processing/app/AbstractWithPreferencesTest.java
@@ -1,17 +1,51 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
+import cc.arduino.files.DeleteFilesOnShutdown;
import org.junit.Before;
public abstract class AbstractWithPreferencesTest {
@Before
public void init() throws Exception {
+ Runtime.getRuntime().addShutdownHook(new Thread(DeleteFilesOnShutdown.INSTANCE));
Base.initPlatform();
+ Base.getPlatform().init();
Preferences.init(null);
Theme.init();
- Base.untitledFolder = Base.createTempFolder("untitled");
- Base.untitledFolder.deleteOnExit();
+ BaseNoGui.initPackages();
+ Base.untitledFolder = Base.createTempFolder("untitled");
+ DeleteFilesOnShutdown.add(Base.untitledFolder);
}
+
}
diff --git a/app/test/processing/app/AutoformatProducesOneUndoActionTest.java b/app/test/processing/app/AutoformatProducesOneUndoActionTest.java
new file mode 100644
index 000000000..8c5243a66
--- /dev/null
+++ b/app/test/processing/app/AutoformatProducesOneUndoActionTest.java
@@ -0,0 +1,85 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app;
+
+import org.fest.swing.fixture.JMenuItemFixture;
+import org.junit.Test;
+import processing.app.helpers.SketchTextAreaFixture;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+public class AutoformatProducesOneUndoActionTest extends AbstractGUITest {
+
+ public static final String SOURCE_BEFORE = "void setup() {\n" +
+ " // put your setup code here, to run once:\n" +
+ "\n" +
+ "}\n" +
+ "\n" +
+ "void loop() {\n" +
+ " // put your main code here, to run repeatedly:\n" +
+ "\n" +
+ "}";
+ public static final String SOURCE_AFTER = "void setup() {\n" +
+ " // put your setup code here, to run once:\n" +
+ "\n" +
+ "}\n" +
+ "\n" +
+ "void loop() {\n" +
+ " // put your main code here, to run repeatedly:\n" +
+ "\n" +
+ "}";
+
+ @Test
+ public void shouldSaveCaretPositionAfterAutoformat() {
+ JMenuItemFixture menuEditUndo = window.menuItem("menuEditUndo");
+ menuEditUndo.requireDisabled();
+
+ JMenuItemFixture menuToolsAutoFormat = window.menuItem("menuToolsAutoFormat");
+ menuToolsAutoFormat.requireEnabled();
+
+ SketchTextAreaFixture editor = window.textArea("editor");
+ editor.setText(SOURCE_BEFORE);
+
+ editor.setCaretPosition(29); // right before the first // (double slash)
+
+ menuToolsAutoFormat.click();
+
+ String formattedText = editor.getText();
+ assertEquals(SOURCE_AFTER, formattedText);
+
+ assertEquals(29, editor.getCaretPosition());
+
+ menuEditUndo.requireEnabled();
+ menuEditUndo.click();
+ assertEquals(SOURCE_BEFORE, editor.getText());
+ }
+
+}
diff --git a/app/test/processing/app/AutoformatSavesCaretPositionTest.java b/app/test/processing/app/AutoformatSavesCaretPositionTest.java
index 8ffa03190..fb311707d 100644
--- a/app/test/processing/app/AutoformatSavesCaretPositionTest.java
+++ b/app/test/processing/app/AutoformatSavesCaretPositionTest.java
@@ -1,8 +1,37 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
import org.fest.swing.fixture.JMenuItemFixture;
import org.junit.Test;
-import processing.app.helpers.JEditTextAreaFixture;
+import processing.app.helpers.SketchTextAreaFixture;
import static org.junit.Assert.assertEquals;
@@ -13,7 +42,7 @@ public class AutoformatSavesCaretPositionTest extends AbstractGUITest {
JMenuItemFixture menuToolsAutoFormat = window.menuItem("menuToolsAutoFormat");
menuToolsAutoFormat.requireEnabled();
- JEditTextAreaFixture editor = window.jEditTextArea("editor");
+ SketchTextAreaFixture editor = window.textArea("editor");
editor.setText("void setup() {\n" +
" // put your setup code here, to run once:\n" +
"\n" +
diff --git a/app/test/processing/app/AutoformatTest.java b/app/test/processing/app/AutoformatTest.java
index 51fdc35d6..2b87b1757 100644
--- a/app/test/processing/app/AutoformatTest.java
+++ b/app/test/processing/app/AutoformatTest.java
@@ -1,8 +1,37 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
import org.fest.swing.fixture.JMenuItemFixture;
import org.junit.Test;
-import processing.app.helpers.JEditTextAreaFixture;
+import processing.app.helpers.SketchTextAreaFixture;
import static org.junit.Assert.assertEquals;
@@ -13,7 +42,7 @@ public class AutoformatTest extends AbstractGUITest {
JMenuItemFixture menuToolsAutoFormat = window.menuItem("menuToolsAutoFormat");
menuToolsAutoFormat.requireEnabled();
- JEditTextAreaFixture editor = window.jEditTextArea("editor");
+ SketchTextAreaFixture editor = window.textArea("editor");
editor.setText("void setup() {\n" +
"// put your setup code here, to run once:\n" +
"int foo[] = { 1, 2, 3, 4, 5};\n" +
diff --git a/app/test/processing/app/BlockCommentGeneratesOneUndoActionTest.java b/app/test/processing/app/BlockCommentGeneratesOneUndoActionTest.java
index 555a03fcc..411cb5de6 100644
--- a/app/test/processing/app/BlockCommentGeneratesOneUndoActionTest.java
+++ b/app/test/processing/app/BlockCommentGeneratesOneUndoActionTest.java
@@ -1,14 +1,44 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
+import static org.junit.Assert.assertEquals;
+
+import java.awt.Frame;
+
import org.fest.swing.edt.GuiActionRunner;
import org.fest.swing.edt.GuiQuery;
import org.fest.swing.fixture.JMenuItemFixture;
import org.junit.Test;
-import processing.app.helpers.JEditTextAreaFixture;
-import java.awt.*;
-
-import static org.junit.Assert.assertEquals;
+import processing.app.helpers.SketchTextAreaFixture;
public class BlockCommentGeneratesOneUndoActionTest extends AbstractGUITest {
@@ -17,7 +47,7 @@ public class BlockCommentGeneratesOneUndoActionTest extends AbstractGUITest {
JMenuItemFixture menuEditUndo = window.menuItem("menuEditUndo");
menuEditUndo.requireDisabled();
- JEditTextAreaFixture jEditTextArea = window.jEditTextArea("editor");
+ SketchTextAreaFixture jEditTextArea = window.textArea("editor");
String previousText = jEditTextArea.getText();
jEditTextArea.selectAll();
diff --git a/app/test/processing/app/DefaultTargetTest.java b/app/test/processing/app/DefaultTargetTest.java
index e2641e36a..37819c84c 100644
--- a/app/test/processing/app/DefaultTargetTest.java
+++ b/app/test/processing/app/DefaultTargetTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
import org.junit.After;
@@ -14,18 +43,18 @@ public class DefaultTargetTest extends AbstractWithPreferencesTest {
@Before
public void saveBoardFromPreferences() throws Exception {
- oldBoardID = Preferences.get("board");
+ oldBoardID = PreferencesData.get("board");
}
@After
public void restoreBoardIntoPreferences() throws Exception {
- Preferences.set("board", oldBoardID);
- Preferences.save();
+ PreferencesData.set("board", oldBoardID);
+ PreferencesData.save();
}
@Test
public void testDefaultTarget() throws Exception {
- Preferences.set("board", "unreal_board");
+ PreferencesData.set("board", "unreal_board");
// should not raise an exception
new Base(new String[0]);
diff --git a/app/test/processing/app/HittingEscapeOnCloseConfirmationDialogTest.java b/app/test/processing/app/HittingEscapeOnCloseConfirmationDialogTest.java
index c760ef29b..b56559659 100644
--- a/app/test/processing/app/HittingEscapeOnCloseConfirmationDialogTest.java
+++ b/app/test/processing/app/HittingEscapeOnCloseConfirmationDialogTest.java
@@ -1,10 +1,39 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
import org.fest.swing.core.KeyPressInfo;
import org.fest.swing.finder.WindowFinder;
import org.fest.swing.fixture.DialogFixture;
import org.junit.Test;
-import processing.app.helpers.JEditTextAreaFixture;
+import processing.app.helpers.SketchTextAreaFixture;
import javax.swing.*;
import java.awt.event.KeyEvent;
@@ -15,7 +44,7 @@ public class HittingEscapeOnCloseConfirmationDialogTest extends AbstractGUITest
@Test
public void shouldJustCloseTheDialog() throws Exception {
- JEditTextAreaFixture editor = window.jEditTextArea("editor");
+ SketchTextAreaFixture editor = window.textArea("editor");
editor.setText("test");
window.close();
diff --git a/app/test/processing/app/I18NTest.java b/app/test/processing/app/I18NTest.java
index 74c231ef7..1df455f91 100644
--- a/app/test/processing/app/I18NTest.java
+++ b/app/test/processing/app/I18NTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
import org.junit.Ignore;
diff --git a/app/test/processing/app/ReduceIndentWith1CharOnLastLineTest.java b/app/test/processing/app/ReduceIndentWith1CharOnLastLineTest.java
index 9ee7e0c50..f5cd01f89 100644
--- a/app/test/processing/app/ReduceIndentWith1CharOnLastLineTest.java
+++ b/app/test/processing/app/ReduceIndentWith1CharOnLastLineTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
import static org.junit.Assert.assertEquals;
@@ -5,7 +34,7 @@ import static org.junit.Assert.assertEquals;
import org.fest.swing.fixture.JMenuItemFixture;
import org.junit.Test;
-import processing.app.helpers.JEditTextAreaFixture;
+import processing.app.helpers.SketchTextAreaFixture;
public class ReduceIndentWith1CharOnLastLineTest extends AbstractGUITest {
@@ -13,7 +42,7 @@ public class ReduceIndentWith1CharOnLastLineTest extends AbstractGUITest {
public void shouldJustCloseTheDialog() throws Exception {
JMenuItemFixture menuDecreaseIndent = window.menuItem("menuDecreaseIndent");
- JEditTextAreaFixture editor = window.jEditTextArea("editor");
+ SketchTextAreaFixture editor = window.textArea("editor");
editor.setText("void loop()\n{\n Serial.begin(9600)\n}");
editor.selectAll();
diff --git a/app/test/processing/app/ReplacingTextGeneratesTwoUndoActionsTest.java b/app/test/processing/app/ReplacingTextGeneratesTwoUndoActionsTest.java
index bd03f1108..f1ebe4a97 100644
--- a/app/test/processing/app/ReplacingTextGeneratesTwoUndoActionsTest.java
+++ b/app/test/processing/app/ReplacingTextGeneratesTwoUndoActionsTest.java
@@ -1,8 +1,37 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
import org.fest.swing.fixture.JMenuItemFixture;
import org.junit.Test;
-import processing.app.helpers.JEditTextAreaFixture;
+import processing.app.helpers.SketchTextAreaFixture;
import static org.junit.Assert.assertEquals;
@@ -15,19 +44,19 @@ public class ReplacingTextGeneratesTwoUndoActionsTest extends AbstractGUITest {
JMenuItemFixture menuEditRedo = window.menuItem("menuEditRedo");
menuEditRedo.requireDisabled();
- JEditTextAreaFixture jEditTextArea = window.jEditTextArea("editor");
+ SketchTextAreaFixture textArea = window.textArea("editor");
- jEditTextArea.setText("fake text");
+ textArea.setText("fake text");
menuEditUndo.requireEnabled();
menuEditUndo.click();
- assertEquals("", jEditTextArea.getText());
+ assertEquals("", textArea.getText());
menuEditRedo.requireEnabled();
menuEditRedo.click();
- //assertEquals("fake text", jEditTextArea.getText());
+ //assertEquals("fake text", RSyntaxTextArea.getText());
menuEditUndo.requireEnabled();
menuEditUndo.click();
diff --git a/app/test/processing/app/TestHelper.java b/app/test/processing/app/TestHelper.java
index bee55b09e..ae433061d 100644
--- a/app/test/processing/app/TestHelper.java
+++ b/app/test/processing/app/TestHelper.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app;
import java.io.*;
diff --git a/app/test/processing/app/debug/CompilerTest.java b/app/test/processing/app/debug/CompilerTest.java
index 1d701ff64..9662df24a 100755
--- a/app/test/processing/app/debug/CompilerTest.java
+++ b/app/test/processing/app/debug/CompilerTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.debug;
import static org.junit.Assert.assertEquals;
diff --git a/app/test/processing/app/debug/TargetPlatformStub.java b/app/test/processing/app/debug/TargetPlatformStub.java
new file mode 100644
index 000000000..a8048c514
--- /dev/null
+++ b/app/test/processing/app/debug/TargetPlatformStub.java
@@ -0,0 +1,102 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.debug;
+
+import processing.app.helpers.PreferencesMap;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Set;
+
+public class TargetPlatformStub implements TargetPlatform {
+
+ private final String id;
+ private final TargetPackage targetPackage;
+
+ public TargetPlatformStub(String id, TargetPackage targetPackage) {
+ this.id = id;
+ this.targetPackage = targetPackage;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public File getFolder() {
+ return null;
+ }
+
+ @Override
+ public Map getBoards() {
+ return null;
+ }
+
+ @Override
+ public PreferencesMap getCustomMenus() {
+ return null;
+ }
+
+ @Override
+ public Set getCustomMenuIds() {
+ return null;
+ }
+
+ @Override
+ public Map getProgrammers() {
+ return null;
+ }
+
+ @Override
+ public PreferencesMap getProgrammer(String programmer) {
+ return null;
+ }
+
+ @Override
+ public PreferencesMap getTool(String tool) {
+ return null;
+ }
+
+ @Override
+ public PreferencesMap getPreferences() {
+ return null;
+ }
+
+ @Override
+ public TargetBoard getBoard(String boardId) {
+ return null;
+ }
+
+ @Override
+ public TargetPackage getContainerPackage() {
+ return targetPackage;
+ }
+}
diff --git a/app/test/processing/app/debug/UploaderFactoryTest.java b/app/test/processing/app/debug/UploaderFactoryTest.java
index 5365f97bc..827025265 100644
--- a/app/test/processing/app/debug/UploaderFactoryTest.java
+++ b/app/test/processing/app/debug/UploaderFactoryTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.debug;
import cc.arduino.packages.BoardPort;
@@ -5,26 +34,21 @@ import cc.arduino.packages.Uploader;
import cc.arduino.packages.UploaderFactory;
import cc.arduino.packages.uploaders.SSHUploader;
import cc.arduino.packages.uploaders.SerialUploader;
-import org.junit.Before;
import org.junit.Test;
import processing.app.AbstractWithPreferencesTest;
+import processing.app.helpers.PreferencesMap;
-import java.io.File;
+import java.util.HashMap;
import static org.junit.Assert.assertTrue;
public class UploaderFactoryTest extends AbstractWithPreferencesTest {
- private TargetPackage targetPackage;
-
- @Before
- public void setUp() throws Exception {
- targetPackage = new TargetPackage("arduino", new File(".", "hardware/arduino/"));
- }
-
@Test
public void shouldCreateAnInstanceOfSSHUploader() throws Exception {
- TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("yun");
+ TargetBoard board = new LegacyTargetBoard("yun", new PreferencesMap(new HashMap()), new TargetPlatformStub("id", new TargetPackageStub("id")));
+ board.getPreferences().put("upload.via_ssh", "true");
+
BoardPort boardPort = new BoardPort();
boardPort.setBoardName("yun");
boardPort.setAddress("192.168.0.1");
@@ -36,7 +60,9 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
@Test
public void shouldCreateAnInstanceOfBasicUploaderWhenSSHIsUnsupported() throws Exception {
- TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
+ TargetBoard board = new LegacyTargetBoard("uno", new PreferencesMap(new HashMap()), new TargetPlatformStub("id", new TargetPackageStub("id")));
+ board.getPreferences().put("upload.via_ssh", "false");
+
BoardPort boardPort = new BoardPort();
boardPort.setBoardName("myyun");
boardPort.setAddress("192.168.0.1");
@@ -48,7 +74,9 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest {
@Test
public void shouldCreateAnInstanceOfBasicUploaderWhenPortIsSerial() throws Exception {
- TargetBoard board = targetPackage.getPlatforms().get("avr").getBoards().get("uno");
+ TargetBoard board = new LegacyTargetBoard("uno", new PreferencesMap(new HashMap()), new TargetPlatformStub("id", new TargetPackageStub("id")));
+ board.getPreferences().put("upload.via_ssh", "false");
+
BoardPort boardPort = new BoardPort();
boardPort.setBoardName("Arduino Leonardo");
boardPort.setAddress("/dev/ttyACM0");
diff --git a/app/test/processing/app/helpers/ArduinoFrameFixture.java b/app/test/processing/app/helpers/ArduinoFrameFixture.java
index a5832a904..9f597e27b 100644
--- a/app/test/processing/app/helpers/ArduinoFrameFixture.java
+++ b/app/test/processing/app/helpers/ArduinoFrameFixture.java
@@ -1,8 +1,37 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.helpers;
import org.fest.swing.fixture.FrameFixture;
import processing.app.Editor;
-import processing.app.syntax.JEditTextArea;
+import processing.app.syntax.SketchTextArea;
public class ArduinoFrameFixture extends FrameFixture {
@@ -13,8 +42,8 @@ public class ArduinoFrameFixture extends FrameFixture {
this.editor = editor;
}
- public JEditTextAreaFixture jEditTextArea(String name) {
- return new JEditTextAreaFixture(robot, (JEditTextArea) this.robot.finder().find(new JEditTextAreaComponentMatcher(name)));
+ public SketchTextAreaFixture textArea(String name) {
+ return new SketchTextAreaFixture(robot, (SketchTextArea) this.robot.finder().find(new SketchTextAreaComponentMatcher(name)));
}
public Editor getEditor() {
diff --git a/app/test/processing/app/helpers/JEditTextAreaComponentDriver.java b/app/test/processing/app/helpers/JEditTextAreaComponentDriver.java
deleted file mode 100644
index f292c3998..000000000
--- a/app/test/processing/app/helpers/JEditTextAreaComponentDriver.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package processing.app.helpers;
-
-import org.fest.swing.core.Robot;
-import org.fest.swing.driver.JComponentDriver;
-import org.fest.swing.edt.GuiActionRunner;
-import org.fest.swing.edt.GuiQuery;
-import processing.app.syntax.JEditTextArea;
-
-public class JEditTextAreaComponentDriver extends JComponentDriver {
-
- public JEditTextAreaComponentDriver(Robot robot) {
- super(robot);
- }
-
- public void enterText(JEditTextArea target, String text) {
- focusAndWaitForFocusGain(target);
- robot.enterText(text);
- }
-
- public void setText(final JEditTextArea target, final String text) {
- focusAndWaitForFocusGain(target);
- GuiActionRunner.execute(new GuiQuery() {
-
- protected JEditTextArea executeInEDT() {
- target.setText(text);
- return target;
- }
-
- });
- robot.waitForIdle();
- }
-
- public String getText(final JEditTextArea target) {
- focusAndWaitForFocusGain(target);
- return GuiActionRunner.execute(new GuiQuery() {
-
- protected String executeInEDT() {
- return target.getText();
- }
-
- });
- }
-
- public JEditTextArea selectAll(final JEditTextArea target) {
- return GuiActionRunner.execute(new GuiQuery() {
-
- protected JEditTextArea executeInEDT() {
- target.selectAll();
- return target;
- }
-
- });
- }
-
- public Integer getCaretPosition(final JEditTextArea target) {
- focusAndWaitForFocusGain(target);
- return GuiActionRunner.execute(new GuiQuery() {
-
- protected Integer executeInEDT() {
- return target.getCaretPosition();
- }
-
- });
- }
-
- public void setCaretPosition(final JEditTextArea target, final int caretPosition) {
- focusAndWaitForFocusGain(target);
- GuiActionRunner.execute(new GuiQuery() {
-
- protected JEditTextArea executeInEDT() {
- target.setCaretPosition(caretPosition);
- return target;
- }
-
- });
- robot.waitForIdle();
- }
-
-}
diff --git a/app/test/processing/app/helpers/JEditTextAreaComponentMatcher.java b/app/test/processing/app/helpers/JEditTextAreaComponentMatcher.java
deleted file mode 100644
index f168b92b9..000000000
--- a/app/test/processing/app/helpers/JEditTextAreaComponentMatcher.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package processing.app.helpers;
-
-import org.fest.swing.core.ComponentMatcher;
-import processing.app.syntax.JEditTextArea;
-
-import java.awt.*;
-
-public class JEditTextAreaComponentMatcher implements ComponentMatcher {
-
- private final String name;
-
- public JEditTextAreaComponentMatcher(String name) {
- this.name = name;
- }
-
- @Override
- public boolean matches(Component component) {
- return component instanceof JEditTextArea && name.equals(component.getName());
- }
-}
diff --git a/app/test/processing/app/helpers/JEditTextAreaFixture.java b/app/test/processing/app/helpers/JEditTextAreaFixture.java
deleted file mode 100644
index 19560d88b..000000000
--- a/app/test/processing/app/helpers/JEditTextAreaFixture.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package processing.app.helpers;
-
-import org.fest.swing.core.Robot;
-import org.fest.swing.fixture.ComponentFixture;
-import processing.app.syntax.JEditTextArea;
-
-public class JEditTextAreaFixture extends ComponentFixture {
-
- private final JEditTextAreaComponentDriver driver;
-
- public JEditTextAreaFixture(Robot robot, Class type) {
- super(robot, type);
- this.driver = new JEditTextAreaComponentDriver(robot);
- }
-
- public JEditTextAreaFixture(Robot robot, String name, Class type) {
- super(robot, name, type);
- this.driver = new JEditTextAreaComponentDriver(robot);
- }
-
- public JEditTextAreaFixture(Robot robot, JEditTextArea target) {
- super(robot, target);
- this.driver = new JEditTextAreaComponentDriver(robot);
- }
-
- public JEditTextAreaFixture enterText(String text) {
- driver.enterText((JEditTextArea) target, text);
- return this;
- }
-
- public JEditTextAreaFixture setText(String text) {
- driver.setText((JEditTextArea) target, text);
- return this;
- }
-
- public String getText() {
- return driver.getText((JEditTextArea) target);
- }
-
- public JEditTextAreaFixture selectAll() {
- driver.selectAll((JEditTextArea) target);
- return this;
- }
-
- public int getCaretPosition() {
- return driver.getCaretPosition((JEditTextArea) target);
- }
-
- public void setCaretPosition(int caretPosition) {
- driver.setCaretPosition((JEditTextArea) target, caretPosition);
- }
-}
diff --git a/app/test/processing/app/helpers/SketchTextAreaComponentDriver.java b/app/test/processing/app/helpers/SketchTextAreaComponentDriver.java
new file mode 100644
index 000000000..7d569c3bf
--- /dev/null
+++ b/app/test/processing/app/helpers/SketchTextAreaComponentDriver.java
@@ -0,0 +1,109 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.helpers;
+
+import org.fest.swing.core.Robot;
+import org.fest.swing.driver.JComponentDriver;
+import org.fest.swing.edt.GuiActionRunner;
+import org.fest.swing.edt.GuiQuery;
+import processing.app.syntax.SketchTextArea;
+
+public class SketchTextAreaComponentDriver extends JComponentDriver {
+
+ public SketchTextAreaComponentDriver(Robot robot) {
+ super(robot);
+ }
+
+ public void enterText(SketchTextArea target, String text) {
+ focusAndWaitForFocusGain(target);
+ robot.enterText(text);
+ }
+
+ public void setText(final SketchTextArea target, final String text) {
+ focusAndWaitForFocusGain(target);
+ GuiActionRunner.execute(new GuiQuery() {
+
+ protected SketchTextArea executeInEDT() {
+ target.setText(text);
+ return target;
+ }
+
+ });
+ robot.waitForIdle();
+ }
+
+ public String getText(final SketchTextArea target) {
+ focusAndWaitForFocusGain(target);
+ return GuiActionRunner.execute(new GuiQuery() {
+
+ protected String executeInEDT() {
+ return target.getText();
+ }
+
+ });
+ }
+
+ public SketchTextArea selectAll(final SketchTextArea target) {
+ return GuiActionRunner.execute(new GuiQuery() {
+
+ protected SketchTextArea executeInEDT() {
+ target.selectAll();
+ return target;
+ }
+
+ });
+ }
+
+ public Integer getCaretPosition(final SketchTextArea target) {
+ focusAndWaitForFocusGain(target);
+ return GuiActionRunner.execute(new GuiQuery() {
+
+ protected Integer executeInEDT() {
+ return target.getCaretPosition();
+ }
+
+ });
+ }
+
+ public void setCaretPosition(final SketchTextArea target, final int caretPosition) {
+ focusAndWaitForFocusGain(target);
+ GuiActionRunner.execute(new GuiQuery() {
+
+ protected SketchTextArea executeInEDT() {
+ target.setCaretPosition(caretPosition);
+ return target;
+ }
+
+ });
+ robot.waitForIdle();
+ }
+
+}
diff --git a/app/test/processing/app/helpers/SketchTextAreaComponentMatcher.java b/app/test/processing/app/helpers/SketchTextAreaComponentMatcher.java
new file mode 100644
index 000000000..006ec2a91
--- /dev/null
+++ b/app/test/processing/app/helpers/SketchTextAreaComponentMatcher.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.helpers;
+
+import org.fest.swing.core.ComponentMatcher;
+import processing.app.syntax.SketchTextArea;
+
+import java.awt.*;
+
+public class SketchTextAreaComponentMatcher implements ComponentMatcher {
+
+ private final String name;
+
+ public SketchTextAreaComponentMatcher(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public boolean matches(Component component) {
+ return component instanceof SketchTextArea && name.equals(component.getName());
+ }
+}
diff --git a/app/test/processing/app/helpers/SketchTextAreaFixture.java b/app/test/processing/app/helpers/SketchTextAreaFixture.java
new file mode 100644
index 000000000..e5e1f703b
--- /dev/null
+++ b/app/test/processing/app/helpers/SketchTextAreaFixture.java
@@ -0,0 +1,82 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Ricardo JL Rufino (ricardo@criativasoft.com.br)
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.helpers;
+
+import org.fest.swing.core.Robot;
+import org.fest.swing.fixture.ComponentFixture;
+import processing.app.syntax.SketchTextArea;
+
+public class SketchTextAreaFixture extends ComponentFixture {
+
+ private final SketchTextAreaComponentDriver driver;
+
+ public SketchTextAreaFixture(Robot robot, Class type) {
+ super(robot, type);
+ this.driver = new SketchTextAreaComponentDriver(robot);
+ }
+
+ public SketchTextAreaFixture(Robot robot, String name, Class type) {
+ super(robot, name, type);
+ this.driver = new SketchTextAreaComponentDriver(robot);
+ }
+
+ public SketchTextAreaFixture(Robot robot, SketchTextArea target) {
+ super(robot, target);
+ this.driver = new SketchTextAreaComponentDriver(robot);
+ }
+
+ public SketchTextAreaFixture enterText(String text) {
+ driver.enterText((SketchTextArea) target, text);
+ return this;
+ }
+
+ public SketchTextAreaFixture setText(String text) {
+ driver.setText((SketchTextArea) target, text);
+ return this;
+ }
+
+ public String getText() {
+ return driver.getText((SketchTextArea) target);
+ }
+
+ public SketchTextAreaFixture selectAll() {
+ driver.selectAll((SketchTextArea) target);
+ return this;
+ }
+
+ public int getCaretPosition() {
+ return driver.getCaretPosition((SketchTextArea) target);
+ }
+
+ public void setCaretPosition(int caretPosition) {
+ driver.setCaretPosition((SketchTextArea) target, caretPosition);
+ }
+}
diff --git a/app/test/processing/app/helpers/StringReplacerTest.java b/app/test/processing/app/helpers/StringReplacerTest.java
index 90ecd0144..18b7fc683 100644
--- a/app/test/processing/app/helpers/StringReplacerTest.java
+++ b/app/test/processing/app/helpers/StringReplacerTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.helpers;
import static org.junit.Assert.assertArrayEquals;
diff --git a/app/test/processing/app/linux/UDevAdmParserTest.java b/app/test/processing/app/linux/UDevAdmParserTest.java
index efcc70bfb..a7a2b6c59 100644
--- a/app/test/processing/app/linux/UDevAdmParserTest.java
+++ b/app/test/processing/app/linux/UDevAdmParserTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.linux;
import org.junit.Test;
diff --git a/app/test/processing/app/macosx/SystemProfilerParserTest.java b/app/test/processing/app/macosx/SystemProfilerParserTest.java
index 3f2e0b9de..30c6f6b63 100644
--- a/app/test/processing/app/macosx/SystemProfilerParserTest.java
+++ b/app/test/processing/app/macosx/SystemProfilerParserTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.macosx;
import org.junit.Test;
diff --git a/app/test/processing/app/preproc/PdePreprocessorTest.java b/app/test/processing/app/preproc/PdePreprocessorTest.java
index aa66a84b6..ef2f916c1 100644
--- a/app/test/processing/app/preproc/PdePreprocessorTest.java
+++ b/app/test/processing/app/preproc/PdePreprocessorTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.preproc;
import org.junit.Test;
diff --git a/app/test/processing/app/syntax/PdeKeywordsTest.java b/app/test/processing/app/syntax/PdeKeywordsTest.java
new file mode 100644
index 000000000..29c6b4675
--- /dev/null
+++ b/app/test/processing/app/syntax/PdeKeywordsTest.java
@@ -0,0 +1,59 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
+package processing.app.syntax;
+
+import org.fife.ui.rsyntaxtextarea.TokenTypes;
+import org.junit.Test;
+import processing.app.AbstractWithPreferencesTest;
+import processing.app.BaseNoGui;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+public class PdeKeywordsTest extends AbstractWithPreferencesTest {
+
+ @Test
+ public void testKeywordsTxtParsing() throws Exception {
+ PdeKeywords pdeKeywords = new PdeKeywords();
+ pdeKeywords.reload();
+
+ assertEquals("Constants", pdeKeywords.getReference("HIGH"));
+ assertEquals("RESERVED_WORD_2", pdeKeywords.getTokenTypeAsString("HIGH"));
+ assertEquals(TokenTypes.RESERVED_WORD_2, pdeKeywords.getTokenType("HIGH".toCharArray(), 0, 3));
+
+ assertEquals("IncrementCompound", pdeKeywords.getReference("+="));
+ assertNull(pdeKeywords.getTokenTypeAsString("+="));
+
+ assertNull(pdeKeywords.getReference("Mouse"));
+ assertEquals("DATA_TYPE", pdeKeywords.getTokenTypeAsString("Mouse"));
+ assertEquals(TokenTypes.DATA_TYPE, pdeKeywords.getTokenType("Mouse".toCharArray(), 0, 4));
+ }
+
+}
diff --git a/app/test/processing/app/tools/ZipDeflaterTest.java b/app/test/processing/app/tools/ZipDeflaterTest.java
index ba240254d..21f28cc29 100644
--- a/app/test/processing/app/tools/ZipDeflaterTest.java
+++ b/app/test/processing/app/tools/ZipDeflaterTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.tools;
import static org.junit.Assert.assertEquals;
diff --git a/app/test/processing/app/windows/ListComPortsParserTest.java b/app/test/processing/app/windows/ListComPortsParserTest.java
index dd6d9755a..e75857933 100644
--- a/app/test/processing/app/windows/ListComPortsParserTest.java
+++ b/app/test/processing/app/windows/ListComPortsParserTest.java
@@ -1,3 +1,32 @@
+/*
+ * This file is part of Arduino.
+ *
+ * Copyright 2015 Arduino LLC (http://www.arduino.cc/)
+ *
+ * Arduino is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ */
+
package processing.app.windows;
import org.junit.Test;
@@ -14,5 +43,15 @@ public class ListComPortsParserTest {
assertEquals("0X16C0_0X0483", new ListComPortsParser().extractVIDAndPID(listComPortsOutput, "COM24"));
}
+ @Test
+ public void shouldFindVIDPID2() throws Exception {
+ String listComPortsOutput = "COM1 - (Standard port types) - ACPI\\PNP0501\\1\n" +
+ "COM3 - IVT Corporation - {F12D3CF8-B11D-457E-8641-BE2AF2D6D204}\\IVTCOMM\\1&27902E60&2&0001\n" +
+ "COM4 - IVT Corporation - {F12D3CF8-B11D-457E-8641-BE2AF2D6D204}\\IVTCOMM\\1&27902E60&2&0002\n" +
+ "COM18 - FTDI - FTDIBUS\\VID_0403+PID_0000+A9EPHBR7A\\0000";
+
+ assertEquals("0X0403_0X0000", new ListComPortsParser().extractVIDAndPID(listComPortsOutput, "COM18"));
+ }
+
}
diff --git a/arduino-core/.classpath b/arduino-core/.classpath
index bf61b5826..cd3604c15 100644
--- a/arduino-core/.classpath
+++ b/arduino-core/.classpath
@@ -9,5 +9,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+