blob: 5d049f3e9c14c6e49ab2b9220b191f33e0aecc8a [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.impl;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.localVcs.UpToDateLineNumberProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.ex.LineStatusTracker;
import com.intellij.openapi.vcs.ex.Range;
import java.util.List;
/**
* author: lesya
*/
public class UpToDateLineNumberProviderImpl implements UpToDateLineNumberProvider {
private final Document myDocument;
private final Project myProject;
private final LineStatusTrackerManagerI myLineStatusTrackerManagerI;
public UpToDateLineNumberProviderImpl(Document document, Project project) {
myDocument = document;
myProject = project;
myLineStatusTrackerManagerI = LineStatusTrackerManager.getInstance(myProject);
}
public int getLineNumber(int currentNumber) {
LineStatusTracker tracker = myLineStatusTrackerManagerI.getLineStatusTracker(myDocument);
if (tracker == null) {
return currentNumber;
}
return calcLineNumber(tracker, currentNumber);
}
public boolean isRangeChanged(final int start, final int end) {
LineStatusTracker tracker = LineStatusTrackerManager.getInstance(myProject).getLineStatusTracker(myDocument);
if (tracker == null) {
return false;
}
for (Range range : tracker.getRanges()) {
if (lineInRange(range, start) || lineInRange(range, end)) {
return true;
}
if (range.getLine1() > start) {
return range.getLine1() < end;
}
}
return false;
}
private static boolean lineInRange(final Range range, final int currentNumber) {
return range.getLine1() <= currentNumber && range.getLine2() >= currentNumber;
}
@Override
public boolean isLineChanged(int currentNumber) {
LineStatusTracker tracker = LineStatusTrackerManager.getInstance(myProject).getLineStatusTracker(myDocument);
if (tracker == null) {
return false;
}
for (Range range : tracker.getRanges()) {
if (range.getLine1() <= currentNumber && range.getLine2() >= currentNumber) {
return true;
}
}
return false;
}
private boolean endsWithSeparator(final CharSequence string) {
if ((string == null) || (string.length() == 0)) {
return false;
}
final char latest = string.charAt(string.length() - 1);
return ('\n' == latest) || ('\r' == latest);
}
// annotated content is not aware about latest line ends with end-line separator or not. ignore latest separator difference then
private String fixLatestLineSeparator(final Document document, final String content) {
final CharSequence documentSequence = document.getCharsSequence();
if (endsWithSeparator(documentSequence) && (! endsWithSeparator(content))) {
int numCharsToCopy = 1;
final int docLen = documentSequence.length();
if (docLen > 1) {
final char beforeLatest = documentSequence.charAt(docLen - 2);
if (('\r' == beforeLatest) || ('\n' == beforeLatest)) {
numCharsToCopy = 2;
}
}
return content + documentSequence.subSequence(docLen - numCharsToCopy, docLen);
}
return content;
}
private static int calcLineNumber(LineStatusTracker tracker, int currentNumber){
if (tracker == null) return -1;
List ranges = tracker.getRanges();
int result = currentNumber;
for (final Object range1 : ranges) {
Range range = (Range)range1;
int startOffset = range.getLine1();
int endOffset = range.getLine2();
if ((startOffset <= currentNumber) && (endOffset > currentNumber)) {
return ABSENT_LINE_NUMBER;
}
if (endOffset > currentNumber) return result;
int currentRangeLength = endOffset - startOffset;
result += range.getUpToDateRangeLength() - currentRangeLength;
}
return result;
}
}