1 11 package org.eclipse.jface.text.source; 12 13 import org.eclipse.swt.SWT; 14 import org.eclipse.swt.custom.StyledText; 15 import org.eclipse.swt.events.DisposeEvent; 16 import org.eclipse.swt.events.DisposeListener; 17 import org.eclipse.swt.events.MouseEvent; 18 import org.eclipse.swt.events.MouseListener; 19 import org.eclipse.swt.events.MouseMoveListener; 20 import org.eclipse.swt.events.PaintEvent; 21 import org.eclipse.swt.events.PaintListener; 22 import org.eclipse.swt.graphics.Color; 23 import org.eclipse.swt.graphics.Font; 24 import org.eclipse.swt.graphics.GC; 25 import org.eclipse.swt.graphics.Image; 26 import org.eclipse.swt.graphics.Point; 27 import org.eclipse.swt.graphics.Rectangle; 28 import org.eclipse.swt.widgets.Canvas; 29 import org.eclipse.swt.widgets.Composite; 30 import org.eclipse.swt.widgets.Control; 31 import org.eclipse.swt.widgets.Display; 32 33 import org.eclipse.core.runtime.Assert; 34 35 import org.eclipse.jface.internal.text.revisions.RevisionPainter; 36 import org.eclipse.jface.internal.text.source.DiffPainter; 37 import org.eclipse.jface.viewers.ISelectionProvider; 38 39 import org.eclipse.jface.text.BadLocationException; 40 import org.eclipse.jface.text.IDocument; 41 import org.eclipse.jface.text.IRegion; 42 import org.eclipse.jface.text.ITextListener; 43 import org.eclipse.jface.text.ITextViewer; 44 import org.eclipse.jface.text.ITextViewerExtension5; 45 import org.eclipse.jface.text.IViewportListener; 46 import org.eclipse.jface.text.JFaceTextUtil; 47 import org.eclipse.jface.text.TextEvent; 48 import org.eclipse.jface.text.revisions.IRevisionRulerColumn; 49 import org.eclipse.jface.text.revisions.RevisionInformation; 50 51 57 public final class ChangeRulerColumn implements IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension, IChangeRulerColumn, IRevisionRulerColumn { 58 61 private class MouseHandler implements MouseListener, MouseMoveListener { 62 63 66 public void mouseUp(MouseEvent event) { 67 } 68 69 72 public void mouseDown(MouseEvent event) { 73 fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); 74 } 75 76 79 public void mouseDoubleClick(MouseEvent event) { 80 fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); 81 } 82 83 86 public void mouseMove(MouseEvent event) { 87 fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y); 88 } 89 } 90 91 94 private class InternalListener implements IViewportListener, ITextListener { 95 96 99 public void viewportChanged(int verticalPosition) { 100 if (verticalPosition != fScrollPos) 101 redraw(); 102 } 103 104 107 public void textChanged(TextEvent event) { 108 109 if (!event.getViewerRedrawState()) 110 return; 111 112 if (fSensitiveToTextChanges || event.getDocumentEvent() == null) 113 postRedraw(); 114 115 } 116 } 117 118 121 private final InternalListener fInternalListener= new InternalListener(); 122 126 private final MouseHandler fMouseHandler= new MouseHandler(); 127 131 private final RevisionPainter fRevisionPainter; 132 136 private final DiffPainter fDiffPainter; 137 138 139 private CompositeRuler fParentRuler; 140 141 private ITextViewer fCachedTextViewer; 142 143 private StyledText fCachedTextWidget; 144 145 private Canvas fCanvas; 146 147 private Color fBackground; 148 149 private IAnnotationModel fAnnotationModel; 150 151 private final int fWidth= 5; 152 153 154 private int fScrollPos; 155 156 private Image fBuffer; 157 158 private boolean fSensitiveToTextChanges= false; 159 160 165 public ChangeRulerColumn() { 166 fRevisionPainter= null; 167 fDiffPainter= new DiffPainter(this, null); 168 } 169 170 176 public ChangeRulerColumn(ISharedTextColors sharedColors) { 177 Assert.isNotNull(sharedColors); 178 fRevisionPainter= new RevisionPainter(this, sharedColors); 179 fDiffPainter= new DiffPainter(this, null); } 181 182 187 private Color getBackground() { 188 if (fBackground == null) 189 return fCachedTextWidget.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND); 190 return fBackground; 191 } 192 193 196 public Control createControl(CompositeRuler parentRuler, Composite parentControl) { 197 198 fParentRuler= parentRuler; 199 fCachedTextViewer= parentRuler.getTextViewer(); 200 fCachedTextWidget= fCachedTextViewer.getTextWidget(); 201 202 fCanvas= new Canvas(parentControl, SWT.NONE); 203 fCanvas.setBackground(getBackground()); 204 205 fCanvas.addPaintListener(new PaintListener() { 206 public void paintControl(PaintEvent event) { 207 if (fCachedTextViewer != null) 208 doubleBufferPaint(event.gc); 209 } 210 }); 211 212 fCanvas.addDisposeListener(new DisposeListener() { 213 public void widgetDisposed(DisposeEvent e) { 214 handleDispose(); 215 fCachedTextViewer= null; 216 fCachedTextWidget= null; 217 } 218 }); 219 220 fCanvas.addMouseListener(fMouseHandler); 221 fCanvas.addMouseMoveListener(fMouseHandler); 222 223 if (fCachedTextViewer != null) { 224 225 fCachedTextViewer.addViewportListener(fInternalListener); 226 fCachedTextViewer.addTextListener(fInternalListener); 227 } 228 229 fRevisionPainter.setParentRuler(parentRuler); 230 fDiffPainter.setParentRuler(parentRuler); 231 232 return fCanvas; 233 } 234 235 238 protected void handleDispose() { 239 240 if (fCachedTextViewer != null) { 241 fCachedTextViewer.removeViewportListener(fInternalListener); 242 fCachedTextViewer.removeTextListener(fInternalListener); 243 } 244 245 if (fBuffer != null) { 246 fBuffer.dispose(); 247 fBuffer= null; 248 } 249 } 250 251 256 private void doubleBufferPaint(GC dest) { 257 258 Point size= fCanvas.getSize(); 259 260 if (size.x <= 0 || size.y <= 0) 261 return; 262 263 if (fBuffer != null) { 264 Rectangle r= fBuffer.getBounds(); 265 if (r.width != size.x || r.height != size.y) { 266 fBuffer.dispose(); 267 fBuffer= null; 268 } 269 } 270 if (fBuffer == null) 271 fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y); 272 273 GC gc= new GC(fBuffer); 274 gc.setFont(fCanvas.getFont()); 275 276 try { 277 gc.setBackground(getBackground()); 278 gc.fillRectangle(0, 0, size.x, size.y); 279 280 doPaint(gc); 281 } finally { 282 gc.dispose(); 283 } 284 285 dest.drawImage(fBuffer, 0, 0); 286 } 287 288 295 protected int getVisibleLinesInViewport() { 296 return LineNumberRulerColumn.getVisibleLinesInViewport(fCachedTextWidget); 298 } 299 300 307 protected final boolean isViewerCompletelyShown() { 308 return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget); 309 } 310 311 316 private void doPaint(GC gc) { 317 ILineRange visibleModelLines= computeVisibleModelLines(); 318 if (visibleModelLines == null) 319 return; 320 321 fSensitiveToTextChanges= isViewerCompletelyShown(); 322 323 fScrollPos= fCachedTextWidget.getTopPixel(); 324 325 fRevisionPainter.paint(gc, visibleModelLines); 326 if (!fRevisionPainter.hasInformation()) fDiffPainter.paint(gc, visibleModelLines); 328 } 329 330 333 public void redraw() { 334 335 if (fCachedTextViewer != null && fCanvas != null && !fCanvas.isDisposed()) { 336 GC gc= new GC(fCanvas); 337 doubleBufferPaint(gc); 338 gc.dispose(); 339 } 340 } 341 342 345 public void setFont(Font font) { 346 } 347 348 354 private CompositeRuler getParentRuler() { 355 return fParentRuler; 356 } 357 358 361 public int getLineOfLastMouseButtonActivity() { 362 return getParentRuler().getLineOfLastMouseButtonActivity(); 363 } 364 365 368 public int toDocumentLineNumber(int y_coordinate) { 369 return getParentRuler().toDocumentLineNumber(y_coordinate); 370 } 371 372 375 public IAnnotationHover getHover() { 376 int activeLine= getParentRuler().getLineOfLastMouseButtonActivity(); 377 if (fRevisionPainter.hasHover(activeLine)) 378 return fRevisionPainter.getHover(); 379 if (fDiffPainter.hasHover(activeLine)) 380 return fDiffPainter.getHover(); 381 return null; 382 } 383 384 387 public void setHover(IAnnotationHover hover) { 388 fRevisionPainter.setHover(hover); 389 fDiffPainter.setHover(hover); 390 } 391 392 395 public void setModel(IAnnotationModel model) { 396 setAnnotationModel(model); 397 fRevisionPainter.setModel(model); 398 fDiffPainter.setModel(model); 399 } 400 401 private void setAnnotationModel(IAnnotationModel model) { 402 if (fAnnotationModel != model) 403 fAnnotationModel= model; 404 } 405 406 409 public void setBackground(Color background) { 410 fBackground= background; 411 if (fCanvas != null && !fCanvas.isDisposed()) 412 fCanvas.setBackground(getBackground()); 413 fRevisionPainter.setBackground(background); 414 fDiffPainter.setBackground(background); 415 } 416 417 420 public void setAddedColor(Color addedColor) { 421 fDiffPainter.setAddedColor(addedColor); 422 } 423 424 427 public void setChangedColor(Color changedColor) { 428 fDiffPainter.setChangedColor(changedColor); 429 } 430 431 434 public void setDeletedColor(Color deletedColor) { 435 fDiffPainter.setDeletedColor(deletedColor); 436 } 437 438 441 public IAnnotationModel getModel() { 442 return fAnnotationModel; 443 } 444 445 448 public Control getControl() { 449 return fCanvas; 450 } 451 452 455 public int getWidth() { 456 return fWidth; 457 } 458 459 462 protected final void postRedraw() { 463 if (fCanvas != null && !fCanvas.isDisposed()) { 464 Display d= fCanvas.getDisplay(); 465 if (d != null) { 466 d.asyncExec(new Runnable () { 467 public void run() { 468 redraw(); 469 } 470 }); 471 } 472 } 473 } 474 475 478 public void addVerticalRulerListener(IVerticalRulerListener listener) { 479 throw new UnsupportedOperationException (); 480 } 481 482 485 public void removeVerticalRulerListener(IVerticalRulerListener listener) { 486 throw new UnsupportedOperationException (); 487 } 488 489 495 private final ILineRange computeVisibleModelLines() { 496 IDocument doc= fCachedTextViewer.getDocument(); 497 if (doc == null) 498 return null; 499 500 int topLine; 501 IRegion coverage; 502 503 if (fCachedTextViewer instanceof ITextViewerExtension5) { 504 ITextViewerExtension5 extension= (ITextViewerExtension5) fCachedTextViewer; 505 506 int widgetTopLine= JFaceTextUtil.getPartialTopIndex(fCachedTextWidget); 509 topLine= extension.widgetLine2ModelLine(widgetTopLine); 510 511 coverage= extension.getModelCoverage(); 512 513 } else { 514 topLine= JFaceTextUtil.getPartialTopIndex(fCachedTextViewer); 515 coverage= fCachedTextViewer.getVisibleRegion(); 516 } 517 518 int bottomLine= fCachedTextViewer.getBottomIndex(); 519 if (bottomLine != -1) 520 ++ bottomLine; 521 522 try { 524 int firstLine= doc.getLineOfOffset(coverage.getOffset()); 525 if (firstLine > topLine) 526 topLine= firstLine; 527 528 int lastLine= doc.getLineOfOffset(coverage.getOffset() + coverage.getLength()); 529 if (lastLine < bottomLine || bottomLine == -1) 530 bottomLine= lastLine; 531 } catch (BadLocationException x) { 532 x.printStackTrace(); 533 return null; 534 } 535 536 ILineRange visibleModelLines= new LineRange(topLine, bottomLine - topLine + 1); 537 return visibleModelLines; 538 } 539 540 543 public void setRevisionInformation(RevisionInformation info) { 544 fRevisionPainter.setRevisionInformation(info); 545 fRevisionPainter.setBackground(getBackground()); 546 } 547 548 554 public ISelectionProvider getRevisionSelectionProvider() { 555 return fRevisionPainter.getRevisionSelectionProvider(); 556 } 557 } 558 | Popular Tags |