1 11 package org.eclipse.debug.internal.ui.views.console; 12 13 14 import org.eclipse.debug.internal.ui.DebugUIPlugin; 15 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; 16 import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; 17 import org.eclipse.debug.ui.console.IConsoleColorProvider; 18 import org.eclipse.debug.ui.console.IConsoleHyperlink; 19 import org.eclipse.jface.resource.JFaceResources; 20 import org.eclipse.jface.text.BadLocationException; 21 import org.eclipse.jface.text.BadPositionCategoryException; 22 import org.eclipse.jface.text.DocumentEvent; 23 import org.eclipse.jface.text.IDocument; 24 import org.eclipse.jface.text.IDocumentListener; 25 import org.eclipse.jface.text.IDocumentPartitioner; 26 import org.eclipse.jface.text.IRegion; 27 import org.eclipse.jface.text.ITypedRegion; 28 import org.eclipse.jface.text.Position; 29 import org.eclipse.jface.text.TextViewer; 30 import org.eclipse.jface.util.IPropertyChangeListener; 31 import org.eclipse.jface.util.PropertyChangeEvent; 32 import org.eclipse.swt.SWT; 33 import org.eclipse.swt.custom.LineStyleEvent; 34 import org.eclipse.swt.custom.LineStyleListener; 35 import org.eclipse.swt.custom.StyleRange; 36 import org.eclipse.swt.custom.StyledText; 37 import org.eclipse.swt.events.MouseEvent; 38 import org.eclipse.swt.events.MouseListener; 39 import org.eclipse.swt.events.MouseMoveListener; 40 import org.eclipse.swt.events.MouseTrackListener; 41 import org.eclipse.swt.events.PaintEvent; 42 import org.eclipse.swt.events.PaintListener; 43 import org.eclipse.swt.events.VerifyEvent; 44 import org.eclipse.swt.graphics.Color; 45 import org.eclipse.swt.graphics.Cursor; 46 import org.eclipse.swt.graphics.FontMetrics; 47 import org.eclipse.swt.graphics.Point; 48 import org.eclipse.swt.widgets.Composite; 49 import org.eclipse.swt.widgets.Control; 50 import org.eclipse.swt.widgets.Event; 51 import org.eclipse.swt.widgets.Listener; 52 import org.eclipse.ui.console.IConsoleConstants; 53 54 public class ConsoleViewer extends TextViewer implements IPropertyChangeListener, MouseTrackListener, MouseMoveListener, MouseListener, PaintListener, LineStyleListener, Listener { 55 56 59 private Cursor fHandCursor; 60 61 64 private Cursor fTextCursor; 65 66 69 private IConsoleHyperlink fHyperLink = null; 70 71 protected InternalDocumentListener fInternalDocumentListener= new InternalDocumentListener(); 72 73 76 private boolean fAutoScroll = true; 77 78 81 class InternalDocumentListener implements IDocumentListener { 82 85 public void documentAboutToBeChanged(DocumentEvent e) { 86 } 87 88 91 public void documentChanged(DocumentEvent e) { 92 ConsoleDocument doc= (ConsoleDocument)getDocument(); 93 if (doc == null) { 94 getTextWidget().setEditable(false); 95 return; 96 } 97 getTextWidget().setEditable(!doc.isReadOnly()); 98 revealEndOfDocument(); 99 } 100 } 101 102 109 public ConsoleViewer(Composite parent) { 110 super(parent, getSWTStyles()); 111 112 getTextWidget().setDoubleClickEnabled(true); 113 114 DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); 115 JFaceResources.getFontRegistry().addListener(this); 116 117 getTextWidget().setFont(JFaceResources.getFont(IConsoleConstants.CONSOLE_FONT)); 118 getTextWidget().addMouseTrackListener(this); 119 getTextWidget().addPaintListener(this); 120 getTextWidget().addLineStyleListener(this); 121 getTextWidget().addListener(SWT.KeyUp, this); 122 getTextWidget().setTabs(DebugUIPlugin.getDefault().getPluginPreferences().getInt(IDebugPreferenceConstants.CONSOLE_TAB_WIDTH)); 123 } 124 125 128 private static int getSWTStyles() { 129 int styles= SWT.H_SCROLL | SWT.V_SCROLL; 130 return styles; 131 } 132 133 136 protected void revealEndOfDocument() { 137 if (isAutoScroll()) { 138 IDocument doc = getDocument(); 139 int lines = doc.getNumberOfLines(); 140 try { 141 int lineStartOffset = doc.getLineOffset(lines - 1); 143 StyledText widget= getTextWidget(); 144 if (lineStartOffset > 0) { 145 widget.setCaretOffset(lineStartOffset); 146 widget.showSelection(); 147 } 148 int lineEndOffset = lineStartOffset + doc.getLineLength(lines - 1); 149 if (lineEndOffset > 0) { 150 widget.setCaretOffset(lineEndOffset); 151 } 152 } catch (BadLocationException e) { 153 } 154 } 155 } 156 157 160 public void setDocument(IDocument doc) { 161 IDocument oldDoc= getDocument(); 162 IDocument document= doc; 163 if (oldDoc == null && document == null) { 164 return; 165 } 166 if (oldDoc != null) { 167 oldDoc.removeDocumentListener(fInternalDocumentListener); 168 if (oldDoc.equals(document)) { 169 document.addDocumentListener(fInternalDocumentListener); 170 return; 171 } 172 } 173 174 super.setDocument(document); 175 if (document != null) { 176 revealEndOfDocument(); 177 document.addDocumentListener(fInternalDocumentListener); 178 } 179 } 180 181 184 public void propertyChange(PropertyChangeEvent event) { 185 String propertyName= event.getProperty(); 186 if (propertyName.equals(IDebugPreferenceConstants.CONSOLE_SYS_IN_COLOR) || 187 propertyName.equals(IDebugPreferenceConstants.CONSOLE_SYS_OUT_COLOR) || 188 propertyName.equals(IDebugPreferenceConstants.CONSOLE_SYS_ERR_COLOR)) { 189 getTextWidget().redraw(); 190 } else if (propertyName.equals(IConsoleConstants.CONSOLE_FONT)) { 191 getTextWidget().setFont(JFaceResources.getFont(IConsoleConstants.CONSOLE_FONT)); 192 } else if (propertyName.equals(IDebugPreferenceConstants.CONSOLE_TAB_WIDTH)) { 193 getTextWidget().setTabs(DebugUIPlugin.getDefault().getPluginPreferences().getInt(IDebugPreferenceConstants.CONSOLE_TAB_WIDTH)); 194 } else if (propertyName.equals(IInternalDebugUIConstants.PREF_CONSOLE_SCROLL_LOCK)) { 195 setAutoScroll(!DebugUIPlugin.getDefault().getPluginPreferences().getBoolean(IInternalDebugUIConstants.PREF_CONSOLE_SCROLL_LOCK)); 196 } 197 } 198 199 202 public void dispose() { 203 Control control = getTextWidget(); 204 if (control != null) { 205 control.removeMouseTrackListener(this); 206 control.removePaintListener(this); 207 } 208 if (fHandCursor != null) { 209 fHandCursor.dispose(); 210 } 211 if (fTextCursor != null) { 212 fTextCursor.dispose(); 213 } 214 DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); 215 JFaceResources.getFontRegistry().removeListener(this); 216 } 217 218 223 protected void handleVerifyEvent(VerifyEvent e) { 224 ConsoleDocument doc= (ConsoleDocument)getDocument(); 225 if (doc != null) { 226 if (doc.isReadOnly()) { 227 e.doit = false; 228 return; 229 } 230 IDocumentPartitioner partitioner = doc.getDocumentPartitioner(); 231 if (partitioner != null) { 232 int length = doc.getLength(); 233 ITypedRegion[] partitions = partitioner.computePartitioning(length, 0); 234 if (partitions.length == 0) { 235 } else { 236 ITypedRegion partition = partitions[partitions.length - 1]; 237 if (partition.getType().equals(InputPartition.INPUT_PARTITION_TYPE)) { 238 e.doit = (e.start >= partition.getOffset()) && (e.end <= (partition.getLength() + partition.getOffset())); 240 } else { 241 e.doit = length == e.start; 243 } 244 } 245 } 246 } 247 } 248 249 252 public void mouseEnter(MouseEvent e) { 253 getTextWidget().addMouseMoveListener(this); 254 } 255 256 259 public void mouseExit(MouseEvent e) { 260 getTextWidget().removeMouseMoveListener(this); 261 if (fHyperLink != null) { 262 linkExited(fHyperLink); 263 } 264 } 265 266 269 public void mouseHover(MouseEvent e) { 270 } 271 272 275 public void mouseMove(MouseEvent e) { 276 int offset = -1; 277 try { 278 Point p = new Point(e.x, e.y); 279 offset = getTextWidget().getOffsetAtLocation(p); 280 } catch (IllegalArgumentException ex) { 281 } 283 updateLinks(offset); 284 } 285 286 public IConsoleHyperlink getHyperlink(int offset) { 287 if (offset >= 0 && getDocument() != null) { 288 Position[] positions = null; 289 try { 290 positions = getDocument().getPositions(HyperlinkPosition.HYPER_LINK_CATEGORY); 291 } catch (BadPositionCategoryException ex) { 292 return null; 294 } 295 for (int i = 0; i < positions.length; i++) { 296 Position position = positions[i]; 297 if (offset >= position.getOffset() && offset <= (position.getOffset() + position.getLength())) { 298 return ((HyperlinkPosition)position).getHyperLink(); 299 } 300 } 301 } 302 return null; 303 } 304 305 protected void linkEntered(IConsoleHyperlink link) { 306 Control control = getTextWidget(); 307 control.setRedraw(false); 308 if (fHyperLink != null) { 309 linkExited(fHyperLink); 310 } 311 fHyperLink = link; 312 fHyperLink.linkEntered(); 313 control.setCursor(getHandCursor()); 314 control.setRedraw(true); 315 control.redraw(); 316 control.addMouseListener(this); 317 } 318 319 protected void linkExited(IConsoleHyperlink link) { 320 link.linkExited(); 321 fHyperLink = null; 322 Control control = getTextWidget(); 323 control.setCursor(getTextCursor()); 324 control.redraw(); 325 control.removeMouseListener(this); 326 } 327 330 public void paintControl(PaintEvent e) { 331 if (fHyperLink != null) { 332 IDocument doc = getDocument(); 333 if (doc == null) { 334 return; 335 } 336 ConsoleDocumentPartitioner partitioner = (ConsoleDocumentPartitioner)doc.getDocumentPartitioner(); 337 if (partitioner == null) { 338 return; 339 } 340 IRegion linkRegion = partitioner.getRegion(fHyperLink); 341 if (linkRegion != null) { 342 int start = linkRegion.getOffset(); 343 int end = start + linkRegion.getLength(); 344 IConsoleColorProvider colorProvider = partitioner.getColorProvider(); 345 try { 346 ITypedRegion partition = doc.getPartition(start); 347 Color fontColor = e.gc.getForeground(); 348 if (partition instanceof StreamPartition) { 349 StreamPartition streamPartition = (StreamPartition)partition; 350 fontColor = colorProvider.getColor(streamPartition.getStreamIdentifier()); 351 } 352 int startLine = doc.getLineOfOffset(start); 353 int endLine = doc.getLineOfOffset(end); 354 for (int i = startLine; i <= endLine; i++) { 355 IRegion lineRegion = doc.getLineInformation(i); 356 int lineStart = lineRegion.getOffset(); 357 int lineEnd = lineStart + lineRegion.getLength(); 358 Color color = e.gc.getForeground(); 359 e.gc.setForeground(fontColor); 360 if (lineStart < end) { 361 lineStart = Math.max(start, lineStart); 362 lineEnd = Math.min(end, lineEnd); 363 Point p1 = getTextWidget().getLocationAtOffset(lineStart); 364 Point p2 = getTextWidget().getLocationAtOffset(lineEnd); 365 FontMetrics metrics = e.gc.getFontMetrics(); 366 int height = metrics.getHeight(); 367 e.gc.drawLine(p1.x, p1.y + height, p2.x, p2.y + height); 368 } 369 e.gc.setForeground(color); 370 } 371 } catch (BadLocationException ex) { 372 } 373 } 374 } 375 } 376 377 protected Cursor getHandCursor() { 378 if (fHandCursor == null) { 379 fHandCursor = new Cursor(DebugUIPlugin.getStandardDisplay(), SWT.CURSOR_HAND); 380 } 381 return fHandCursor; 382 } 383 384 protected Cursor getTextCursor() { 385 if (fTextCursor == null) { 386 fTextCursor = new Cursor(DebugUIPlugin.getStandardDisplay(), SWT.CURSOR_IBEAM); 387 } 388 return fTextCursor; 389 } 390 391 394 public void mouseDoubleClick(MouseEvent e) { 395 } 396 397 400 public void mouseDown(MouseEvent e) { 401 } 402 403 406 public void mouseUp(MouseEvent e) { 407 if (fHyperLink != null) { 408 String selection = getTextWidget().getSelectionText(); 409 if (selection.length() <= 0) { 410 if (e.button == 1) { 411 fHyperLink.linkActivated(); 412 } 413 } 414 } 415 } 416 417 420 public void lineGetStyle(LineStyleEvent event) { 421 IDocument document = getDocument(); 422 if (document != null) { 423 ConsoleDocumentPartitioner partitioner = (ConsoleDocumentPartitioner)document.getDocumentPartitioner(); 424 if (partitioner != null) { 425 IConsoleColorProvider colorProvider = partitioner.getColorProvider(); 426 ITypedRegion[] regions = partitioner.computePartitioning(event.lineOffset, event.lineOffset + event.lineText.length()); 427 StyleRange[] styles = new StyleRange[regions.length]; 428 for (int i = 0; i < regions.length; i++) { 429 StreamPartition partition = (StreamPartition)regions[i]; 430 Color color = colorProvider.getColor(partition.getStreamIdentifier()); 431 styles[i] = new StyleRange(partition.getOffset(), partition.getLength(), color, null); 432 } 433 event.styles = styles; 434 } 435 } 436 } 437 438 444 public void setAutoScroll(boolean scroll) { 445 fAutoScroll = scroll; 446 } 447 448 452 public boolean isAutoScroll() { 453 return fAutoScroll; 454 } 455 456 461 public void handleEvent(Event event) { 462 int offset = getTextWidget().getCaretOffset(); 463 updateLinks(offset); 464 } 465 466 472 protected void updateLinks(int offset) { 473 if (offset >= 0) { 474 IConsoleHyperlink link = getHyperlink(offset); 475 if (link != null) { 476 if (link.equals(fHyperLink)) { 477 return; 478 } else { 479 linkEntered(link); 480 return; 481 } 482 } 483 } 484 if (fHyperLink != null) { 485 linkExited(fHyperLink); 486 } 487 } 488 489 } 490 491 | Popular Tags |