1 11 package org.eclipse.jface.text; 12 13 14 import java.util.ArrayList ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 18 import org.eclipse.swt.SWT; 19 import org.eclipse.swt.custom.TextChangeListener; 20 import org.eclipse.swt.custom.TextChangedEvent; 21 import org.eclipse.swt.custom.TextChangingEvent; 22 23 import org.eclipse.core.runtime.Assert; 24 25 26 32 class DefaultDocumentAdapter implements IDocumentAdapter, IDocumentListener, IDocumentAdapterExtension { 33 34 35 private IDocument fDocument; 36 37 private IDocument fDocumentClone; 38 39 private String fOriginalContent; 40 41 private String [] fOriginalLineDelimiters; 42 43 private List fTextChangeListeners= new ArrayList (1); 44 48 private DocumentEvent fEvent; 49 50 private String fLineDelimiter= null; 51 55 private boolean fIsForwarding= true; 56 60 private int fRememberedLengthOfDocument; 61 65 private int fRememberedLengthOfFirstLine; 66 70 private DocumentEvent fOriginalEvent= new DocumentEvent(); 71 72 73 77 public DefaultDocumentAdapter() { 78 } 79 80 85 public void setDocument(IDocument document) { 86 87 if (fDocument != null) 88 fDocument.removePrenotifiedDocumentListener(this); 89 90 fDocument= document; 91 fLineDelimiter= null; 92 93 if (!fIsForwarding) { 94 fDocumentClone= null; 95 if (fDocument != null) { 96 fOriginalContent= fDocument.get(); 97 fOriginalLineDelimiters= fDocument.getLegalLineDelimiters(); 98 } else { 99 fOriginalContent= null; 100 fOriginalLineDelimiters= null; 101 } 102 } 103 104 if (fDocument != null) 105 fDocument.addPrenotifiedDocumentListener(this); 106 } 107 108 111 public void addTextChangeListener(TextChangeListener listener) { 112 Assert.isNotNull(listener); 113 if (! fTextChangeListeners.contains(listener)) 114 fTextChangeListeners.add(listener); 115 } 116 117 120 public void removeTextChangeListener(TextChangeListener listener) { 121 Assert.isNotNull(listener); 122 fTextChangeListeners.remove(listener); 123 } 124 125 132 private void repairLineInformation(IDocument document) { 133 if (document instanceof IRepairableDocument) { 134 IRepairableDocument repairable= (IRepairableDocument) document; 135 repairable.repairLineInformation(); 136 } 137 } 138 139 148 private String doGetLine(IDocument document, int line) throws BadLocationException { 149 IRegion r= document.getLineInformation(line); 150 return document.get(r.getOffset(), r.getLength()); 151 } 152 153 private IDocument getDocumentForRead() { 154 if (!fIsForwarding) { 155 if (fDocumentClone == null) { 156 String content= fOriginalContent == null ? "" : fOriginalContent; String [] delims= fOriginalLineDelimiters == null ? DefaultLineTracker.DELIMITERS : fOriginalLineDelimiters; 158 fDocumentClone= new DocumentClone(content, delims); 159 } 160 return fDocumentClone; 161 } 162 163 return fDocument; 164 } 165 166 169 public String getLine(int line) { 170 171 IDocument document= getDocumentForRead(); 172 try { 173 return doGetLine(document, line); 174 } catch (BadLocationException x) { 175 repairLineInformation(document); 176 try { 177 return doGetLine(document, line); 178 } catch (BadLocationException x2) { 179 } 180 } 181 182 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 183 return null; 184 } 185 186 189 public int getLineAtOffset(int offset) { 190 IDocument document= getDocumentForRead(); 191 try { 192 return document.getLineOfOffset(offset); 193 } catch (BadLocationException x) { 194 repairLineInformation(document); 195 try { 196 return document.getLineOfOffset(offset); 197 } catch (BadLocationException x2) { 198 } 199 } 200 201 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 202 return -1; 203 } 204 205 208 public int getLineCount() { 209 return getDocumentForRead().getNumberOfLines(); 210 } 211 212 215 public int getOffsetAtLine(int line) { 216 IDocument document= getDocumentForRead(); 217 try { 218 return document.getLineOffset(line); 219 } catch (BadLocationException x) { 220 repairLineInformation(document); 221 try { 222 return document.getLineOffset(line); 223 } catch (BadLocationException x2) { 224 } 225 } 226 227 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 228 return -1; 229 } 230 231 234 public String getTextRange(int offset, int length) { 235 try { 236 return getDocumentForRead().get(offset, length); 237 } catch (BadLocationException x) { 238 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 239 return null; 240 } 241 } 242 243 246 public void replaceTextRange(int pos, int length, String text) { 247 try { 248 fDocument.replace(pos, length, text); 249 } catch (BadLocationException x) { 250 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 251 } 252 } 253 254 257 public void setText(String text) { 258 fDocument.set(text); 259 } 260 261 264 public int getCharCount() { 265 return getDocumentForRead().getLength(); 266 } 267 268 271 public String getLineDelimiter() { 272 if (fLineDelimiter == null) 273 fLineDelimiter= TextUtilities.getDefaultLineDelimiter(fDocument); 274 return fLineDelimiter; 275 } 276 277 280 public void documentChanged(DocumentEvent event) { 281 if (fEvent == null || event != fEvent) 283 return; 284 285 if (isPatchedEvent(event) || (event.getOffset() == 0 && event.getLength() == fRememberedLengthOfDocument)) { 286 fLineDelimiter= null; 287 fireTextSet(); 288 } else { 289 if (event.getOffset() < fRememberedLengthOfFirstLine) 290 fLineDelimiter= null; 291 fireTextChanged(); 292 } 293 } 294 295 298 public void documentAboutToBeChanged(DocumentEvent event) { 299 300 fRememberedLengthOfDocument= fDocument.getLength(); 301 try { 302 fRememberedLengthOfFirstLine= fDocument.getLineLength(0); 303 } catch (BadLocationException e) { 304 fRememberedLengthOfFirstLine= -1; 305 } 306 307 fEvent= event; 308 rememberEventData(fEvent); 309 fireTextChanging(); 310 } 311 312 319 private boolean isPatchedEvent(DocumentEvent event) { 320 return fOriginalEvent.fOffset != event.fOffset || fOriginalEvent.fLength != event.fLength || fOriginalEvent.fText != event.fText; 321 } 322 323 328 private void rememberEventData(DocumentEvent event) { 329 fOriginalEvent.fOffset= event.fOffset; 330 fOriginalEvent.fLength= event.fLength; 331 fOriginalEvent.fText= event.fText; 332 } 333 334 337 private void fireTextChanged() { 338 339 if (!fIsForwarding) 340 return; 341 342 TextChangedEvent event= new TextChangedEvent(this); 343 344 if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) { 345 Iterator e= new ArrayList (fTextChangeListeners).iterator(); 346 while (e.hasNext()) 347 ((TextChangeListener) e.next()).textChanged(event); 348 } 349 } 350 351 354 private void fireTextSet() { 355 356 if (!fIsForwarding) 357 return; 358 359 TextChangedEvent event = new TextChangedEvent(this); 360 361 if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) { 362 Iterator e= new ArrayList (fTextChangeListeners).iterator(); 363 while (e.hasNext()) 364 ((TextChangeListener) e.next()).textSet(event); 365 } 366 } 367 368 371 private void fireTextChanging() { 372 373 if (!fIsForwarding) 374 return; 375 376 try { 377 IDocument document= fEvent.getDocument(); 378 if (document == null) 379 return; 380 381 TextChangingEvent event= new TextChangingEvent(this); 382 event.start= fEvent.fOffset; 383 event.replaceCharCount= fEvent.fLength; 384 event.replaceLineCount= document.getNumberOfLines(fEvent.fOffset, fEvent.fLength) - 1; 385 event.newText= fEvent.fText; 386 event.newCharCount= (fEvent.fText == null ? 0 : fEvent.fText.length()); 387 event.newLineCount= (fEvent.fText == null ? 0 : document.computeNumberOfLines(fEvent.fText)); 388 389 if (fTextChangeListeners != null && fTextChangeListeners.size() > 0) { 390 Iterator e= new ArrayList (fTextChangeListeners).iterator(); 391 while (e.hasNext()) 392 ((TextChangeListener) e.next()).textChanging(event); 393 } 394 395 } catch (BadLocationException e) { 396 } 397 } 398 399 403 public void resumeForwardingDocumentChanges() { 404 fIsForwarding= true; 405 fDocumentClone= null; 406 fOriginalContent= null; 407 fOriginalLineDelimiters= null; 408 fireTextSet(); 409 } 410 411 415 public void stopForwardingDocumentChanges() { 416 fDocumentClone= null; 417 fOriginalContent= fDocument.get(); 418 fOriginalLineDelimiters= fDocument.getLegalLineDelimiters(); 419 fIsForwarding= false; 420 } 421 } 422 | Popular Tags |