From a6c8753a80d6ccf2b168bb8609fbeb0c20a7c3cc Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Aug 2011 19:51:02 +0200 Subject: [PATCH] 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() {} }