IDEADEV-41265 (IU-9.0 Beta - Undo does not revert file to unchanged)
[fedora-idea.git] / platform / vcs-impl / src / com / intellij / openapi / vcs / impl / UpToDateLineNumberProviderImpl.java
blob5e22d632a6d8b65644e0dcc6da1da396543c518c
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.openapi.vcs.impl;
18 import com.intellij.openapi.editor.Document;
19 import com.intellij.openapi.localVcs.UpToDateLineNumberProvider;
20 import com.intellij.openapi.project.Project;
21 import com.intellij.openapi.vcs.ex.LineStatusTracker;
22 import com.intellij.openapi.vcs.ex.Range;
23 import com.intellij.openapi.vfs.VirtualFile;
25 import java.util.List;
27 /**
28 * author: lesya
30 public class UpToDateLineNumberProviderImpl implements UpToDateLineNumberProvider {
31 private final Document myDocument;
32 private final Project myProject;
33 private final String myUpToDateContent;
34 private final VirtualFile myVf;
36 public UpToDateLineNumberProviderImpl(Document document, Project project, String upToDateContent, VirtualFile vf) {
37 myDocument = document;
38 myProject = project;
39 myUpToDateContent = upToDateContent;
40 myVf = vf;
43 public int getLineNumber(int currentNumber) {
44 LineStatusTracker tracker = LineStatusTrackerManager.getInstance(myProject).getLineStatusTracker(myDocument);
45 if (tracker == null) {
46 tracker = LineStatusTrackerManager.getInstance(myProject).setUpToDateContent(myDocument, myUpToDateContent, myVf);
48 return calcLineNumber(tracker, currentNumber);
51 private boolean endsWithSeparator(final CharSequence string) {
52 if ((string == null) || (string.length() == 0)) {
53 return false;
55 final char latest = string.charAt(string.length() - 1);
56 return ('\n' == latest) || ('\r' == latest);
59 // annotated content is not aware about latest line ends with end-line separator or not. ignore latest separator difference then
60 private String fixLatestLineSeparator(final Document document, final String content) {
61 final CharSequence documentSequence = document.getCharsSequence();
62 if (endsWithSeparator(documentSequence) && (! endsWithSeparator(content))) {
63 int numCharsToCopy = 1;
64 final int docLen = documentSequence.length();
65 if (docLen > 1) {
66 final char beforeLatest = documentSequence.charAt(docLen - 2);
67 if (('\r' == beforeLatest) || ('\n' == beforeLatest)) {
68 numCharsToCopy = 2;
71 return content + documentSequence.subSequence(docLen - numCharsToCopy, docLen);
73 return content;
76 private static int calcLineNumber(LineStatusTracker tracker, int currentNumber){
77 if (tracker == null) return -1;
78 List ranges = tracker.getRanges();
79 int result = currentNumber;
81 for (final Object range1 : ranges) {
82 Range range = (Range)range1;
83 int startOffset = range.getOffset1();
84 int endOffset = range.getOffset2();
86 if ((startOffset <= currentNumber) && (endOffset > currentNumber)) {
87 return ABSENT_LINE_NUMBER;
90 if (endOffset > currentNumber) return result;
92 int currentRangeLength = endOffset - startOffset;
94 result += range.getUpToDateRangeLength() - currentRangeLength;
96 return result;