changedUpdate exception
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / editor / impl / event / DocumentEventImpl.java
blobd73844a04713264a8674c71d487011fde1a57ee9
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.editor.impl.event;
18 import com.intellij.openapi.editor.Document;
19 import com.intellij.openapi.editor.event.DocumentEvent;
20 import com.intellij.openapi.util.text.LineTokenizer;
21 import com.intellij.openapi.util.text.StringUtil;
22 import com.intellij.util.diff.Diff;
23 import org.jetbrains.annotations.NotNull;
25 public class DocumentEventImpl extends DocumentEvent {
26 private final int myOffset;
27 private final CharSequence myOldString;
28 private final int myOldLength;
29 private final CharSequence myNewString;
30 private final int myNewLength;
32 private boolean isOnlyOneLineChangedCalculated = false;
33 private boolean isOnlyOneLineChanged;
35 private boolean isStartOldIndexCalculated = false;
36 private int myStartOldIndex;
38 private final long myOldTimeStamp;
39 private final boolean myIsWholeDocReplaced;
40 private Diff.Change myChange;
42 private int myOptimizedLineShift = -1;
43 private boolean myOptimizedLineShiftCalculated;
45 private int myOptimizedOldLineShift = -1;
46 private boolean myOptimizedOldLineShiftCalculated;
48 public DocumentEventImpl(Document document, int offset, CharSequence oldString, CharSequence newString, long oldTimeStamp,
49 boolean wholeTextReplaced) {
50 super(document);
51 myOffset = offset;
53 myOldString = oldString == null ? "" : oldString;
54 myOldLength = myOldString.length();
56 myNewString = newString == null ? "" : newString;
57 myNewLength = myNewString.length();
59 myOldTimeStamp = oldTimeStamp;
61 if (getDocument().getTextLength() == 0) {
62 isOnlyOneLineChangedCalculated = true;
63 isOnlyOneLineChanged = false;
64 myIsWholeDocReplaced = false;
66 else {
67 myIsWholeDocReplaced = wholeTextReplaced;
71 public int getOffset() {
72 return myOffset;
75 public int getOldLength() {
76 return myOldLength;
79 public int getNewLength() {
80 return myNewLength;
83 public CharSequence getOldFragment() {
84 return myOldString;
87 public CharSequence getNewFragment() {
88 return myNewString;
91 @NotNull
92 public Document getDocument() {
93 return (Document) getSource();
96 public int getStartOldIndex() {
97 if(isStartOldIndexCalculated) return myStartOldIndex;
99 isStartOldIndexCalculated = true;
100 myStartOldIndex = getDocument().getLineNumber(myOffset);
101 return myStartOldIndex;
104 public boolean isOnlyOneLineChanged() {
105 if(isOnlyOneLineChangedCalculated) return isOnlyOneLineChanged;
107 isOnlyOneLineChangedCalculated = true;
108 isOnlyOneLineChanged = true;
110 for(int i=0; i<myOldString.length(); i++) {
111 if(myOldString.charAt(i) == '\n') {
112 isOnlyOneLineChanged = false;
113 break;
117 if(isOnlyOneLineChanged) {
118 for(int i=0; i<myNewString.length(); i++) {
119 if(myNewString.charAt(i) == '\n') {
120 isOnlyOneLineChanged = false;
121 break;
125 return isOnlyOneLineChanged;
128 public long getOldTimeStamp() {
129 return myOldTimeStamp;
132 @SuppressWarnings({"HardCodedStringLiteral"})
133 public String toString() {
134 return "DocumentEventImpl[myOffset=" + myOffset + ", myOldLength=" + myOldLength + ", myNewLength=" + myNewLength +
135 ", myOldString='" + myOldString + "', myNewString='" + myNewString + "']" + (isWholeTextReplaced() ? " Whole." : ".");
138 public boolean isWholeTextReplaced() {
139 return myIsWholeDocReplaced;
142 public int translateLineViaDiff(int line) {
143 if (myChange == null) buildDiff();
144 if (myChange == null) return line;
146 Diff.Change change = myChange;
148 int newLine = line;
150 while (change != null) {
151 if (line < change.line0) break;
152 if (line >= change.line0 + change.deleted) {
153 newLine += change.inserted - change.deleted;
154 } else {
155 int delta = Math.min(change.inserted, line - change.line0);
156 newLine = change.line1 + delta;
157 break;
160 change = change.link;
163 return newLine;
166 public int translateLineViaDiffStrict(int line) {
167 if (myChange == null) buildDiff();
168 if (myChange == null) return line;
170 Diff.Change change = myChange;
172 int newLine = line;
174 while (change != null) {
175 if (line < change.line0) break;
176 if (line >= change.line0 + change.deleted) {
177 newLine += change.inserted - change.deleted;
178 } else {
179 return -1;
182 change = change.link;
185 return newLine;
188 private void buildDiff() {
189 final String[] strings1 = LineTokenizer.tokenize(myOldString, false);
190 final String[] strings2 = LineTokenizer.tokenize(myNewString, false);
192 //Diff diff = new Diff(strings1, strings2);
193 //myChange = diff.diff_2(false);
194 myChange = Diff.buildChanges(strings1, strings2);
197 public int getOptimizedLineShift() {
198 if (!myOptimizedLineShiftCalculated) {
199 myOptimizedLineShiftCalculated = true;
201 if (myOldLength == 0) {
202 int lineShift = StringUtil.countNewLines(myNewString);
204 myOptimizedLineShift = lineShift == 0 ? -1 : lineShift;
207 return myOptimizedLineShift;
210 public int getOptimizedOldLineShift() {
211 if (!myOptimizedOldLineShiftCalculated) {
212 myOptimizedOldLineShiftCalculated = true;
214 if (myNewLength == 0) {
215 int lineShift = StringUtil.countNewLines(myOldString);
217 myOptimizedOldLineShift = lineShift == 0 ? -1 : lineShift;
220 return myOptimizedOldLineShift;