/*
* RegexSearcher.java
*
* Created on 03 March 2006, 12:11
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
package org.owasp.webscarab.ui.swing.editors;
import java.awt.Color;
import java.awt.Insets;
import java.awt.Rectangle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
/**
*
* @author rdawes
*/
public class RegexSearcher {
public RegexSearcher(JTextComponent comp, Color matchColor, Color selectionColor) {
this.comp = comp;
this.matchPainter = new DefaultHighlighter.DefaultHighlightPainter(matchColor);
this.selectionPainter = new DefaultHighlighter.DefaultHighlightPainter(selectionColor);
}
// Highlights all occurrences found of the specified pattern.
public void search(String pattern, boolean caseSensitive) throws PatternSyntaxException {
pos = -1;
Highlighter highlighter = comp.getHighlighter();
// Remove any existing highlights for last search
Highlighter.Highlight[] highlights = highlighter.getHighlights();
for (int i = 0; i < highlights.length; i++) {
Highlighter.Highlight h = highlights[i];
if (h.getPainter() == this.matchPainter ||
h.getPainter() == this.selectionPainter) {
highlighter.removeHighlight(h);
}
}
if (pattern == null || "".equals(pattern))
return;
// Look for the pattern we are given - insensitive search
String content = null;
try {
Document d = comp.getDocument();
content = d.getText(0, d.getLength());
} catch (BadLocationException e) {
// Cannot happen
return;
}
int flags = Pattern.DOTALL | Pattern.MULTILINE;
if (!caseSensitive) flags |= Pattern.CASE_INSENSITIVE;
Pattern p = Pattern.compile(pattern, flags);
Matcher m = p.matcher(content);
while (m.find()) {
for (int i=(m.groupCount()>0?1:0); i<=m.groupCount(); i++) {
try {
highlighter.addHighlight(m.start(i), m.end(i), matchPainter);
} catch (BadLocationException e) {}
}
}
}
public int previousMatch() {
Highlighter highlighter = comp.getHighlighter();
Highlighter.Highlight[] highlights = highlighter.getHighlights();
Highlighter.Highlight last = null, previous = null, current = null;
for (int i = 0; i < highlights.length; i++) {
Highlighter.Highlight h = highlights[i];
if (h.getPainter() == matchPainter) {
if (last == null || h.getStartOffset() > last.getStartOffset())
last = h;
if (h.getStartOffset() < pos) {
if (previous == null) {
previous = h;
} else if (previous.getStartOffset() < h.getStartOffset()) {
previous = h;
}
}
} else if (h.getPainter() == selectionPainter) {
current = h;
}
}
if (previous == null)
previous = last;
if (previous == null)
previous = current;
if (previous == null) {
pos = -1;
} else {
if (previous != current)
try {
if (current != null) {
highlighter.removeHighlight(current);
highlighter.addHighlight(current.getStartOffset(), current.getEndOffset(), matchPainter);
}
highlighter.removeHighlight(previous);
highlighter.addHighlight(previous.getStartOffset(), previous.getEndOffset(), selectionPainter);
center(previous);
} catch (BadLocationException ble) {
// impossible
}
pos = previous.getStartOffset();
}
return pos;
}
public int nextMatch() {
Highlighter highlighter = comp.getHighlighter();
Highlighter.Highlight[] highlights = highlighter.getHighlights();
Highlighter.Highlight first = null, next = null, current = null;
for (int i = 0; i < highlights.length; i++) {
Highlighter.Highlight h = highlights[i];
if (h.getPainter() == matchPainter) {
if (first == null || h.getStartOffset() < first.getStartOffset())
first = h;
if (h.getStartOffset() > pos) {
if (next == null) {
next = h;
} else if (next.getStartOffset() > h.getStartOffset()) {
next = h;
}
}
} else if (h.getPainter() == selectionPainter) {
current = h;
}
}
if (next == null)
next = first;
if (next == null)
next = current;
if (next == null) {
pos = -1;
} else {
if (next != current)
try {
if (current != null) {
highlighter.removeHighlight(current);
highlighter.addHighlight(current.getStartOffset(), current.getEndOffset(), matchPainter);
}
highlighter.removeHighlight(next);
highlighter.addHighlight(next.getStartOffset(), next.getEndOffset(), selectionPainter);
center(next);
} catch (BadLocationException ble) {
// impossible
}
pos = next.getStartOffset();
}
return pos;
}
private void center(Highlighter.Highlight match) throws BadLocationException {
Rectangle r = comp.modelToView(match.getStartOffset());
if (r == null)
return;
r.add(comp.modelToView(match.getEndOffset()));
if (! comp.getVisibleRect().contains(r))
center(r, false);
}
private void center(Rectangle r, boolean withInsets) {
Rectangle visible = comp.getVisibleRect();
visible.x = r.x - (visible.width - r.width) / 2;
visible.y = r.y - (visible.height - r.height) / 2;
Rectangle bounds = comp.getBounds();
Insets i = withInsets ? new Insets(0, 0, 0, 0) : comp.getInsets();
bounds.x = i.left;
bounds.y = i.top;
bounds.width -= i.left + i.right;
bounds.height -= i.top + i.bottom;
if (visible.x < bounds.x)
visible.x = bounds.x;
if (visible.x + visible.width > bounds.x + bounds.width)
visible.x = bounds.x + bounds.width - visible.width;
if (visible.y < bounds.y)
visible.y = bounds.y;
if (visible.y + visible.height > bounds.y + bounds.height)
visible.y = bounds.y + bounds.height - visible.height;
comp.scrollRectToVisible(visible);
}
private JTextComponent comp;
private Highlighter.HighlightPainter matchPainter, selectionPainter;
private int pos = -1;
}