From a6c8753a80d6ccf2b168bb8609fbeb0c20a7c3cc Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Aug 2011 19:51:02 +0200 Subject: [PATCH 1/5] Schematic URL. Actually tag is "@schematics " that should be put inside code comments. --- app/src/processing/app/Editor.java | 82 +++++++++++++------ .../app/syntax/SyntaxUtilities.java | 70 +++++++++++++++- 2 files changed, 127 insertions(+), 25 deletions(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index fa0544a1e..e34bb4a87 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -46,6 +46,7 @@ import gnu.io.*; /** * Main editor panel for the Processing Development Environment. */ +@SuppressWarnings("serial") public class Editor extends JFrame implements RunnerListener { Base base; @@ -113,7 +114,7 @@ public class Editor extends JFrame implements RunnerListener { EditorLineStatus lineStatus; - JEditorPane editorPane; + //JEditorPane editorPane; JEditTextArea textarea; EditorListener listener; @@ -1838,7 +1839,7 @@ public class Editor extends JFrame implements RunnerListener { public void run() { try { sketch.prepare(); - String appletClassName = sketch.build(false); + sketch.build(false); statusNotice("Done compiling."); } catch (Exception e) { status.unprogress(); @@ -1855,7 +1856,7 @@ public class Editor extends JFrame implements RunnerListener { public void run() { try { sketch.prepare(); - String appletClassName = sketch.build(true); + sketch.build(true); statusNotice("Done compiling."); } catch (Exception e) { status.unprogress(); @@ -2628,25 +2629,38 @@ public class Editor extends JFrame implements RunnerListener { * Returns the edit popup menu. */ class TextAreaPopup extends JPopupMenu { - //String currentDir = System.getProperty("user.dir"); - String referenceFile = null; + //private String currentDir = System.getProperty("user.dir"); + private String referenceFile = null; - JMenuItem cutItem; - JMenuItem copyItem; - JMenuItem discourseItem; - JMenuItem referenceItem; + private JMenuItem cutItem; + private JMenuItem copyItem; + private JMenuItem discourseItem; + private JMenuItem referenceItem; + private JMenuItem openURLItem; + private JSeparator openURLItemSeparator; + private String clickedURL; public TextAreaPopup() { - JMenuItem item; - + openURLItem = new JMenuItem("Open URL"); + openURLItem.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Base.openURL(clickedURL); + } + }); + add(openURLItem); + + openURLItemSeparator = new JSeparator(); + add(openURLItemSeparator); + cutItem = new JMenuItem("Cut"); cutItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { handleCut(); } }); - this.add(cutItem); + add(cutItem); copyItem = new JMenuItem("Copy"); copyItem.addActionListener(new ActionListener() { @@ -2654,7 +2668,7 @@ public class Editor extends JFrame implements RunnerListener { handleCopy(); } }); - this.add(copyItem); + add(copyItem); discourseItem = new JMenuItem("Copy for Forum"); discourseItem.addActionListener(new ActionListener() { @@ -2662,7 +2676,7 @@ public class Editor extends JFrame implements RunnerListener { handleDiscourseCopy(); } }); - this.add(discourseItem); + add(discourseItem); discourseItem = new JMenuItem("Copy as HTML"); discourseItem.addActionListener(new ActionListener() { @@ -2670,15 +2684,15 @@ public class Editor extends JFrame implements RunnerListener { handleHTMLCopy(); } }); - this.add(discourseItem); + add(discourseItem); - item = new JMenuItem("Paste"); + JMenuItem item = new JMenuItem("Paste"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { handlePaste(); } }); - this.add(item); + add(item); item = new JMenuItem("Select All"); item.addActionListener(new ActionListener() { @@ -2686,9 +2700,9 @@ public class Editor extends JFrame implements RunnerListener { handleSelectAll(); } }); - this.add(item); + add(item); - this.addSeparator(); + addSeparator(); item = new JMenuItem("Comment/Uncomment"); item.addActionListener(new ActionListener() { @@ -2696,7 +2710,7 @@ public class Editor extends JFrame implements RunnerListener { handleCommentUncomment(); } }); - this.add(item); + add(item); item = new JMenuItem("Increase Indent"); item.addActionListener(new ActionListener() { @@ -2704,7 +2718,7 @@ public class Editor extends JFrame implements RunnerListener { handleIndentOutdent(true); } }); - this.add(item); + add(item); item = new JMenuItem("Decrease Indent"); item.addActionListener(new ActionListener() { @@ -2712,9 +2726,9 @@ public class Editor extends JFrame implements RunnerListener { handleIndentOutdent(false); } }); - this.add(item); + add(item); - this.addSeparator(); + addSeparator(); referenceItem = new JMenuItem("Find in Reference"); referenceItem.addActionListener(new ActionListener() { @@ -2722,11 +2736,31 @@ public class Editor extends JFrame implements RunnerListener { handleFindReference(); } }); - this.add(referenceItem); + add(referenceItem); } + private boolean clickedURL(String line, int offset) { + String[] parse = SyntaxUtilities.parseCommentUrls(line); + if (parse==null) + return false; + int pos = parse[0].length()+parse[1].length(); + if (offsetpos+2) + return false; + clickedURL = parse[1]; + return true; + } + // if no text is selected, disable copy and cut menu items public void show(Component component, int x, int y) { + int line = textarea.getLineOfOffset(textarea.xyToOffset(x, y)); + if (clickedURL(textarea.getLineText(line), textarea.xToOffset(line, x))) { + openURLItem.setVisible(true); + openURLItemSeparator.setVisible(true); + } else { + openURLItem.setVisible(false); + openURLItemSeparator.setVisible(false); + } + if (textarea.isSelectionActive()) { cutItem.setEnabled(true); copyItem.setEnabled(true); diff --git a/app/src/processing/app/syntax/SyntaxUtilities.java b/app/src/processing/app/syntax/SyntaxUtilities.java index 5225d0b73..9423c3952 100644 --- a/app/src/processing/app/syntax/SyntaxUtilities.java +++ b/app/src/processing/app/syntax/SyntaxUtilities.java @@ -11,6 +11,8 @@ package processing.app.syntax; import javax.swing.text.*; import java.awt.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** @@ -148,7 +150,10 @@ public class SyntaxUtilities styles[id].setGraphicsFlags(gfx,defaultFont); line.count = length; - x = Utilities.drawTabbedText(line,x,y,gfx,expander,0); + if (id == Token.COMMENT1 || id == Token.COMMENT2) + x = drawTabbedCommentsText(line, x, y, gfx, expander); + else + x = Utilities.drawTabbedText(line, x, y, gfx, expander, 0); line.offset += length; offset += length; @@ -158,6 +163,69 @@ public class SyntaxUtilities 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) { + // Try to find pattern + Pattern schematics = Pattern.compile("@schematics\\s+([^\\s]+)"); + Matcher m = schematics.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; + } + + 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) { + + 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]); + + x = Utilities.drawTabbedText(pre, x, y, gfx, expander, 0); + x = Utilities.drawTabbedText(tag, x, y, gfx, expander, 0); + + // Draw arrow. + FontMetrics metrics = gfx.getFontMetrics(); + int h = metrics.getHeight() - 2; + drawArrow(gfx, x, y - h + metrics.getDescent() - 1, h, h); + x = Utilities.drawTabbedText(post, x, y, gfx, expander, 0); + return x; + } + + private static void drawArrow(Graphics gfx, int x, int y, int w, int h) { + int h2 = h / 2; + int h4 = h / 4; + gfx.drawLine(x, y+h2, x+h2, y); + gfx.drawLine(x+h2, y, x+h2, y+h4); + gfx.drawLine(x+h2, y+h4, x+h, y+h4); + gfx.drawLine(x+h, y+h4, x+h, y+h-h4); + gfx.drawLine(x+h, y+h-h4, x+h2, y+h-h4); + gfx.drawLine(x+h2,y+h-h4, x+h2, y+h); + gfx.drawLine(x, y+h2, x+h2, y+h); + } + // private members private SyntaxUtilities() {} } From d60c42e5eddf0e5326f38c870eaa5c61b86f8223 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Aug 2011 22:32:34 +0200 Subject: [PATCH 2/5] Clickable url are now searched with a good regexp and highlighted. --- .../app/syntax/PdeTextAreaDefaults.java | 3 ++ .../app/syntax/SyntaxUtilities.java | 29 ++++++++++++++----- app/src/processing/app/syntax/Token.java | 9 ++++-- build/shared/lib/theme/theme.txt | 3 ++ 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/app/src/processing/app/syntax/PdeTextAreaDefaults.java b/app/src/processing/app/syntax/PdeTextAreaDefaults.java index b715255be..382c69aaf 100644 --- a/app/src/processing/app/syntax/PdeTextAreaDefaults.java +++ b/app/src/processing/app/syntax/PdeTextAreaDefaults.java @@ -169,6 +169,9 @@ public class PdeTextAreaDefaults extends TextAreaDefaults { // ?? styles[Token.LABEL] = Theme.getStyle("label"); + // http://arduino.cc/ + styles[Token.URL] = Theme.getStyle("url"); + // + - = / styles[Token.OPERATOR] = Theme.getStyle("operator"); diff --git a/app/src/processing/app/syntax/SyntaxUtilities.java b/app/src/processing/app/syntax/SyntaxUtilities.java index 9423c3952..54443c805 100644 --- a/app/src/processing/app/syntax/SyntaxUtilities.java +++ b/app/src/processing/app/syntax/SyntaxUtilities.java @@ -104,6 +104,7 @@ public class SyntaxUtilities styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true); styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true); styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true); + styles[Token.URL] = new SyntaxStyle(Color.blue,true,false); styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true); return styles; @@ -151,7 +152,7 @@ public class SyntaxUtilities line.count = length; if (id == Token.COMMENT1 || id == Token.COMMENT2) - x = drawTabbedCommentsText(line, x, y, gfx, expander); + x = drawTabbedCommentsText(line, x, y, gfx, expander, styles, styles[id]); else x = Utilities.drawTabbedText(line, x, y, gfx, expander, 0); line.offset += length; @@ -174,9 +175,7 @@ public class SyntaxUtilities * the remaining part of the string. */ public static String[] parseCommentUrls(String line) { - // Try to find pattern - Pattern schematics = Pattern.compile("@schematics\\s+([^\\s]+)"); - Matcher m = schematics.matcher(line.toString()); + Matcher m = urlPattern.matcher(line.toString()); if (!m.find()) return null; @@ -188,12 +187,21 @@ public class SyntaxUtilities 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) { + Graphics gfx, TabExpander expander, SyntaxStyle[] styles, + SyntaxStyle commentStyle) { String parse[] = parseCommentUrls(line.toString()); if (parse == null) @@ -203,14 +211,21 @@ public class SyntaxUtilities Segment tag = stringToSegment(parse[1]); Segment post = stringToSegment(parse[2]); - x = Utilities.drawTabbedText(pre, x, y, gfx, expander, 0); + if (pre.length()>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); // Draw arrow. FontMetrics metrics = gfx.getFontMetrics(); int h = metrics.getHeight() - 2; drawArrow(gfx, x, y - h + metrics.getDescent() - 1, h, h); - x = Utilities.drawTabbedText(post, x, y, gfx, expander, 0); + + commentStyle.setGraphicsFlags(gfx, f); + if (post.length()>0) + x = Utilities.drawTabbedText(post, x, y, gfx, expander, 0); return x; } diff --git a/app/src/processing/app/syntax/Token.java b/app/src/processing/app/syntax/Token.java index a0f73bebf..06dc26323 100644 --- a/app/src/processing/app/syntax/Token.java +++ b/app/src/processing/app/syntax/Token.java @@ -83,17 +83,22 @@ public class Token */ public static final byte OPERATOR = 9; + /** + * URL token id. + */ + public static final byte URL = 10; + /** * Invalid token id. This can be used to mark invalid * or incomplete tokens, so the user can easily spot * syntax errors. */ - public static final byte INVALID = 10; + public static final byte INVALID = 11; /** * The total number of defined token ids. */ - public static final byte ID_COUNT = 11; + public static final byte ID_COUNT = 12; /** * The first id that can be used for internal state diff --git a/build/shared/lib/theme/theme.txt b/build/shared/lib/theme/theme.txt index a0889e64a..c488d20ab 100644 --- a/build/shared/lib/theme/theme.txt +++ b/build/shared/lib/theme/theme.txt @@ -83,6 +83,9 @@ editor.literal1.style = #006699,plain # p5 built in variables: e.g. mouseX, width, pixels editor.literal2.style = #006699,plain +# http://arduino.cc/ +editor.url.style = #0000ff,italic + # e.g. + - = / editor.operator.style = #000000,plain From f233861a4c5b71b65e22151971230b966f9809a7 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 23 Aug 2011 19:21:42 +0200 Subject: [PATCH 3/5] URL right-clickable and underlined. --- app/src/processing/app/Editor.java | 5 +-- app/src/processing/app/Preferences.java | 3 +- app/src/processing/app/Theme.java | 3 +- .../processing/app/syntax/SyntaxStyle.java | 34 ++++++++++++++++--- .../app/syntax/SyntaxUtilities.java | 22 ++++++------ build/shared/lib/theme/theme.txt | 2 +- 6 files changed, 49 insertions(+), 20 deletions(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index e34bb4a87..0b25324a1 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -2743,8 +2743,9 @@ public class Editor extends JFrame implements RunnerListener { String[] parse = SyntaxUtilities.parseCommentUrls(line); if (parse==null) return false; - int pos = parse[0].length()+parse[1].length(); - if (offsetpos+2) + int start = parse[0].length(); + int stop = start + parse[1].length(); + if (offsetstop+2) return false; clickedURL = parse[1]; return true; diff --git a/app/src/processing/app/Preferences.java b/app/src/processing/app/Preferences.java index 4dd15c041..315620033 100644 --- a/app/src/processing/app/Preferences.java +++ b/app/src/processing/app/Preferences.java @@ -772,8 +772,9 @@ public class Preferences { s = st.nextToken(); boolean bold = (s.indexOf("bold") != -1); boolean italic = (s.indexOf("italic") != -1); + boolean underlined = (s.indexOf("underlined") != -1); //System.out.println(what + " = " + str + " " + bold + " " + italic); - return new SyntaxStyle(color, italic, bold); + return new SyntaxStyle(color, italic, bold, underlined); } } diff --git a/app/src/processing/app/Theme.java b/app/src/processing/app/Theme.java index 8b68f4f45..373b56835 100644 --- a/app/src/processing/app/Theme.java +++ b/app/src/processing/app/Theme.java @@ -196,7 +196,8 @@ public class Theme { s = st.nextToken(); boolean bold = (s.indexOf("bold") != -1); boolean italic = (s.indexOf("italic") != -1); + boolean underlined = (s.indexOf("underlined") != -1); - return new SyntaxStyle(color, italic, bold); + return new SyntaxStyle(color, italic, bold, underlined); } } \ No newline at end of file diff --git a/app/src/processing/app/syntax/SyntaxStyle.java b/app/src/processing/app/syntax/SyntaxStyle.java index 56323c3cc..ac3dd797d 100644 --- a/app/src/processing/app/syntax/SyntaxStyle.java +++ b/app/src/processing/app/syntax/SyntaxStyle.java @@ -10,6 +10,10 @@ package processing.app.syntax; import java.awt.*; +import java.awt.font.TextAttribute; +import java.util.Hashtable; +import java.util.Map; + import javax.swing.JComponent; @@ -27,11 +31,12 @@ public class SyntaxStyle * @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) + public SyntaxStyle(Color color, boolean italic, boolean bold, boolean underlined) { this.color = color; this.italic = italic; this.bold = bold; + this.underlined = underlined; } /** @@ -47,7 +52,7 @@ public class SyntaxStyle */ public boolean isPlain() { - return !(bold || italic); + return !(bold || italic || underlined); } /** @@ -67,7 +72,14 @@ public class SyntaxStyle } /** - * Returns the specified font, but with the style's bold and + * @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) @@ -78,10 +90,16 @@ public class SyntaxStyle 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; } @@ -100,6 +118,11 @@ public class SyntaxStyle (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; @@ -125,13 +148,16 @@ public class SyntaxStyle { return getClass().getName() + "[color=" + color + (italic ? ",italic" : "") + - (bold ? ",bold" : "") + "]"; + (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 index 54443c805..d4df8da90 100644 --- a/app/src/processing/app/syntax/SyntaxUtilities.java +++ b/app/src/processing/app/syntax/SyntaxUtilities.java @@ -95,17 +95,17 @@ public class SyntaxUtilities { SyntaxStyle[] styles = new SyntaxStyle[Token.ID_COUNT]; - styles[Token.COMMENT1] = new SyntaxStyle(Color.black,true,false); - styles[Token.COMMENT2] = new SyntaxStyle(new Color(0x990033),true,false); - styles[Token.KEYWORD1] = new SyntaxStyle(Color.black,false,true); - styles[Token.KEYWORD2] = new SyntaxStyle(Color.magenta,false,false); - styles[Token.KEYWORD3] = new SyntaxStyle(new Color(0x009600),false,false); - styles[Token.LITERAL1] = new SyntaxStyle(new Color(0x650099),false,false); - styles[Token.LITERAL2] = new SyntaxStyle(new Color(0x650099),false,true); - styles[Token.LABEL] = new SyntaxStyle(new Color(0x990033),false,true); - styles[Token.OPERATOR] = new SyntaxStyle(Color.black,false,true); - styles[Token.URL] = new SyntaxStyle(Color.blue,true,false); - styles[Token.INVALID] = new SyntaxStyle(Color.red,false,true); + 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; } diff --git a/build/shared/lib/theme/theme.txt b/build/shared/lib/theme/theme.txt index c488d20ab..d8f5b7aa4 100644 --- a/build/shared/lib/theme/theme.txt +++ b/build/shared/lib/theme/theme.txt @@ -84,7 +84,7 @@ editor.literal1.style = #006699,plain editor.literal2.style = #006699,plain # http://arduino.cc/ -editor.url.style = #0000ff,italic +editor.url.style = #0000ff,underlined # e.g. + - = / editor.operator.style = #000000,plain From 303b2e5103546f34fe956b943d9b753f0979dae2 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 23 Aug 2011 19:29:36 +0200 Subject: [PATCH 4/5] Removed arrow. --- .../processing/app/syntax/SyntaxUtilities.java | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/app/src/processing/app/syntax/SyntaxUtilities.java b/app/src/processing/app/syntax/SyntaxUtilities.java index d4df8da90..f6aa20e2b 100644 --- a/app/src/processing/app/syntax/SyntaxUtilities.java +++ b/app/src/processing/app/syntax/SyntaxUtilities.java @@ -218,29 +218,12 @@ public class SyntaxUtilities styles[Token.URL].setGraphicsFlags(gfx, f); x = Utilities.drawTabbedText(tag, x, y, gfx, expander, 0); - // Draw arrow. - FontMetrics metrics = gfx.getFontMetrics(); - int h = metrics.getHeight() - 2; - drawArrow(gfx, x, y - h + metrics.getDescent() - 1, h, h); - commentStyle.setGraphicsFlags(gfx, f); if (post.length()>0) x = Utilities.drawTabbedText(post, x, y, gfx, expander, 0); return x; } - private static void drawArrow(Graphics gfx, int x, int y, int w, int h) { - int h2 = h / 2; - int h4 = h / 4; - gfx.drawLine(x, y+h2, x+h2, y); - gfx.drawLine(x+h2, y, x+h2, y+h4); - gfx.drawLine(x+h2, y+h4, x+h, y+h4); - gfx.drawLine(x+h, y+h4, x+h, y+h-h4); - gfx.drawLine(x+h, y+h-h4, x+h2, y+h-h4); - gfx.drawLine(x+h2,y+h-h4, x+h2, y+h); - gfx.drawLine(x, y+h2, x+h2, y+h); - } - // private members private SyntaxUtilities() {} } From 88794ec1d6b5374548f251815c8a4fa2d5adec6f Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 24 Aug 2011 10:42:58 +0200 Subject: [PATCH 5/5] =?UTF-8?q?Double-click=20now=20opens=20URL=20(right-c?= =?UTF-8?q?lick=20still=20shows=20"Open=20URL"=20in=20popup=20men=C3=B9).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/processing/app/Editor.java | 19 +++++-------------- .../processing/app/syntax/JEditTextArea.java | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 0b25324a1..c3547d87f 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -2739,22 +2739,13 @@ public class Editor extends JFrame implements RunnerListener { add(referenceItem); } - private boolean clickedURL(String line, int offset) { - String[] parse = SyntaxUtilities.parseCommentUrls(line); - if (parse==null) - return false; - int start = parse[0].length(); - int stop = start + parse[1].length(); - if (offsetstop+2) - return false; - clickedURL = parse[1]; - return true; - } - // if no text is selected, disable copy and cut menu items public void show(Component component, int x, int y) { - int line = textarea.getLineOfOffset(textarea.xyToOffset(x, y)); - if (clickedURL(textarea.getLineText(line), textarea.xToOffset(line, x))) { + 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 { diff --git a/app/src/processing/app/syntax/JEditTextArea.java b/app/src/processing/app/syntax/JEditTextArea.java index d5c01c48a..9683c43d8 100644 --- a/app/src/processing/app/syntax/JEditTextArea.java +++ b/app/src/processing/app/syntax/JEditTextArea.java @@ -2045,6 +2045,17 @@ public class JEditTextArea extends JComponent } } + 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) @@ -2111,6 +2122,13 @@ public class JEditTextArea extends JComponent if (getLineLength(line) == 0) return; + // Check for click on urls + String clickedURL = checkClickedURL(getLineText(line), offset); + if (clickedURL != null) { + Base.openURL(clickedURL); + return; + } + try { int bracket = TextUtilities.findMatchingBracket(document, Math.max(0,dot - 1));