1 11 12 package org.eclipse.jdt.internal.ui.javaeditor; 13 14 import java.util.ArrayList ; 15 import java.util.List ; 16 17 import org.eclipse.swt.SWT; 18 import org.eclipse.swt.custom.StyleRange; 19 import org.eclipse.swt.graphics.Color; 20 import org.eclipse.swt.graphics.RGB; 21 22 import org.eclipse.jface.preference.IPreferenceStore; 23 import org.eclipse.jface.preference.PreferenceConverter; 24 import org.eclipse.jface.resource.StringConverter; 25 import org.eclipse.jface.util.IPropertyChangeListener; 26 import org.eclipse.jface.util.PropertyChangeEvent; 27 28 import org.eclipse.jface.text.Position; 29 import org.eclipse.jface.text.Region; 30 import org.eclipse.jface.text.TextAttribute; 31 32 import org.eclipse.jdt.ui.text.IColorManager; 33 import org.eclipse.jdt.ui.text.IColorManagerExtension; 34 import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration; 35 36 import org.eclipse.jdt.internal.ui.text.JavaPresentationReconciler; 37 38 43 public class SemanticHighlightingManager implements IPropertyChangeListener { 44 45 48 static class Highlighting { 50 51 private TextAttribute fTextAttribute; 52 53 private boolean fIsEnabled; 54 55 60 public Highlighting(TextAttribute textAttribute, boolean isEnabled) { 61 setTextAttribute(textAttribute); 62 setEnabled(isEnabled); 63 } 64 65 68 public TextAttribute getTextAttribute() { 69 return fTextAttribute; 70 } 71 72 75 public void setTextAttribute(TextAttribute textAttribute) { 76 fTextAttribute= textAttribute; 77 } 78 79 82 public boolean isEnabled() { 83 return fIsEnabled; 84 } 85 86 89 public void setEnabled(boolean isEnabled) { 90 fIsEnabled= isEnabled; 91 } 92 } 93 94 97 static class HighlightedPosition extends Position { 98 99 100 private Highlighting fStyle; 101 102 103 private Object fLock; 104 105 113 public HighlightedPosition(int offset, int length, Highlighting highlighting, Object lock) { 114 super(offset, length); 115 fStyle= highlighting; 116 fLock= lock; 117 } 118 119 122 public StyleRange createStyleRange() { 123 int len= 0; 124 if (fStyle.isEnabled()) 125 len= getLength(); 126 127 TextAttribute textAttribute= fStyle.getTextAttribute(); 128 int style= textAttribute.getStyle(); 129 int fontStyle= style & (SWT.ITALIC | SWT.BOLD | SWT.NORMAL); 130 StyleRange styleRange= new StyleRange(getOffset(), len, textAttribute.getForeground(), textAttribute.getBackground(), fontStyle); 131 styleRange.strikeout= (style & TextAttribute.STRIKETHROUGH) != 0; 132 styleRange.underline= (style & TextAttribute.UNDERLINE) != 0; 133 134 return styleRange; 135 } 136 137 145 public boolean isEqual(int off, int len, Highlighting highlighting) { 146 synchronized (fLock) { 147 return !isDeleted() && getOffset() == off && getLength() == len && fStyle == highlighting; 148 } 149 } 150 151 158 public boolean isContained(int off, int len) { 159 synchronized (fLock) { 160 return !isDeleted() && off <= getOffset() && off + len >= getOffset() + getLength(); 161 } 162 } 163 164 public void update(int off, int len) { 165 synchronized (fLock) { 166 super.setOffset(off); 167 super.setLength(len); 168 } 169 } 170 171 174 public void setLength(int length) { 175 synchronized (fLock) { 176 super.setLength(length); 177 } 178 } 179 180 183 public void setOffset(int offset) { 184 synchronized (fLock) { 185 super.setOffset(offset); 186 } 187 } 188 189 192 public void delete() { 193 synchronized (fLock) { 194 super.delete(); 195 } 196 } 197 198 201 public void undelete() { 202 synchronized (fLock) { 203 super.undelete(); 204 } 205 } 206 207 210 public Highlighting getHighlighting() { 211 return fStyle; 212 } 213 } 214 215 218 public static class HighlightedRange extends Region { 219 220 private String fKey; 221 222 229 public HighlightedRange(int offset, int length, String key) { 230 super(offset, length); 231 fKey= key; 232 } 233 234 237 public String getKey() { 238 return fKey; 239 } 240 241 244 public boolean equals(Object o) { 245 return super.equals(o) && o instanceof HighlightedRange && fKey.equals(((HighlightedRange)o).getKey()); 246 } 247 248 251 public int hashCode() { 252 return super.hashCode() | fKey.hashCode(); 253 } 254 } 255 256 257 private SemanticHighlightingPresenter fPresenter; 258 259 private SemanticHighlightingReconciler fReconciler; 260 261 262 private SemanticHighlighting[] fSemanticHighlightings; 263 264 private Highlighting[] fHighlightings; 265 266 267 private JavaEditor fEditor; 268 269 private JavaSourceViewer fSourceViewer; 270 271 private IColorManager fColorManager; 272 273 private IPreferenceStore fPreferenceStore; 274 275 private JavaSourceViewerConfiguration fConfiguration; 276 277 private JavaPresentationReconciler fPresentationReconciler; 278 279 280 private HighlightedRange[][] fHardcodedRanges; 281 282 290 public void install(JavaEditor editor, JavaSourceViewer sourceViewer, IColorManager colorManager, IPreferenceStore preferenceStore) { 291 fEditor= editor; 292 fSourceViewer= sourceViewer; 293 fColorManager= colorManager; 294 fPreferenceStore= preferenceStore; 295 if (fEditor != null) { 296 fConfiguration= editor.createJavaSourceViewerConfiguration(); 297 fPresentationReconciler= (JavaPresentationReconciler) fConfiguration.getPresentationReconciler(sourceViewer); 298 } else { 299 fConfiguration= null; 300 fPresentationReconciler= null; 301 } 302 303 fPreferenceStore.addPropertyChangeListener(this); 304 305 if (isEnabled()) 306 enable(); 307 } 308 309 317 public void install(JavaSourceViewer sourceViewer, IColorManager colorManager, IPreferenceStore preferenceStore, HighlightedRange[][] hardcodedRanges) { 318 fHardcodedRanges= hardcodedRanges; 319 install(null, sourceViewer, colorManager, preferenceStore); 320 } 321 322 325 private void enable() { 326 initializeHighlightings(); 327 328 fPresenter= new SemanticHighlightingPresenter(); 329 fPresenter.install(fSourceViewer, fPresentationReconciler); 330 331 if (fEditor != null) { 332 fReconciler= new SemanticHighlightingReconciler(); 333 fReconciler.install(fEditor, fSourceViewer, fPresenter, fSemanticHighlightings, fHighlightings); 334 } else { 335 fPresenter.updatePresentation(null, createHardcodedPositions(), new HighlightedPosition[0]); 336 } 337 } 338 339 344 private HighlightedPosition[] createHardcodedPositions() { 345 List positions= new ArrayList (); 346 for (int i= 0; i < fHardcodedRanges.length; i++) { 347 HighlightedRange range= null; 348 Highlighting hl= null; 349 for (int j= 0; j < fHardcodedRanges[i].length; j++ ) { 350 hl= getHighlighting(fHardcodedRanges[i][j].getKey()); 351 if (hl.isEnabled()) { 352 range= fHardcodedRanges[i][j]; 353 break; 354 } 355 } 356 357 if (range != null) 358 positions.add(fPresenter.createHighlightedPosition(range.getOffset(), range.getLength(), hl)); 359 } 360 return (HighlightedPosition[]) positions.toArray(new HighlightedPosition[positions.size()]); 361 } 362 363 369 private Highlighting getHighlighting(String key) { 370 for (int i= 0; i < fSemanticHighlightings.length; i++) { 371 SemanticHighlighting semanticHighlighting= fSemanticHighlightings[i]; 372 if (key.equals(semanticHighlighting.getPreferenceKey())) 373 return fHighlightings[i]; 374 } 375 return null; 376 } 377 378 381 public void uninstall() { 382 disable(); 383 384 if (fPreferenceStore != null) { 385 fPreferenceStore.removePropertyChangeListener(this); 386 fPreferenceStore= null; 387 } 388 389 fEditor= null; 390 fSourceViewer= null; 391 fColorManager= null; 392 fConfiguration= null; 393 fPresentationReconciler= null; 394 fHardcodedRanges= null; 395 } 396 397 400 private void disable() { 401 if (fReconciler != null) { 402 fReconciler.uninstall(); 403 fReconciler= null; 404 } 405 406 if (fPresenter != null) { 407 fPresenter.uninstall(); 408 fPresenter= null; 409 } 410 411 if (fSemanticHighlightings != null) 412 disposeHighlightings(); 413 } 414 415 418 private boolean isEnabled() { 419 return SemanticHighlightings.isEnabled(fPreferenceStore); 420 } 421 422 425 private void initializeHighlightings() { 426 fSemanticHighlightings= SemanticHighlightings.getSemanticHighlightings(); 427 fHighlightings= new Highlighting[fSemanticHighlightings.length]; 428 429 for (int i= 0, n= fSemanticHighlightings.length; i < n; i++) { 430 SemanticHighlighting semanticHighlighting= fSemanticHighlightings[i]; 431 String colorKey= SemanticHighlightings.getColorPreferenceKey(semanticHighlighting); 432 addColor(colorKey); 433 434 String boldKey= SemanticHighlightings.getBoldPreferenceKey(semanticHighlighting); 435 int style= fPreferenceStore.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL; 436 437 String italicKey= SemanticHighlightings.getItalicPreferenceKey(semanticHighlighting); 438 if (fPreferenceStore.getBoolean(italicKey)) 439 style |= SWT.ITALIC; 440 441 String strikethroughKey= SemanticHighlightings.getStrikethroughPreferenceKey(semanticHighlighting); 442 if (fPreferenceStore.getBoolean(strikethroughKey)) 443 style |= TextAttribute.STRIKETHROUGH; 444 445 String underlineKey= SemanticHighlightings.getUnderlinePreferenceKey(semanticHighlighting); 446 if (fPreferenceStore.getBoolean(underlineKey)) 447 style |= TextAttribute.UNDERLINE; 448 449 boolean isEnabled= fPreferenceStore.getBoolean(SemanticHighlightings.getEnabledPreferenceKey(semanticHighlighting)); 450 451 fHighlightings[i]= new Highlighting(new TextAttribute(fColorManager.getColor(PreferenceConverter.getColor(fPreferenceStore, colorKey)), null, style), isEnabled); 452 } 453 } 454 455 458 private void disposeHighlightings() { 459 for (int i= 0, n= fSemanticHighlightings.length; i < n; i++) 460 removeColor(SemanticHighlightings.getColorPreferenceKey(fSemanticHighlightings[i])); 461 462 fSemanticHighlightings= null; 463 fHighlightings= null; 464 } 465 466 469 public void propertyChange(PropertyChangeEvent event) { 470 handlePropertyChangeEvent(event); 471 } 472 473 478 private void handlePropertyChangeEvent(PropertyChangeEvent event) { 479 if (fPreferenceStore == null) 480 return; 482 if (fConfiguration != null) 483 fConfiguration.handlePropertyChangeEvent(event); 484 485 if (SemanticHighlightings.affectsEnablement(fPreferenceStore, event)) { 486 if (isEnabled()) 487 enable(); 488 else 489 disable(); 490 } 491 492 if (!isEnabled()) 493 return; 494 495 boolean refreshNeeded= false; 496 497 for (int i= 0, n= fSemanticHighlightings.length; i < n; i++) { 498 SemanticHighlighting semanticHighlighting= fSemanticHighlightings[i]; 499 500 String colorKey= SemanticHighlightings.getColorPreferenceKey(semanticHighlighting); 501 if (colorKey.equals(event.getProperty())) { 502 adaptToTextForegroundChange(fHighlightings[i], event); 503 fPresenter.highlightingStyleChanged(fHighlightings[i]); 504 refreshNeeded= true; 505 continue; 506 } 507 508 String boldKey= SemanticHighlightings.getBoldPreferenceKey(semanticHighlighting); 509 if (boldKey.equals(event.getProperty())) { 510 adaptToTextStyleChange(fHighlightings[i], event, SWT.BOLD); 511 fPresenter.highlightingStyleChanged(fHighlightings[i]); 512 refreshNeeded= true; 513 continue; 514 } 515 516 String italicKey= SemanticHighlightings.getItalicPreferenceKey(semanticHighlighting); 517 if (italicKey.equals(event.getProperty())) { 518 adaptToTextStyleChange(fHighlightings[i], event, SWT.ITALIC); 519 fPresenter.highlightingStyleChanged(fHighlightings[i]); 520 refreshNeeded= true; 521 continue; 522 } 523 524 String strikethroughKey= SemanticHighlightings.getStrikethroughPreferenceKey(semanticHighlighting); 525 if (strikethroughKey.equals(event.getProperty())) { 526 adaptToTextStyleChange(fHighlightings[i], event, TextAttribute.STRIKETHROUGH); 527 fPresenter.highlightingStyleChanged(fHighlightings[i]); 528 refreshNeeded= true; 529 continue; 530 } 531 532 String underlineKey= SemanticHighlightings.getUnderlinePreferenceKey(semanticHighlighting); 533 if (underlineKey.equals(event.getProperty())) { 534 adaptToTextStyleChange(fHighlightings[i], event, TextAttribute.UNDERLINE); 535 fPresenter.highlightingStyleChanged(fHighlightings[i]); 536 refreshNeeded= true; 537 continue; 538 } 539 540 String enabledKey= SemanticHighlightings.getEnabledPreferenceKey(semanticHighlighting); 541 if (enabledKey.equals(event.getProperty())) { 542 adaptToEnablementChange(fHighlightings[i], event); 543 fPresenter.highlightingStyleChanged(fHighlightings[i]); 544 refreshNeeded= true; 545 continue; 546 } 547 } 548 549 if (refreshNeeded && fReconciler != null) 550 fReconciler.refresh(); 551 } 552 553 private void adaptToEnablementChange(Highlighting highlighting, PropertyChangeEvent event) { 554 Object value= event.getNewValue(); 555 boolean eventValue; 556 if (value instanceof Boolean ) 557 eventValue= ((Boolean ) value).booleanValue(); 558 else if (IPreferenceStore.TRUE.equals(value)) 559 eventValue= true; 560 else 561 eventValue= false; 562 highlighting.setEnabled(eventValue); 563 } 564 565 private void adaptToTextForegroundChange(Highlighting highlighting, PropertyChangeEvent event) { 566 RGB rgb= null; 567 568 Object value= event.getNewValue(); 569 if (value instanceof RGB) 570 rgb= (RGB) value; 571 else if (value instanceof String ) 572 rgb= StringConverter.asRGB((String ) value); 573 574 if (rgb != null) { 575 576 String property= event.getProperty(); 577 Color color= fColorManager.getColor(property); 578 579 if ((color == null || !rgb.equals(color.getRGB())) && fColorManager instanceof IColorManagerExtension) { 580 IColorManagerExtension ext= (IColorManagerExtension) fColorManager; 581 ext.unbindColor(property); 582 ext.bindColor(property, rgb); 583 color= fColorManager.getColor(property); 584 } 585 586 TextAttribute oldAttr= highlighting.getTextAttribute(); 587 highlighting.setTextAttribute(new TextAttribute(color, oldAttr.getBackground(), oldAttr.getStyle())); 588 } 589 } 590 591 private void adaptToTextStyleChange(Highlighting highlighting, PropertyChangeEvent event, int styleAttribute) { 592 boolean eventValue= false; 593 Object value= event.getNewValue(); 594 if (value instanceof Boolean ) 595 eventValue= ((Boolean ) value).booleanValue(); 596 else if (IPreferenceStore.TRUE.equals(value)) 597 eventValue= true; 598 599 TextAttribute oldAttr= highlighting.getTextAttribute(); 600 boolean activeValue= (oldAttr.getStyle() & styleAttribute) == styleAttribute; 601 602 if (activeValue != eventValue) 603 highlighting.setTextAttribute(new TextAttribute(oldAttr.getForeground(), oldAttr.getBackground(), eventValue ? oldAttr.getStyle() | styleAttribute : oldAttr.getStyle() & ~styleAttribute)); 604 } 605 606 private void addColor(String colorKey) { 607 if (fColorManager != null && colorKey != null && fColorManager.getColor(colorKey) == null) { 608 RGB rgb= PreferenceConverter.getColor(fPreferenceStore, colorKey); 609 if (fColorManager instanceof IColorManagerExtension) { 610 IColorManagerExtension ext= (IColorManagerExtension) fColorManager; 611 ext.unbindColor(colorKey); 612 ext.bindColor(colorKey, rgb); 613 } 614 } 615 } 616 617 private void removeColor(String colorKey) { 618 if (fColorManager instanceof IColorManagerExtension) 619 ((IColorManagerExtension) fColorManager).unbindColor(colorKey); 620 } 621 622 628 public SemanticHighlightingReconciler getReconciler() { 629 return fReconciler; 630 } 631 } 632 | Popular Tags |