/**
* Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.shared_core.string;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.viewers.ISelectionProvider;
/**
* This is a helper class to try to keep a given selection and re-apply it later based
* on the actual lines and columns that were selected.
*/
public class SelectionKeeper {
private final int startLine;
private final int endLine;
private final int startCol;
private final int endCol;
public SelectionKeeper(TextSelectionUtils ps) {
ITextSelection selection = ps.getTextSelection();
startLine = selection.getStartLine();
endLine = selection.getEndLine();
startCol = selection.getOffset() - ps.getLineOffset(startLine);
endCol = (selection.getOffset() + selection.getLength()) - ps.getLineOffset(endLine);
}
/**
* Restores the selection previously gotten.
*/
public void restoreSelection(ISelectionProvider selectionProvider, IDocument doc) {
//OK, now, the start line and the end line should not change -- because the document changed,
//the columns may end up being wrong, so, we must update things so that the selection stays OK.
int numberOfLines = doc.getNumberOfLines();
int startLine = fixBasedOnNumberOfLines(this.startLine, numberOfLines);
int endLine = fixBasedOnNumberOfLines(this.endLine, numberOfLines);
final int startLineOffset = getOffset(doc, startLine);
final int startLineLen = getLineLength(doc, startLine);
final int startLineDelimiterLen = getLineDelimiterLen(doc, startLine);
int startOffset = fixOffset(startLineOffset + startCol, startLineOffset, startLineOffset + startLineLen
- startLineDelimiterLen);
final int endLineOffset = getOffset(doc, endLine);
final int endLineLen = getLineLength(doc, endLine);
final int endLineDelimiterLen = getLineDelimiterLen(doc, endLine);
int endOffset = fixOffset(endLineOffset + endCol, endLineOffset, endLineOffset + endLineLen
- endLineDelimiterLen);
selectionProvider.setSelection(new TextSelection(startOffset, endOffset - startOffset));
}
private int getLineDelimiterLen(IDocument doc, int line) {
try {
String lineDelimiter = doc.getLineDelimiter(line);
if (lineDelimiter == null) {
return 0;
}
return lineDelimiter.length();
} catch (BadLocationException e) {
return 0;
}
}
private int getLineLength(IDocument doc, int line) {
try {
return doc.getLineLength(line);
} catch (BadLocationException e) {
return 0;
}
}
private int fixOffset(int offset, int minOffset, int maxOffset) {
if (offset > maxOffset) {
offset = maxOffset;
}
if (offset < minOffset) {
offset = minOffset;
}
return offset;
}
private int getOffset(IDocument doc, int startLine) {
try {
return doc.getLineOffset(startLine);
} catch (BadLocationException e) {
return 0;
}
}
private int fixBasedOnNumberOfLines(int line, int numberOfLines) {
if (line > numberOfLines - 1) {
line = numberOfLines - 1;
}
if (line < 0) {
line = 0;
}
return line;
}
}