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
) {
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;
67 myIsWholeDocReplaced
= wholeTextReplaced
;
71 public int getOffset() {
75 public int getOldLength() {
79 public int getNewLength() {
83 public CharSequence
getOldFragment() {
87 public CharSequence
getNewFragment() {
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;
117 if(isOnlyOneLineChanged
) {
118 for(int i
=0; i
<myNewString
.length(); i
++) {
119 if(myNewString
.charAt(i
) == '\n') {
120 isOnlyOneLineChanged
= false;
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
;
150 while (change
!= null) {
151 if (line
< change
.line0
) break;
152 if (line
>= change
.line0
+ change
.deleted
) {
153 newLine
+= change
.inserted
- change
.deleted
;
155 int delta
= Math
.min(change
.inserted
, line
- change
.line0
);
156 newLine
= change
.line1
+ delta
;
160 change
= change
.link
;
166 public int translateLineViaDiffStrict(int line
) {
167 if (myChange
== null) buildDiff();
168 if (myChange
== null) return line
;
170 Diff
.Change change
= myChange
;
174 while (change
!= null) {
175 if (line
< change
.line0
) break;
176 if (line
>= change
.line0
+ change
.deleted
) {
177 newLine
+= change
.inserted
- change
.deleted
;
182 change
= change
.link
;
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
;