1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-20 21:01:25 +03:00

Fixing bug in copy for forum (checking array bounds before access instead of after).

This commit is contained in:
David A. Mellis
2009-03-22 12:34:56 +00:00
parent 7e18c29245
commit 628b18674f
2 changed files with 313 additions and 313 deletions

View File

@ -1,313 +1,312 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/* /*
Part of the Processing project - http://processing.org Part of the Processing project - http://processing.org
Copyright (c) 2005-06 Ignacio Manuel Gonz<6E>lez Moreta Copyright (c) 2005-06 Ignacio Manuel Gonz<6E>lez Moreta
Copyright (c) 2006 Ben Fry and Casey Reas Copyright (c) 2006 Ben Fry and Casey Reas
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
package processing.app.tools; package processing.app.tools;
import java.awt.*; import java.awt.*;
import java.awt.datatransfer.*; import java.awt.datatransfer.*;
import java.awt.event.*; import java.awt.event.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.text.Segment; import javax.swing.text.Segment;
import processing.app.*; import processing.app.*;
import processing.app.syntax.*; import processing.app.syntax.*;
import processing.core.PApplet; import processing.core.PApplet;
/** /**
* Format for Discourse Tool * Format for Discourse Tool
* <p/> * <p/>
* Original code by <A HREF="http://usuarios.iponet.es/imoreta">owd</A>. * Original code by <A HREF="http://usuarios.iponet.es/imoreta">owd</A>.
* Revised and updated for revision 0108 by Ben Fry (10 March 2006). * Revised and updated for revision 0108 by Ben Fry (10 March 2006).
* This code will later be removed but is included with release 0108+ * This code will later be removed but is included with release 0108+
* while features for the "Tools" menu are in testing. * while features for the "Tools" menu are in testing.
* <p/> * <p/>
* Updated for 0122 to simply copy the code directly to the clipboard, * Updated for 0122 to simply copy the code directly to the clipboard,
* rather than opening a new window. * rather than opening a new window.
* <p/> * <p/>
* Notes from the original source: * Notes from the original source:
* Discourse.java This is a dirty-mix source. * Discourse.java This is a dirty-mix source.
* NOTE that: No macs and no keyboard. Unreliable source. * NOTE that: No macs and no keyboard. Unreliable source.
* Only format processing code using fontMetrics. * Only format processing code using fontMetrics.
* It works under my windows XP + PentiumIV + Processing 0091. * It works under my windows XP + PentiumIV + Processing 0091.
*/ */
public class DiscourseFormat { public class DiscourseFormat {
//static final String WINDOW_TITLE = "Format for Discourse by owd"; //static final String WINDOW_TITLE = "Format for Discourse by owd";
// p5 icon for the window // p5 icon for the window
//static Image icon; //static Image icon;
Editor editor; Editor editor;
//JEditTextArea textarea; //JEditTextArea textarea;
// JTextArea of the actual Editor // JTextArea of the actual Editor
JEditTextArea parent; JEditTextArea parent;
//JFrame frame; //JFrame frame;
/** /**
* Creates a new window with the formated (YaBB tags) sketchcode * Creates a new window with the formated (YaBB tags) sketchcode
* from the actual Processing Tab ready to send to the processing discourse * from the actual Processing Tab ready to send to the processing discourse
* web (copy & paste) * web (copy & paste)
*/ */
public DiscourseFormat(Editor editor) { public DiscourseFormat(Editor editor) {
this.editor = editor; this.editor = editor;
this.parent = editor.textarea; this.parent = editor.textarea;
/* /*
textarea = new JEditTextArea(new PdeTextAreaDefaults()); textarea = new JEditTextArea(new PdeTextAreaDefaults());
textarea.setRightClickPopup(new DiscourseTextAreaPopup()); textarea.setRightClickPopup(new DiscourseTextAreaPopup());
textarea.setTokenMarker(new PdeKeywords()); textarea.setTokenMarker(new PdeKeywords());
textarea.setHorizontalOffset(6); textarea.setHorizontalOffset(6);
textarea.setEditable(false); textarea.setEditable(false);
// Create and set up the window. // Create and set up the window.
frame = new JFrame(WINDOW_TITLE); frame = new JFrame(WINDOW_TITLE);
frame.setSize(500, 500); frame.setSize(500, 500);
// set the window icon // set the window icon
try { try {
icon = Base.getImage("icon.gif", frame); icon = Base.getImage("icon.gif", frame);
frame.setIconImage(icon); frame.setIconImage(icon);
} catch (Exception e) { } // fail silently, no big whup } catch (Exception e) { } // fail silently, no big whup
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Container pain = frame.getContentPane(); Container pain = frame.getContentPane();
pain.setLayout(new BorderLayout()); pain.setLayout(new BorderLayout());
pain.add(textarea, BorderLayout.CENTER); pain.add(textarea, BorderLayout.CENTER);
frame.setResizable(true); frame.setResizable(true);
frame.pack(); frame.pack();
frame.setLocation(100, 100); frame.setLocation(100, 100);
//frame.setVisible(true); //frame.setVisible(true);
*/ */
} }
public void show() { public void show() {
// Format and render sketchcode // Format and render sketchcode
// [code] tag cancels other tags, using [quote] // [code] tag cancels other tags, using [quote]
StringBuffer cf = new StringBuffer("[quote] \n \n"); StringBuffer cf = new StringBuffer("[quote] \n \n");
// Line by line // Line by line
for (int i = 0; i < parent.getLineCount(); i++) { for (int i = 0; i < parent.getLineCount(); i++) {
cf.append(formatCode(i)); cf.append(formatCode(i));
} }
cf.append("\n [/quote]"); cf.append("\n [/quote]");
/* /*
// Send the text to the textarea // Send the text to the textarea
textarea.setText(cf.toString()); textarea.setText(cf.toString());
textarea.select(0, 0); textarea.select(0, 0);
frame.show(); frame.show();
*/ */
StringSelection formatted = new StringSelection(cf.toString()); StringSelection formatted = new StringSelection(cf.toString());
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(formatted, new ClipboardOwner() { clipboard.setContents(formatted, new ClipboardOwner() {
public void lostOwnership(Clipboard clipboard, Transferable contents) { public void lostOwnership(Clipboard clipboard, Transferable contents) {
// i don't care about ownership // i don't care about ownership
} }
}); });
editor.message("Discourse-formatted code has been " + editor.message("Discourse-formatted code has been " +
"copied to the clipboard."); "copied to the clipboard.");
} }
// A terrible headache... // A terrible headache...
public String formatCode(int line) { public String formatCode(int line) {
StringBuffer cf = new StringBuffer(); StringBuffer cf = new StringBuffer();
// Segment // Segment
Segment lineSegment = new Segment(); Segment lineSegment = new Segment();
TextAreaPainter painter = parent.getPainter(); TextAreaPainter painter = parent.getPainter();
TokenMarker tokenMarker = parent.getTokenMarker(); TokenMarker tokenMarker = parent.getTokenMarker();
// Use painter's cached info for speed // Use painter's cached info for speed
FontMetrics fm = painter.getFontMetrics(); FontMetrics fm = painter.getFontMetrics();
// get line text from parent textarea // get line text from parent textarea
parent.getLineText(line, lineSegment); parent.getLineText(line, lineSegment);
char[] segmentArray = lineSegment.array; char[] segmentArray = lineSegment.array;
int limit = lineSegment.getEndIndex(); int limit = lineSegment.getEndIndex();
int segmentOffset = lineSegment.offset; int segmentOffset = lineSegment.offset;
int segmentCount = lineSegment.count; int segmentCount = lineSegment.count;
int width = 0; //parent.getHorizontalOffset(); int width = 0; //parent.getHorizontalOffset();
int x = 0; //parent.getHorizontalOffset(); int x = 0; //parent.getHorizontalOffset();
// If syntax coloring is disabled, do simple translation // If syntax coloring is disabled, do simple translation
if (tokenMarker == null) { if (tokenMarker == null) {
for (int j = 0; j < segmentCount; j++) { for (int j = 0; j < segmentCount; j++) {
char c = segmentArray[j + segmentOffset]; char c = segmentArray[j + segmentOffset];
cf = cf.append(c); //concat(character(c)); cf = cf.append(c); //concat(character(c));
int charWidth; int charWidth;
if (c == '\t') { if (c == '\t') {
charWidth = (int) painter.nextTabStop(width, j) - width; charWidth = (int) painter.nextTabStop(width, j) - width;
} else { } else {
charWidth = fm.charWidth(c); charWidth = fm.charWidth(c);
} }
width += charWidth; width += charWidth;
} }
} else { } else {
// If syntax coloring is enabled, we have to do this // If syntax coloring is enabled, we have to do this
// because tokens can vary in width // because tokens can vary in width
Token tokens; Token tokens;
if ((painter.getCurrentLineIndex() == line) && if ((painter.getCurrentLineIndex() == line) &&
(painter.getCurrentLineTokens() != null)) { (painter.getCurrentLineTokens() != null)) {
tokens = painter.getCurrentLineTokens(); tokens = painter.getCurrentLineTokens();
} else { } else {
painter.setCurrentLineIndex(line); painter.setCurrentLineIndex(line);
//painter.currentLineIndex = line; //painter.currentLineIndex = line;
painter.setCurrentLineTokens(tokenMarker.markTokens(lineSegment, line)); painter.setCurrentLineTokens(tokenMarker.markTokens(lineSegment, line));
tokens = painter.getCurrentLineTokens(); tokens = painter.getCurrentLineTokens();
} }
int offset = 0; int offset = 0;
Toolkit toolkit = painter.getToolkit(); Toolkit toolkit = painter.getToolkit();
Font defaultFont = painter.getFont(); Font defaultFont = painter.getFont();
SyntaxStyle[] styles = painter.getStyles(); SyntaxStyle[] styles = painter.getStyles();
for (;;) { for (;;) {
byte id = tokens.id; byte id = tokens.id;
if (id == Token.END) { if (id == Token.END) {
char c = segmentArray[segmentOffset + offset]; if (segmentOffset + offset < limit) {
if (segmentOffset + offset < limit) { cf.append(segmentArray[segmentOffset + offset]);
cf.append(c); } else {
} else { cf.append('\n');
cf.append('\n'); }
} return cf.toString();
return cf.toString(); }
} if (id == Token.NULL) {
if (id == Token.NULL) { fm = painter.getFontMetrics();
fm = painter.getFontMetrics(); } else {
} else { // Place open tags []
// Place open tags [] //cf.append("[color=" + color() + "]");
//cf.append("[color=" + color() + "]"); cf.append("[color=#");
cf.append("[color=#"); cf.append(PApplet.hex(styles[id].getColor().getRGB() & 0xFFFFFF, 6));
cf.append(PApplet.hex(styles[id].getColor().getRGB() & 0xFFFFFF, 6)); cf.append("]");
cf.append("]");
if (styles[id].isBold())
if (styles[id].isBold()) cf.append("[b]");
cf.append("[b]");
fm = styles[id].getFontMetrics(defaultFont);
fm = styles[id].getFontMetrics(defaultFont); }
} int length = tokens.length;
int length = tokens.length;
for (int j = 0; j < length; j++) {
for (int j = 0; j < length; j++) { char c = segmentArray[segmentOffset + offset + j];
char c = segmentArray[segmentOffset + offset + j]; cf.append(c);
cf.append(c); // Place close tags [/]
// Place close tags [/] if (j == (length - 1) && id != Token.NULL && styles[id].isBold())
if (j == (length - 1) && id != Token.NULL && styles[id].isBold()) cf.append("[/b]");
cf.append("[/b]"); if (j == (length - 1) && id != Token.NULL)
if (j == (length - 1) && id != Token.NULL) cf.append("[/color]");
cf.append("[/color]"); int charWidth;
int charWidth; if (c == '\t') {
if (c == '\t') { charWidth = (int) painter
charWidth = (int) painter .nextTabStop(width, offset + j)
.nextTabStop(width, offset + j) - width;
- width; } else {
} else { charWidth = fm.charWidth(c);
charWidth = fm.charWidth(c); }
} width += charWidth;
width += charWidth; }
} offset += length;
offset += length; tokens = tokens.next;
tokens = tokens.next; }
} }
} return cf.toString();
return cf.toString(); }
}
/**
/** * Returns the discourse popup menu. Another features can be added: format
* Returns the discourse popup menu. Another features can be added: format * selected text with a determinated tag (I'm thinking about [url]selected
* selected text with a determinated tag (I'm thinking about [url]selected * text[/url])
* text[/url]) */
*/ /*
/* class DiscourseTextAreaPopup extends JPopupMenu {
class DiscourseTextAreaPopup extends JPopupMenu { JMenuItem copyItem;
JMenuItem copyItem;
public DiscourseTextAreaPopup() {
public DiscourseTextAreaPopup() { JMenuItem item;
JMenuItem item;
copyItem = new JMenuItem("Copy");
copyItem = new JMenuItem("Copy"); copyItem.addActionListener(new ActionListener() {
copyItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
public void actionPerformed(ActionEvent e) { textarea.copy();
textarea.copy(); }
} });
}); this.add(copyItem);
this.add(copyItem);
item = new JMenuItem("Select All");
item = new JMenuItem("Select All"); item.addActionListener(new ActionListener() {
item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
public void actionPerformed(ActionEvent e) { textarea.selectAll();
textarea.selectAll(); }
} });
}); this.add(item);
this.add(item); }
}
// if no text is selected, disable copy menu item
// if no text is selected, disable copy menu item public void show(Component component, int x, int y) {
public void show(Component component, int x, int y) { if (textarea.isSelectionActive()) {
if (textarea.isSelectionActive()) { copyItem.setEnabled(true);
copyItem.setEnabled(true);
} else {
} else { copyItem.setEnabled(false);
copyItem.setEnabled(false); }
} super.show(component, x, y);
super.show(component, x, y); }
} }
} */
*/
/*
/* // A false listener (use the mouse)
// A false listener (use the mouse) public class DiscourseListener {
public class DiscourseListener {
public DiscourseListener(JEditTextArea thisTextarea) {
public DiscourseListener(JEditTextArea thisTextarea) { // I'm a... I know this gives peoblems, but all this code
// I'm a... I know this gives peoblems, but all this code // is a funny hacking experiment
// is a funny hacking experiment thisTextarea.editorListener = parent.editorListener;
thisTextarea.editorListener = parent.editorListener; }
}
public boolean keyPressed(KeyEvent event) {
public boolean keyPressed(KeyEvent event) { System.out.println("Is your mouse lone some tonight...");
System.out.println("Is your mouse lone some tonight..."); return false;
return false; }
} }
} */
*/
} }

View File

@ -50,7 +50,8 @@ UPDATES
[environment] [environment]
* Reinstating use of core.a library in the build process, slightly shrinking * Reinstating use of core.a library in the build process, slightly shrinking
compiled sketch sizes. compiled sketch sizes. (Thanks to William Westfield.)
* Fixing bug in copy for forum (thanks to eried).
0014 - 2009.03.07 0014 - 2009.03.07