/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.search;
import java.util.Vector;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class TextQueryResult {
public class Result {
public int startOffset;
public int endOffset;
public Result(int startOffset, int endOffset) {
this.startOffset = startOffset;
this.endOffset = endOffset;
}
public int getLength() {
return endOffset - startOffset;
}
@Override
public String toString() {
return "Start: " + startOffset + " End: " + endOffset;
}
}
public enum Direction {
FORWARD, BACKWARD
}
public class ResultNavigator {
private int currentIndex = -1;
private Direction direction = Direction.FORWARD;
private boolean wrapSearch = true;
private boolean limitToSelectedText = false;
private int selectionStart;
private int selectionEnd;
public ResultNavigator() {
}
public Result getCurrentResult() {
Vector<Result> res = getFilteredResults();
if (currentIndex > -1 && currentIndex < res.size()) {
return res.get(currentIndex);
} else {
return null;
}
}
public void replaceBy(String replacement) {
if (document == null) {
throw new IllegalStateException("No document provided! Cannot edit the text");
}
Result currentResult = getCurrentResult();
if (currentResult == null) {
throw new IllegalStateException("No text is selected!");
}
try {
document.remove(currentResult.startOffset, currentResult.getLength());
document.insertString(currentResult.startOffset, replacement, null);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
public void replaceAllBy(String replacement) {
Vector<Result> results = getFilteredResults();
for (int i = results.size(); i > 0; i--) {
setCurrentIndex(i - 1);
replaceBy(replacement);
}
}
public Result getNextResult() throws EndOfDocumentHasBeenReachedException, ResultNotFoundException {
Vector<Result> filteredResults = getFilteredResults();
if (filteredResults.size() == 0) {
throw new ResultNotFoundException();
}
switch (direction) {
case FORWARD:
if (currentIndex + 1 == filteredResults.size()) {
if (wrapSearch) {
currentIndex = 0;
} else {
throw new EndOfDocumentHasBeenReachedException();
}
} else {
currentIndex++;
}
return filteredResults.get(currentIndex);
case BACKWARD:
if (currentIndex - 1 < 0) {
if (wrapSearch) {
currentIndex = filteredResults.size() - 1;
} else {
throw new EndOfDocumentHasBeenReachedException();
}
} else {
currentIndex--;
}
return filteredResults.get(currentIndex);
default:
break;
}
return null;
}
private Vector<Result> getFilteredResults() {
if (limitToSelectedText) {
Vector<Result> r = new Vector<Result>();
for (Result result : getResults()) {
if (result.startOffset >= selectionStart && result.endOffset <= selectionEnd) {
r.add(result);
}
}
return r;
} else {
return getResults();
}
}
public void setCurrentCaretPosition(int caretPosition) {
if (caretPosition < 0 || caretPosition >= text.length()) {
return;
}
int index = 0;
for (Result res : getFilteredResults()) {
if (res.startOffset >= caretPosition) {
setCurrentIndex(index - 1);
return;
}
index++;
}
setCurrentIndex(index - 1);
}
public int getCurrentIndex() {
return currentIndex;
}
public void setCurrentIndex(int currentIndex) {
this.currentIndex = currentIndex;
}
public Direction getDirection() {
return direction;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
public boolean isWrapSearch() {
return wrapSearch;
}
public void setWrapSearch(boolean wrapSearch) {
this.wrapSearch = wrapSearch;
}
public boolean isLimitToSelectedText() {
return limitToSelectedText;
}
public void setLimitToSelectedText(boolean limitToSelectedText) {
if (this.limitToSelectedText != limitToSelectedText) {
currentIndex = -1;
}
this.limitToSelectedText = limitToSelectedText;
}
public int getSelectionStart() {
return selectionStart;
}
public void setSelectionStart(int selectionStart) {
this.selectionStart = selectionStart;
}
public int getSelectionEnd() {
return selectionEnd;
}
public void setSelectionEnd(int selectionEnd) {
this.selectionEnd = selectionEnd;
}
}
private TextQuery query;
private Vector<Result> results;
String text;
protected Document document;
public TextQueryResult(TextQuery query) {
this.query = query;
this.results = new Vector<Result>();
}
public TextQueryResult(TextQuery query, String text) {
this.query = query;
this.text = text;
this.results = new Vector<Result>();
}
public TextQueryResult(TextQuery query, Document document) {
this.query = query;
this.document = document;
try {
this.text = document.getText(0, document.getLength());
} catch (BadLocationException e) {
e.printStackTrace();// Should never happen
}
this.results = new Vector<Result>();
}
public void addToResults(Result res) {
results.add(res);
}
public TextQuery getQuery() {
return query;
}
public Vector<Result> getResults() {
return results;
}
}