001    package nl.cwi.sen1.tide.tool.srcviewer;
002    
003    import java.awt.Color;
004    import java.awt.Graphics;
005    import java.awt.Point;
006    import java.awt.Rectangle;
007    import java.util.HashMap;
008    import java.util.Iterator;
009    import java.util.Map;
010    
011    import javax.swing.JTextArea;
012    import javax.swing.text.BadLocationException;
013    import javax.swing.text.Document;
014    import javax.swing.text.Element;
015    
016    import nl.cwi.sen1.tide.tool.support.Expr;
017    import nl.cwi.sen1.tide.tool.support.Rule;
018    
019    class SourceBrowser extends JTextArea {
020            private static final Color COLOR_SELECTED_POSITION = Color.red;
021    
022            private int selectedPosition;
023    
024            private Map<Rule, Expr> breakpointLocations;
025            private Map<Rule, Expr> watchpointLocations;
026    
027            //{{{ public SourceBrowser()
028    
029            public SourceBrowser() {
030                    selectedPosition = -1;
031                    breakpointLocations = new HashMap<Rule, Expr>();
032                    watchpointLocations = new HashMap<Rule, Expr>();
033            }
034    
035            //}}}
036            //{{{ public void switchToFile(String fileName)
037    
038            public void clear() {
039                    breakpointLocations.clear();
040                    watchpointLocations.clear();
041            }
042    
043            //}}}
044    
045            //{{{ public void setSelectedPosition(int pos)
046    
047            public void setSelectedPosition(int pos) {
048                    selectedPosition = pos;
049                    repaint();
050            }
051    
052            //}}}
053            //{{{ public void clearSelectedPosition()
054    
055            public void clearSelectedPosition() {
056                    selectedPosition = -1;
057                    repaint();
058            }
059    
060            //}}}
061    
062            //{{{ int getLine(int offset)
063    
064            int getLine(int offset) {
065                    Document doc = getDocument();
066                    Element root = doc.getDefaultRootElement();
067                    return root.getElementIndex(offset) + 1;
068            }
069    
070            //}}}
071            //{{{ int getColumn(int offset)
072    
073            int getColumn(int offset) {
074                    Document doc = getDocument();
075                    Element root = doc.getDefaultRootElement();
076                    Element line = root.getElement(root.getElementIndex(offset));
077    
078                    return offset - line.getStartOffset();
079            }
080    
081            //}}}
082    
083            //{{{ private void paintLocation(Graphics g, Expr loc)
084    
085            private void paintLocation(Graphics g, Expr loc) {
086                    try {
087                            int line = loc.getLocationStartLine();
088                            int col = loc.getLocationStartColumn();
089                            int pos = getLineStartOffset(line - 1);
090                            pos += col;
091                            Rectangle rect1 = modelToView(pos);
092                            Rectangle rect2 = modelToView(pos + 1);
093                            int x = rect1.x - 1;
094                            int y = rect1.y;
095                            int w = rect2.x - x - 1;
096                            int h = rect1.height;
097                            g.drawRect(x, y, w, h);
098                            g.drawRect(x + 1, y + 1, w - 2, h - 2);
099                    } catch (BadLocationException e) {}
100            }
101    
102            //}}}
103            //{{{ public void paint(Graphics g)
104    
105            public void paint(Graphics g) {
106                    super.paint(g);
107    
108                    if (selectedPosition >= 0) {
109                            try {
110                                    Rectangle rect = modelToView(selectedPosition);
111                                    Rectangle rect_end = modelToView(selectedPosition + 1);
112    
113                                    g.setColor(COLOR_SELECTED_POSITION);
114    
115                                    g.drawOval(
116                                            rect.x - 1,
117                                            rect.y,
118                                            rect_end.x - rect.x + 1,
119                                            rect.height);
120                            } catch (BadLocationException e) {
121                                    selectedPosition = -1;
122                            }
123                    }
124    
125                    // Paint watchpoints and breakpoints
126                    Iterator<Expr> iter;
127    
128                    g.setColor(SourceFileViewer.COLOR_WATCHPOINT);
129                    iter = watchpointLocations.values().iterator();
130                    while (iter.hasNext()) {
131                            paintLocation(g, iter.next());
132                    }
133    
134                    g.setColor(SourceFileViewer.COLOR_BREAKPOINT);
135                    iter = breakpointLocations.values().iterator();
136                    while (iter.hasNext()) {
137                            paintLocation(g, iter.next());
138                    }
139            }
140    
141            //}}}
142    
143            //{{{ public void addWatchpoint(Rule rule, Expr location)
144    
145            public void addWatchpoint(Rule rule, Expr location) {
146                    watchpointLocations.put(rule, location);
147            }
148    
149            //}}}
150            //{{{ public void removeWatchpoint(Rule rule)
151    
152            public void removeWatchpoint(Rule rule) {
153                    watchpointLocations.remove(rule);
154            }
155    
156            //}}}
157            //{{{ public void addBreakpoint(Rule rule, Expr location)
158    
159            public void addBreakpoint(Rule rule, Expr location) {
160                    breakpointLocations.put(rule, location);
161            }
162    
163            //}}}
164            //{{{ public void removeWatchpoint(Rule rule)
165    
166            public void removeBreakpoint(Rule rule) {
167                    breakpointLocations.remove(rule);
168            }
169    
170            //}}}
171    
172            //{{{ public Rule getRuleAt(int x, int y)
173    
174            public Rule getRuleAt(int x, int y) {
175                    int pos = viewToModel(new Point(x, y));
176                    int linenr = getLine(pos);
177                    int column = getColumn(pos);
178    
179                    Iterator<Rule> iter;
180                    iter = breakpointLocations.keySet().iterator();
181                    while (iter.hasNext()) {
182                            Rule rule = iter.next();
183                            Expr location = breakpointLocations.get(rule);
184                            if (location.getLocationStartLine() == linenr
185                                    && location.getLocationStartColumn() == column) {
186                                    return rule;
187                            }
188                    }
189    
190                    iter = watchpointLocations.keySet().iterator();
191                    while (iter.hasNext()) {
192                            Rule rule = iter.next();
193                            Expr location = watchpointLocations.get(rule);
194                            if (location.getLocationStartLine() == linenr
195                                    && location.getLocationStartColumn() == column) {
196                                    return rule;
197                            }
198                    }
199    
200                    return null;
201            }
202    
203            //}}}
204    }