Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.swing / org.gvsig.scripting.swing.impl / src / main / java / org / gvsig / scripting / swing / impl / syntaxhighlight / JRSyntaxTextArea.java @ 1200

History | View | Annotate | Download (23.3 KB)

1 368 jjdelcerro
package org.gvsig.scripting.swing.impl.syntaxhighlight;
2
3 468 jjdelcerro
import java.awt.BorderLayout;
4 686 jjdelcerro
import java.awt.Color;
5 630 jjdelcerro
import java.awt.Component;
6 686 jjdelcerro
import java.awt.Container;
7
import java.awt.Cursor;
8
import java.awt.Dimension;
9
import java.awt.Point;
10
import java.awt.Rectangle;
11 368 jjdelcerro
import java.awt.event.ActionEvent;
12
import java.awt.event.ActionListener;
13 630 jjdelcerro
import java.awt.event.InputEvent;
14 468 jjdelcerro
import java.awt.event.KeyEvent;
15 412 jjdelcerro
import java.awt.event.KeyListener;
16 686 jjdelcerro
import java.awt.event.MouseAdapter;
17
import java.awt.event.MouseEvent;
18 478 jjdelcerro
import java.net.URL;
19 630 jjdelcerro
import java.util.ArrayList;
20
import java.util.Arrays;
21
import java.util.Comparator;
22 468 jjdelcerro
import java.util.HashMap;
23 678 jjdelcerro
import java.util.HashSet;
24 630 jjdelcerro
import java.util.List;
25 468 jjdelcerro
import java.util.Map;
26 678 jjdelcerro
import java.util.Set;
27 630 jjdelcerro
import java.util.TreeSet;
28
import javax.swing.DefaultListCellRenderer;
29
import javax.swing.Icon;
30 478 jjdelcerro
import javax.swing.ImageIcon;
31
import javax.swing.JCheckBox;
32 468 jjdelcerro
import javax.swing.JComponent;
33 630 jjdelcerro
import javax.swing.JLabel;
34
import javax.swing.JList;
35 468 jjdelcerro
import javax.swing.JOptionPane;
36
import javax.swing.JPanel;
37 368 jjdelcerro
38
import javax.swing.JScrollPane;
39 686 jjdelcerro
import javax.swing.JViewport;
40 468 jjdelcerro
import javax.swing.KeyStroke;
41 686 jjdelcerro
import javax.swing.SwingUtilities;
42 468 jjdelcerro
import javax.swing.UIManager;
43 368 jjdelcerro
import javax.swing.event.CaretEvent;
44
import javax.swing.event.CaretListener;
45 678 jjdelcerro
import javax.swing.text.BadLocationException;
46 686 jjdelcerro
import javax.swing.text.Element;
47 368 jjdelcerro
import javax.swing.text.JTextComponent;
48 630 jjdelcerro
import org.apache.commons.lang3.StringUtils;
49 468 jjdelcerro
import org.fife.rsta.ui.CollapsibleSectionPanel;
50
import org.fife.rsta.ui.search.FindToolBar;
51
import org.fife.rsta.ui.search.ReplaceToolBar;
52
import org.fife.rsta.ui.search.SearchEvent;
53
import org.fife.rsta.ui.search.SearchListener;
54 630 jjdelcerro
import org.fife.ui.autocomplete.AutoCompletion;
55
import org.fife.ui.autocomplete.BasicCompletion;
56
import org.fife.ui.autocomplete.Completion;
57
import org.fife.ui.autocomplete.CompletionProvider;
58
import org.fife.ui.autocomplete.DefaultCompletionProvider;
59 368 jjdelcerro
60
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
61
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
62 1200 jjdelcerro
import org.fife.ui.rsyntaxtextarea.TokenMakerFactory;
63 678 jjdelcerro
import org.fife.ui.rtextarea.GutterIconInfo;
64 368 jjdelcerro
import org.fife.ui.rtextarea.RTextScrollPane;
65 468 jjdelcerro
import org.fife.ui.rtextarea.SearchContext;
66
import org.fife.ui.rtextarea.SearchEngine;
67
import org.fife.ui.rtextarea.SearchResult;
68 1066 jjdelcerro
import org.gvsig.scripting.swing.api.ScriptingSwingLocator;
69
import org.gvsig.scripting.swing.api.ScriptingUIManager;
70 368 jjdelcerro
import org.gvsig.scripting.swing.api.SyntaxtHighlightTextComponent;
71 886 jjdelcerro
import org.slf4j.Logger;
72
import org.slf4j.LoggerFactory;
73 368 jjdelcerro
74 468 jjdelcerro
public class JRSyntaxTextArea implements SyntaxtHighlightTextComponent, SearchListener {
75 478 jjdelcerro
76 886 jjdelcerro
    private static final Logger logger = LoggerFactory.getLogger(JRSyntaxTextArea.class);
77
78 478 jjdelcerro
    public static class MyCheckBox extends JCheckBox {
79
80
        private static final String uiClassID = "ToggleButtonUI";
81
82
        @Override
83
        public String getUIClassID() {
84
            return uiClassID;
85
        }
86
87
    }
88
89 1066 jjdelcerro
    private class MyFindToolBar extends FindToolBar {
90 478 jjdelcerro
91
        public MyFindToolBar(SearchListener listener) {
92
            super(listener);
93
        }
94
95
        @Override
96
        protected JCheckBox createCB(String key) {
97
            JCheckBox cb = new MyCheckBox();
98
            cb.setToolTipText(searchMsg.getString(key));
99
            cb.addActionListener(listener);
100
            cb.addMouseListener(listener);
101 1066 jjdelcerro
            cb.setIcon(getIcon("scripting-search-" + key.toLowerCase()));
102 478 jjdelcerro
            return cb;
103
        }
104
105
    }
106
107 1066 jjdelcerro
    private class MyReplaceToolBar extends ReplaceToolBar {
108 478 jjdelcerro
109
        public MyReplaceToolBar(SearchListener listener) {
110
            super(listener);
111
        }
112
113
        @Override
114
        protected JCheckBox createCB(String key) {
115
            JCheckBox cb = new MyCheckBox();
116
            cb.setToolTipText(searchMsg.getString(key));
117
            cb.addActionListener(listener);
118
            cb.addMouseListener(listener);
119 1066 jjdelcerro
            cb.setIcon(getIcon("scripting-search-" + key.toLowerCase()));
120 478 jjdelcerro
            return cb;
121
        }
122
    }
123
124 686 jjdelcerro
    private class LineTrackerPanel extends JPanel {
125
126
        private static final long serialVersionUID = -1923556745197997373L;
127
128
        private class Line extends JLabel {
129
130
            private static final long serialVersionUID = 8966359978957026490L;
131
            private final int lineno;
132
            private final String tag;
133
134
            public Line(String tag, final int lineno, int posy, Color color, String tooltip) {
135
                this.lineno = lineno;
136
                this.tag = tag;
137
                this.setBackground(color);
138
                this.setBounds(0, posy, 15, 2);
139
                this.setOpaque(true);
140
                this.setToolTipText(tooltip);
141
                this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
142
                this.addMouseListener(new MouseAdapter() {
143
144
                    @Override
145
                    public void mouseClicked(MouseEvent e) {
146
                        gotoline(lineno);
147
                    }
148
                });
149 886 jjdelcerro
//                Rectangle r = this.getBounds();
150
//                logger.info("LineTracker: created lineno:"+lineno+", tag:"+tag+", x:"+ r.x + ", y:"+ r.y + ", w:"+ r.width+", h:"+ r.height);
151 686 jjdelcerro
            }
152 886 jjdelcerro
153 686 jjdelcerro
            public int getLineno() {
154
                return this.lineno;
155
            }
156
157
            public String getTag() {
158
                return this.tag;
159
            }
160
        }
161
162
        public LineTrackerPanel() {
163 886 jjdelcerro
            setLayout(null);
164 686 jjdelcerro
        }
165
166
        @Override
167
        public Dimension getPreferredSize() {
168
            Dimension d = super.getPreferredSize();
169
            return new Dimension(15, d.height);
170
        }
171
172
        public void addLineTracker(String tag, int lineno, String tooltip, Color color) {
173
            int posy = (int) (((float)lineno)*this.getSize().height / textArea.getLineCount());
174
            Line line = new Line(tag,lineno,posy,color,tooltip);
175
            this.add(line);
176
            this.repaint();
177
        }
178
179
        public void removeLineTrackers() {
180
            this.removeAll();
181 976 jjdelcerro
            this.repaint();
182 686 jjdelcerro
        }
183
184
        public void removeLineTrackers(String tag) {
185
            if( StringUtils.isEmpty(tag) ) {
186
                return;
187
            }
188
            List<Line> toremove = new ArrayList<>();
189
            for( int i=0; i<this.getComponentCount(); i++ ) {
190
                Line line = (Line) this.getComponent(i);
191
                if( tag.equalsIgnoreCase(line.getTag()) ) {
192
                    toremove.add(line);
193
                }
194
            }
195
            for (Line line : toremove) {
196
                this.remove(line);
197
            }
198 976 jjdelcerro
            this.repaint();
199 686 jjdelcerro
        }
200
    }
201
202 678 jjdelcerro
    private static class IconsTracker {
203
204
        private Map<String,Set<GutterIconInfo>>iconInfos = new HashMap<>();
205
206
        public IconsTracker() {
207
208
        }
209
210
        public void add(String tag, GutterIconInfo x) {
211
            Set<GutterIconInfo> set = this.iconInfos.get(tag);
212
            if( set == null ) {
213
                set = new HashSet<>();
214
                this.iconInfos.put(tag, set);
215
            }
216
            set.add(x);
217
        }
218
219
        public void removeAll() {
220
            this.iconInfos = new HashMap<>();
221
        }
222
223
        public void remove(String tag) {
224
            this.iconInfos.remove(tag);
225
        }
226
227
        public void remove(String tag, GutterIconInfo x) {
228
            Set<GutterIconInfo> set = this.iconInfos.get(tag);
229
            if( set == null ) {
230
                return;
231
            }
232
            set.remove(x);
233
        }
234
235
        public boolean exists(String tag) {
236
            return this.iconInfos.containsKey(tag);
237
        }
238
239
        public Set<GutterIconInfo> get(String tag) {
240
            Set<GutterIconInfo> set = this.iconInfos.get(tag);
241
            return set;
242
        }
243
    }
244
245 468 jjdelcerro
    private final FindToolBar findToolBar;
246
    private final ReplaceToolBar replaceToolBar;
247
    private final CollapsibleSectionPanel csp;
248 368 jjdelcerro
249 468 jjdelcerro
    public class DefaultUpdateCaretPositionActionEvent extends ActionEvent implements UpdateCaretPositionActionEvent {
250 368 jjdelcerro
251 468 jjdelcerro
        /**
252
         *
253
         */
254
        private static final long serialVersionUID = 8238486105726094074L;
255
        int line = -1;
256
        int column = -1;
257 368 jjdelcerro
258 468 jjdelcerro
        public DefaultUpdateCaretPositionActionEvent(Object source, int id,
259
                String command, int line, int column) {
260
            super(source, id, command);
261
            this.line = line;
262
            this.column = column;
263
        }
264 368 jjdelcerro
265 468 jjdelcerro
        public int getLine() {
266
            return this.line + 1;
267
        }
268 368 jjdelcerro
269 468 jjdelcerro
        public int getColumn() {
270
            return this.column;
271
        }
272 368 jjdelcerro
273 468 jjdelcerro
        public boolean hasLineAndColumn() {
274
            return this.line >= 0 && this.column >= 0;
275
        }
276 368 jjdelcerro
277 468 jjdelcerro
    }
278 368 jjdelcerro
279 468 jjdelcerro
    protected ActionListener updateCaretPosition = null;
280
    protected RSyntaxTextArea textArea = null;
281
    private final RTextScrollPane scrollPanel;
282 678 jjdelcerro
    private final JPanel panel;
283
    private final Map<String, String> contentTypeAlias;
284
    private final IconsTracker iconsTracker = new IconsTracker();
285 686 jjdelcerro
    private LineTrackerPanel lineTrackerPanel;
286 1066 jjdelcerro
    private ScriptingUIManager scriptingUIManager;
287
288 478 jjdelcerro
289 468 jjdelcerro
    public JRSyntaxTextArea() {
290
        this.contentTypeAlias = new HashMap<>();
291 478 jjdelcerro
        this.contentTypeAlias.put("text/r", SyntaxConstants.SYNTAX_STYLE_C);
292 468 jjdelcerro
        this.contentTypeAlias.put("text/ecmascript", SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT);
293 1120 jjdelcerro
        this.contentTypeAlias.put("text/cosa", SyntaxConstants.SYNTAX_STYLE_SQL);
294 368 jjdelcerro
295 468 jjdelcerro
        this.textArea = new RSyntaxTextArea(20, 60);
296 686 jjdelcerro
297 468 jjdelcerro
        this.init();
298 686 jjdelcerro
        lineTrackerPanel = new LineTrackerPanel();
299 468 jjdelcerro
        scrollPanel = new RTextScrollPane(this.textArea);
300 678 jjdelcerro
        scrollPanel.setIconRowHeaderEnabled(true);
301
        scrollPanel.setLineNumbersEnabled(true);
302
        scrollPanel.setFoldIndicatorEnabled(true);
303
304 468 jjdelcerro
        panel = new JPanel();
305
        panel.setLayout(new BorderLayout());
306
        panel.add(scrollPanel, BorderLayout.CENTER);
307 686 jjdelcerro
        panel.add(lineTrackerPanel,BorderLayout.EAST);
308
309 478 jjdelcerro
        findToolBar = new MyFindToolBar(this);
310
        replaceToolBar = new MyReplaceToolBar(this);
311 468 jjdelcerro
        replaceToolBar.setSearchContext(findToolBar.getSearchContext());
312
        csp = new CollapsibleSectionPanel();
313
        csp.add(scrollPanel);
314
        panel.add(csp, BorderLayout.CENTER);
315 478 jjdelcerro
        int ctrl = (KeyEvent.CTRL_MASK | KeyEvent.ALT_MASK);
316 468 jjdelcerro
        KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_F, ctrl);
317
        csp.addBottomComponent(ks, findToolBar);
318
        ks = KeyStroke.getKeyStroke(KeyEvent.VK_H, ctrl);
319
        csp.addBottomComponent(ks, replaceToolBar);
320 478 jjdelcerro
321 468 jjdelcerro
        textArea.addKeyListener(new KeyListener() {
322
323
            @Override
324
            public void keyTyped(KeyEvent ke) {
325
            }
326
327
            @Override
328
            public void keyPressed(KeyEvent ke) {
329 478 jjdelcerro
                if (ke.getModifiers() == (KeyEvent.CTRL_MASK | KeyEvent.ALT_MASK)) {
330
                    if (ke.getKeyCode() == KeyEvent.VK_H) {
331 468 jjdelcerro
                        csp.showBottomComponent(replaceToolBar);
332 478 jjdelcerro
                    } else if (ke.getKeyCode() == KeyEvent.VK_F) {
333 468 jjdelcerro
                        csp.showBottomComponent(findToolBar);
334 478 jjdelcerro
                    }
335 468 jjdelcerro
                }
336
            }
337
338
            @Override
339
            public void keyReleased(KeyEvent ke) {
340
            }
341
        });
342
343
    }
344
345
    protected void init() {
346
        textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_PYTHON);
347
        textArea.setCodeFoldingEnabled(true);
348
        textArea.setClearWhitespaceLinesEnabled(true);
349
        textArea.setAutoIndentEnabled(true);
350
        textArea.setCloseCurlyBraces(true);
351
        textArea.setWhitespaceVisible(true);
352
        textArea.setAnimateBracketMatching(true);
353
        textArea.setBracketMatchingEnabled(true);
354
        textArea.setAutoIndentEnabled(true);
355
        textArea.setTabsEmulated(true);
356
        textArea.setTabSize(2);
357
        textArea.setAntiAliasingEnabled(true);
358
359
        textArea.addCaretListener(new CaretListener() {
360
            public void caretUpdate(CaretEvent e) {
361
                if (updateCaretPosition == null) {
362
                    return;
363
                }
364
                updateCaretPosition.actionPerformed(
365
                        new DefaultUpdateCaretPositionActionEvent(textArea, 1, "position", textArea.getCaretLineNumber(), textArea.getCaretOffsetFromLineStart())
366
                );
367
            }
368
369
        });
370 630 jjdelcerro
371
        CompletionProvider provider = new MyCompletionProvider(python_keywords);
372
        AutoCompletion ac = new AutoCompletion(provider);
373
        ac.setListCellRenderer(new MyListCellRenderer());
374
        ac.setTriggerKey(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_DOWN_MASK));
375
        ac.install(textArea);
376 468 jjdelcerro
    }
377
378 1066 jjdelcerro
    private ScriptingUIManager getUIManager() {
379
        if( this.scriptingUIManager==null ) {
380
            this.scriptingUIManager = ScriptingSwingLocator.getUIManager();
381
        }
382
        return this.scriptingUIManager;
383
    }
384
385
    private ImageIcon getIcon(String key) {
386
        ImageIcon icon = this.getUIManager().getIcon(key);
387
        return icon;
388
    }
389
390
391 630 jjdelcerro
    private static class MyListCellRenderer extends DefaultListCellRenderer {
392
393
        @Override
394
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
395
            Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); //To change body of generated methods, choose Tools | Templates.
396
            ((JLabel) comp).setIcon(((Completion) value).getIcon());
397
            return comp;
398
        }
399
400
    }
401
402
    private String[] python_keywords = new String[]{
403
        "except",
404
        "class",
405
        "continue",
406
        "else",
407
        "finally",
408
        "if",
409
        "elif",
410
        "in",
411
        "return",
412
        "raise",
413
        "try",
414
        "while",
415
        "def",
416
        "print",
417
        "globals",
418
        "for",
419
        "pass",
420
        "from",
421
        "import",
422
        "True",
423
        "False",
424
        "None",
425
        "self",
426 687 jjdelcerro
        "break",
427 630 jjdelcerro
        "__init__",
428
        "__len__",
429
        "__str__",
430
        "__repr__",
431
        "__call__",
432
        "__iter__",
433
        "__class__",
434
        "__getattr__",
435
        "__setattr__",
436
        "__delattr__",
437
        "__getitem__",
438
        "__setitem__",
439
        "__delitem__",
440
        "__getslice__",
441
        "__setslice__",
442
        "__delslice__",
443
        "__getattribute__",
444
        "__setattribute__",
445
        "__contains__",
446
        "__reduce__",
447
        "__cmp__",
448
        "__eq__",
449
        "__ne__",
450
        "__lt__",
451
        "__le__",
452
        "__gt__",
453
        "__ge__",
454
        "__mul__",
455
        "__imul__",
456
        "__rmul__",
457
        "__add__",
458
        "__iadd__",
459
        "__radd__",
460
        "__mod__",
461
        "__rmod__",
462
        "int",
463
        "unicode",
464
        "str",
465
        "float",
466
        "long",
467
        "list",
468
        "tuple",
469
        "dict",
470
        "iter",
471
        "vars",
472
        "isinstance",
473
        "dir",
474
        "repr",
475
        "reduce",
476
        "zip",
477
        "chr",
478
        "hex",
479
        "id",
480
        "max",
481
        "min",
482
        "oct",
483
        "pow",
484
        "ord",
485
        "unichr",
486
        "range",
487
        "xrange",
488
        "abs",
489
        "len",
490
        "apply",
491
        "open",
492
        "getattr",
493
        "setattr",
494
        "hasattr"
495
    };
496
497
    private class MyCompletionProvider extends DefaultCompletionProvider {
498
499
        private List<Completion> keywords;
500
        private Icon keywordIcon;
501
        private Icon wordIcon;
502
503
        public MyCompletionProvider(String[] keywords) {
504
            ClassLoader loader = this.getClass().getClassLoader();
505
            URL url = loader.getResource("org/gvsig/scripting/swing/impl/syntaxhighlight/images/autocompletion_keywords.png");
506
            if (url != null) {
507
                keywordIcon = new ImageIcon(url);
508
            }
509
            url = loader.getResource("org/gvsig/scripting/swing/impl/syntaxhighlight/images/autocompletion_words.png");
510
            if (url != null) {
511
                wordIcon = new ImageIcon(url);
512
            }
513
514
            this.keywords = new ArrayList<>();
515
            for (String keyword : keywords) {
516
                BasicCompletion completion = new BasicCompletion(this, keyword);
517
                completion.setIcon(keywordIcon);
518
                this.keywords.add(completion);
519
            }
520
        }
521
522
523
524
        @Override
525
        protected List<Completion> getCompletionsImpl(JTextComponent comp) {
526
            TreeSet all = new TreeSet();
527
            all.addAll(this.keywords);
528
529
            String s = comp.getText();
530
            String[] x = StringUtils.split(s, "\\ \n\t\r!\"><'@#|$%&/()=??,.;:{}[]*-+");
531
            TreeSet<String> words = new TreeSet(new Comparator<String>() {
532
                @Override
533
                public int compare(String o1, String o2) {
534
                    return o1.compareTo(o2);
535
                }
536
            });
537
            words.addAll(Arrays.asList(x));
538
            for (String word : words) {
539 687 jjdelcerro
                BasicCompletion completion = new BasicCompletion(this, word);
540 630 jjdelcerro
                completion.setIcon(wordIcon);
541
                completion.setRelevance(10);
542
                all.add(completion);
543
            }
544
            completions = new ArrayList<>();
545
            completions.addAll(all);
546
            return super.getCompletionsImpl(comp);
547
        }
548
549
    }
550
551 468 jjdelcerro
    private String normalizeContentType(String s) {
552
        s = s.toLowerCase();
553 478 jjdelcerro
        if (this.contentTypeAlias.containsKey(s)) {
554 468 jjdelcerro
            s = this.contentTypeAlias.get(s);
555
        }
556
        return s;
557
    }
558 478 jjdelcerro
559 468 jjdelcerro
    public void setContentType(String contentType) {
560 1200 jjdelcerro
        TokenMakerFactory factory = TokenMakerFactory.getDefaultInstance();
561
        Set<String> mimetypes = factory.keySet();
562
        String mimetype = this.normalizeContentType(contentType);
563
        if( !mimetypes.contains(mimetype)) {
564
          mimetype = mimetype.replace("-source", "");
565
          if( !mimetypes.contains(mimetype)) {
566
            mimetype = mimetype.replace("/x-", "/");
567
            if( !mimetypes.contains(mimetype)) {
568
              mimetype = this.normalizeContentType(contentType);
569
            }
570
          }
571
        }
572
        this.textArea.setSyntaxEditingStyle(mimetype);
573 468 jjdelcerro
    }
574
575
    public JScrollPane getJScrollPane() {
576
        return this.scrollPanel;
577
    }
578
579
    public JTextComponent getJTextComponent() {
580
        return this.textArea;
581
    }
582
583
    @Override
584
    public JComponent asJComponent() {
585
        return this.panel;
586
    }
587
588
    public String getContentType() {
589
        return this.textArea.getSyntaxEditingStyle();
590
    }
591
592
    public void addUpdateCaretPositionActionListener(ActionListener updateCaretPosition) {
593
        this.updateCaretPosition = updateCaretPosition;
594
    }
595
596
    public void setText(String text) {
597
        this.textArea.setText(text);
598
    }
599
600
    public String getText() {
601
        return this.textArea.getText();
602
    }
603
604
    public void addKeyListener(KeyListener keyListener) {
605
        this.textArea.addKeyListener(keyListener);
606
    }
607
608
    @Override
609
    public void searchEvent(SearchEvent e) {
610
611
        SearchEvent.Type type = e.getType();
612
        SearchContext context = e.getSearchContext();
613
        SearchResult result = null;
614
615
        switch (type) {
616
            default: // Prevent FindBugs warning later
617
            case MARK_ALL:
618
                result = SearchEngine.markAll(textArea, context);
619
                break;
620
            case FIND:
621
                result = SearchEngine.find(textArea, context);
622
                if (!result.wasFound()) {
623 630 jjdelcerro
                    textArea.getCaret().setDot(0);
624
                    result = SearchEngine.find(textArea, context);
625
                    if (!result.wasFound()) {
626
                        UIManager.getLookAndFeel().provideErrorFeedback(textArea);
627
                    }
628 468 jjdelcerro
                }
629
                break;
630
            case REPLACE:
631
                result = SearchEngine.replace(textArea, context);
632
                if (!result.wasFound()) {
633
                    UIManager.getLookAndFeel().provideErrorFeedback(textArea);
634
                }
635
                break;
636
            case REPLACE_ALL:
637
                result = SearchEngine.replaceAll(textArea, context);
638
                JOptionPane.showMessageDialog(null, result.getCount()
639
                        + " occurrences replaced.");
640
                break;
641
        }
642
        String text = null;
643
        if (result.wasFound()) {
644
            text = "Text found; occurrences marked: " + result.getMarkedCount();
645
        } else if (type == SearchEvent.Type.MARK_ALL) {
646
            if (result.getMarkedCount() > 0) {
647
                text = "Occurrences marked: " + result.getMarkedCount();
648
            } else {
649
                text = "";
650
            }
651
        } else {
652
            text = "Text not found";
653
        }
654
        //setMessage(text);
655
    }
656
657
    @Override
658
    public String getSelectedText() {
659
        return textArea.getSelectedText();
660
    }
661
662 678 jjdelcerro
    /**
663
     *
664
     */
665 630 jjdelcerro
    @Override
666
    public void discardAllEdits() {
667
        this.textArea.discardAllEdits();
668
    }
669 678 jjdelcerro
670
    @Override
671
    public void removeTrackingIcons() {
672
        this.scrollPanel.getGutter().removeAllTrackingIcons();
673
        this.iconsTracker.removeAll();
674 686 jjdelcerro
        this.lineTrackerPanel.removeLineTrackers();
675 678 jjdelcerro
    }
676
677
    @Override
678
    public void addLineTrackingIcon(String tag, int line, Icon icon, String tip) {
679 686 jjdelcerro
        addLineTrackingIcon(tag, line, icon, tip, Color.BLUE.darker());
680
    }
681
682
    @Override
683
    public void addLineTrackingIcon(String tag, int line, Icon icon, String tip, Color color) {
684 678 jjdelcerro
        try {
685
            GutterIconInfo x = this.scrollPanel.getGutter().addLineTrackingIcon(line,icon,tip);
686
            this.iconsTracker.add(tag, x);
687 686 jjdelcerro
            this.lineTrackerPanel.addLineTracker(tag, line, tip, color);
688 678 jjdelcerro
        } catch (BadLocationException ex) {
689
            throw new RuntimeException("Can't add tracking icon with tag '"+tag+"' in line '"+line+"', tip='"+tip+"'", ex);
690
        }
691
    }
692
693
    @Override
694
    public void removeTrackingIcons(String tag) {
695
        Set<GutterIconInfo> icontags = this.iconsTracker.get(tag);
696
        if( icontags!=null ) {
697
            for (GutterIconInfo icontag : icontags) {
698
                this.scrollPanel.getGutter().removeTrackingIcon(icontag);
699
            }
700
            this.iconsTracker.remove(tag);
701
        }
702 686 jjdelcerro
        this.lineTrackerPanel.removeLineTrackers(tag);
703 678 jjdelcerro
    }
704 686 jjdelcerro
705
    @Override
706
    public void gotoline(final int line) {
707
        JTextComponent component = getJTextComponent();
708
709
        Element root = component.getDocument().getDefaultRootElement();
710
        int lineno = Math.max(line, 1);
711
        int maxlines = root.getElementCount();
712
        lineno = Math.min(lineno, maxlines);
713
        int startOfLineOffset = root.getElement( lineno - 1 ).getStartOffset();
714
        component.setCaretPosition( startOfLineOffset );
715
716
        Container container = SwingUtilities.getAncestorOfClass(JViewport.class, component);
717
        if (container == null) {
718
            return;
719
        }
720
        try {
721
            Rectangle r = component.modelToView(component.getCaretPosition());
722
            JViewport viewport = (JViewport) container;
723
            int extentHeight = viewport.getExtentSize().height;
724
            int viewHeight = viewport.getViewSize().height;
725
726
            int y = Math.max(0, r.y - ((extentHeight - r.height) / 2));
727
            y = Math.min(y, viewHeight - extentHeight);
728
729
            viewport.setViewPosition(new Point(0, y));
730
        } catch (BadLocationException ble) {
731
            ble.printStackTrace();
732
        }
733
        try {
734
            component.setCaretPosition( startOfLineOffset+1 );
735
        } catch (Exception e) {
736
            e.printStackTrace();
737
        }
738
    }
739
740 368 jjdelcerro
}