Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/style/SemanticHighlightingManager.java')
-rw-r--r--core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/style/SemanticHighlightingManager.java786
1 files changed, 786 insertions, 0 deletions
diff --git a/core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/style/SemanticHighlightingManager.java b/core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/style/SemanticHighlightingManager.java
new file mode 100644
index 0000000000..6131843e5e
--- /dev/null
+++ b/core/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/style/SemanticHighlightingManager.java
@@ -0,0 +1,786 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2014 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.sse.ui.internal.style;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.wst.sse.core.utils.StringUtils;
+import org.eclipse.wst.sse.ui.ISemanticHighlighting;
+import org.eclipse.wst.sse.ui.ISemanticHighlightingExtension2;
+import org.eclipse.wst.sse.ui.internal.Logger;
+import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
+import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames;
+import org.eclipse.wst.sse.ui.internal.preferences.ui.ColorHelper;
+import org.eclipse.wst.sse.ui.internal.provisional.style.StructuredPresentationReconciler;
+import org.eclipse.wst.sse.ui.internal.reconcile.DocumentRegionProcessor;
+import org.eclipse.wst.sse.ui.internal.util.EditorUtility;
+
+/**
+ * Semantic highlighting manager. Responsible for maintaining the semantic highlightings
+ * and the associated styles. Semantic highlighting preference changes are handled
+ * through listeners in this class. Based on org.eclipse.jdt.internal.ui.javaeditor.SemanticHighlightingManager
+ *
+ * @since 3.1
+ */
+public class SemanticHighlightingManager implements IPropertyChangeListener {
+
+ /**
+ * HighlightingStyle.
+ */
+ static class HighlightingStyle {
+
+ /** Text attribute */
+ private TextAttribute fTextAttribute;
+ /** Enabled state */
+ private boolean fIsEnabled;
+
+ /**
+ * Initialize with the given text attribute.
+ * @param textAttribute The text attribute
+ * @param isEnabled the enabled state
+ */
+ public HighlightingStyle(TextAttribute textAttribute, boolean isEnabled) {
+ setTextAttribute(textAttribute);
+ setEnabled(isEnabled);
+ }
+
+ /**
+ * @return Returns the text attribute.
+ */
+ public TextAttribute getTextAttribute() {
+ return fTextAttribute;
+ }
+
+ /**
+ * @param textAttribute The background to set.
+ */
+ public void setTextAttribute(TextAttribute textAttribute) {
+ fTextAttribute = textAttribute;
+ }
+
+ /**
+ * @return the enabled state
+ */
+ public boolean isEnabled() {
+ return fIsEnabled;
+ }
+
+ /**
+ * @param isEnabled the new enabled state
+ */
+ public void setEnabled(boolean isEnabled) {
+ fIsEnabled = isEnabled;
+ }
+ }
+
+ /**
+ * Highlighted Positions.
+ */
+ static class HighlightedPosition extends Position {
+
+ /** Highlighting of the position */
+ private HighlightingStyle fStyle;
+
+ private boolean fReadOnly;
+
+ /** Lock object */
+ private Object fLock;
+
+ /**
+ * Initialize the styled positions with the given offset, length and foreground color.
+ *
+ * @param offset The position offset
+ * @param length The position length
+ * @param highlighting The position's highlighting
+ * @param lock The lock object
+ */
+ public HighlightedPosition(int offset, int length, HighlightingStyle highlighting, Object lock, boolean isReadOnly) {
+ super(offset, length);
+ fStyle = highlighting;
+ fLock = lock;
+ fReadOnly = isReadOnly;
+ }
+
+ public HighlightedPosition(int offset, int length, HighlightingStyle highlighting, Object lock) {
+ this(offset, length, highlighting, lock, false);
+ }
+
+ public HighlightedPosition(Position position, HighlightingStyle highlighting, Object lock) {
+ this(position.offset, position.length, highlighting, lock, false);
+ }
+
+ public HighlightedPosition(Position position, HighlightingStyle highlighting, Object lock, boolean isReadOnly) {
+ this(position.offset, position.length, highlighting, lock, isReadOnly);
+ }
+
+ /**
+ * @return Returns a corresponding style range.
+ */
+ public StyleRange createStyleRange() {
+ int len= 0;
+ if (fStyle.isEnabled())
+ len= getLength();
+
+ TextAttribute textAttribute = fStyle.getTextAttribute();
+ int style = textAttribute.getStyle();
+ int fontStyle = style & (SWT.ITALIC | SWT.BOLD | SWT.NORMAL);
+ StyleRange styleRange = new StyleRange(getOffset(), len, textAttribute.getForeground(), textAttribute.getBackground(), fontStyle);
+ styleRange.strikeout = (style & TextAttribute.STRIKETHROUGH) != 0;
+ styleRange.underline = (style & TextAttribute.UNDERLINE) != 0;
+
+ return styleRange;
+ }
+
+ /**
+ * Uses reference equality for the highlighting.
+ *
+ * @param off The offset
+ * @param len The length
+ * @param highlighting The highlighting
+ * @return <code>true</code> iff the given offset, length and highlighting are equal to the internal ones.
+ */
+ public boolean isEqual(int off, int len, HighlightingStyle highlighting) {
+ synchronized (fLock) {
+ return !isDeleted() && getOffset() == off && getLength() == len && fStyle == highlighting;
+ }
+ }
+
+ /**
+ * Uses reference equality for the highlighting.
+ *
+ * @param pos The position
+ * @param highlighting The highlighting
+ * @return <code>true</code> iff the given offset, length and highlighting are equal to the internal ones.
+ */
+ public boolean isEqual(Position pos, HighlightingStyle highlighting) {
+ synchronized (fLock) {
+ return !isDeleted() && getOffset() == pos.getOffset() && getLength() == pos.getLength() && fStyle == highlighting;
+ }
+ }
+
+ /**
+ * Is this position contained in the given range (inclusive)? Synchronizes on position updater.
+ *
+ * @param off The range offset
+ * @param len The range length
+ * @return <code>true</code> iff this position is not delete and contained in the given range.
+ */
+ public boolean isContained(int off, int len) {
+ synchronized (fLock) {
+ return !isDeleted() && off <= getOffset() && off + len >= getOffset() + getLength();
+ }
+ }
+
+ public void update(int off, int len) {
+ synchronized (fLock) {
+ super.setOffset(off);
+ super.setLength(len);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.Position#setLength(int)
+ */
+ public void setLength(int length) {
+ synchronized (fLock) {
+ super.setLength(length);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.Position#setOffset(int)
+ */
+ public void setOffset(int offset) {
+ synchronized (fLock) {
+ super.setOffset(offset);
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.Position#delete()
+ */
+ public void delete() {
+ synchronized (fLock) {
+ super.delete();
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.Position#undelete()
+ */
+ public void undelete() {
+ synchronized (fLock) {
+ super.undelete();
+ }
+ }
+
+ /**
+ * @return Returns the highlighting.
+ */
+ public HighlightingStyle getHighlighting() {
+ return fStyle;
+ }
+
+ public boolean isReadOnly() {
+ return fReadOnly;
+ }
+ }
+
+ /**
+ * Highlighted ranges.
+ */
+ public static class HighlightedRange extends Region {
+ /** The highlighting key as returned by {@link ISemanticHighlighting#getPreferenceKey()}. */
+ private String fKey;
+
+ /**
+ * Initialize with the given offset, length and highlighting key.
+ *
+ * @param offset
+ * @param length
+ * @param key the highlighting key as returned by {@link ISemanticHighlighting#getPreferenceKey()}
+ */
+ public HighlightedRange(int offset, int length, String key) {
+ super(offset, length);
+ fKey = key;
+ }
+
+ /**
+ * @return the highlighting key as returned by {@link ISemanticHighlighting#getPreferenceKey()}
+ */
+ public String getKey() {
+ return fKey;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.Region#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+ return super.equals(o) && o instanceof HighlightedRange && fKey.equals(((HighlightedRange)o).getKey());
+ }
+
+ /*
+ * @see org.eclipse.jface.text.Region#hashCode()
+ */
+ public int hashCode() {
+ return super.hashCode() | fKey.hashCode();
+ }
+ }
+
+ private static final String SEMANTIC_HIGHLIGHTING_EXTENSION_POINT = "semanticHighlighting"; //$NON-NLS-1$
+ private static final String TARGET_ATTR = "target"; //$NON-NLS-1$
+ private static final String CLASS_ATTR = "class"; //$NON-NLS-1$
+ private static final String STYLE_KEY_ATTR = "styleStringKey"; //$NON-NLS-1$
+ private static final String ID_ATTR = "id"; //$NON-NLS-1$
+ private static final String AFTER_ATTR = "after"; //$NON-NLS-1$
+
+ private ISourceViewer fSourceViewer;
+ private IPreferenceStore fPreferenceStore;
+ private SourceViewerConfiguration fConfiguration;
+ private StructuredPresentationReconciler fPresentationReconciler;
+ private String fContentTypeId;
+
+ private SemanticHighlightingPresenter fPresenter;
+ private SemanticHighlightingReconciler fReconciler;
+
+ /** The semantic highlightings for the content type */
+ private ISemanticHighlighting[] fHighlightings;
+ /** The semantic highlighting styles associated with the semantic highlightings */
+ private HighlightingStyle[] fHighlightingStyles;
+ /** The semantic highlighting style string preference keys. null of the highlighting doesn't support it */
+ private String[] fHighlightingStyleStringKeys;
+
+ private IPropertyChangeListener fHighlightingChangeListener = new IPropertyChangeListener() {
+
+ public void propertyChange(PropertyChangeEvent event) {
+ handleHighlightingPropertyChange(event);
+ }
+ };
+
+ public void propertyChange(PropertyChangeEvent event) {
+ handlePropertyChange(event);
+ }
+
+ public void install(ISourceViewer sourceViewer, IPreferenceStore preferenceStore, SourceViewerConfiguration configuration, String contentTypeId) {
+ fSourceViewer = sourceViewer;
+ fPreferenceStore = preferenceStore;
+ fConfiguration = configuration;
+ fContentTypeId = contentTypeId;
+
+ fPreferenceStore.addPropertyChangeListener(this);
+ fPresentationReconciler = (StructuredPresentationReconciler) fConfiguration.getPresentationReconciler(fSourceViewer);
+
+ if (isEnabled()) {
+ enable();
+ }
+ }
+
+ /**
+ * Load the semantic highlightings defined for this content type.
+ */
+ private void loadSemanticHighlightings() {
+ List semantics = new ArrayList(0);
+
+ ISemanticHighlighting highlighting = null;
+ String styleKey = null;
+ String id = null;
+ String after = null;
+ IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(SSEUIPlugin.ID, SEMANTIC_HIGHLIGHTING_EXTENSION_POINT);
+
+ IContentType contentType = Platform.getContentTypeManager().getContentType(fContentTypeId);
+
+ for (int i = 0; i < elements.length; i++) {
+ String[] targets = StringUtils.unpack(elements[i].getAttribute(TARGET_ATTR));
+ for (int j = 0; j < targets.length; j++) {
+ IContentType targetContentType = Platform.getContentTypeManager().getContentType(targets[j]);
+ /* Apply semantic highlighting to kinds of targetContentType */
+ if (contentType.isKindOf(targetContentType)) {
+ try {
+ highlighting = (ISemanticHighlighting) elements[i].createExecutableExtension(CLASS_ATTR);
+ styleKey = elements[i].getAttribute(STYLE_KEY_ATTR);
+ id = elements[i].getAttribute(ID_ATTR);
+ after = elements[i].getAttribute(AFTER_ATTR);
+ } catch (CoreException e) {
+ Logger.logException(e);
+ }
+ if (highlighting != null) {
+ // The highlighting was not inserted through priority; insert at the beginning of the list
+ semantics.add(new SemanticContent(targetContentType, highlighting, styleKey, id, after));
+ }
+
+ break;
+ }
+ }
+ }
+ /* Sort the semantics, so that styles will be applied from general to specific */
+ Collections.sort(semantics);
+ fHighlightings = new ISemanticHighlighting[semantics.size()];
+ fHighlightingStyles = new HighlightingStyle[semantics.size()];
+ fHighlightingStyleStringKeys = new String[semantics.size()];
+
+ for (int i = 0; i < semantics.size(); i++) {
+ fHighlightings[i] = ((SemanticContent) semantics.get(i)).getHighlighting();
+ styleKey = ((SemanticContent) semantics.get(i)).getStyleKey();
+ fHighlightingStyles[i] = createHighlightingStyle(((SemanticContent) semantics.get(i)).getHighlighting(), styleKey);
+ fHighlightingStyleStringKeys[i] = styleKey;
+ }
+ }
+
+ /**
+ * This class is used for relating a semantic highlighting to a content type.
+ * The content type is used in the sorting algorithm. Content types that are more specific
+ * to the file's content type will cause styles to be applied from general to specific
+ */
+ private class SemanticContent implements Comparable {
+ public IContentType type;
+ public ISemanticHighlighting highlighting;
+ public String styleKey;
+ public String id;
+ public String after;
+ public SemanticContent(IContentType type, ISemanticHighlighting highlighting, String styleKey, String id, String after) {
+ this.type = type;
+ this.highlighting = highlighting;
+ this.styleKey = styleKey;
+ this.id = id;
+ this.after = after;
+ }
+
+ public int compareTo(Object arg0) {
+ SemanticContent other = (SemanticContent) arg0;
+ /* Equal weighting for the same types */
+ if (this.type.equals(other.type)) {
+ if (this.after != null && other.id != null && other.id.equals(this.after)) {
+ return 1;
+ }
+ return 0;
+ }
+ /* Subtypes have more weight than base types */
+ if (this.type.isKindOf(other.type))
+ return 1;
+ return -1;
+ }
+
+ public ISemanticHighlighting getHighlighting() {
+ return highlighting;
+ }
+
+ public String getStyleKey() {
+ return styleKey;
+ }
+ }
+
+ /**
+ * Creates a highlighting style based on the preferences defined in the semantic highlighting
+ * @param highlighting the semantic highlighting
+ * @return a highlighting style based on the preferences of the semantic highlighting
+ */
+ private HighlightingStyle createHighlightingStyle(ISemanticHighlighting highlighting, String styleKey) {
+ IPreferenceStore store = highlighting.getPreferenceStore();
+ HighlightingStyle highlightingStyle = null;
+ if (store != null) {
+ TextAttribute attribute = null;
+ // A style string is used instead of separate attribute keys
+ if (styleKey != null) {
+ attribute = createTextAttribute(store.getString(styleKey));
+ }
+ else {
+ int style = getBoolean(store, highlighting.getBoldPreferenceKey()) ? SWT.BOLD : SWT.NORMAL;
+
+ if (getBoolean(store, highlighting.getItalicPreferenceKey()))
+ style |= SWT.ITALIC;
+ if (getBoolean(store, highlighting.getStrikethroughPreferenceKey()))
+ style |= TextAttribute.STRIKETHROUGH;
+ if (getBoolean(store, highlighting.getUnderlinePreferenceKey()))
+ style |= TextAttribute.UNDERLINE;
+
+ String rgbString = getString(store, highlighting.getColorPreferenceKey());
+ Color color = null;
+ Color bgColor = null;
+
+ if (rgbString != null)
+ color = EditorUtility.getColor(ColorHelper.toRGB(rgbString));
+ if (highlighting instanceof ISemanticHighlightingExtension2) {
+ rgbString = getString(store, ((ISemanticHighlightingExtension2) highlighting).getBackgroundColorPreferenceKey());
+ if (rgbString != null) {
+ bgColor = EditorUtility.getColor(ColorHelper.toRGB(rgbString));
+ }
+ }
+ attribute = new TextAttribute(color, bgColor, style);
+ }
+
+ store.addPropertyChangeListener(fHighlightingChangeListener);
+ boolean isEnabled = getBoolean(store, highlighting.getEnabledPreferenceKey());
+ highlightingStyle = new HighlightingStyle(attribute, isEnabled);
+ }
+ return highlightingStyle;
+ }
+
+ /**
+ * Creates a text attribute from the style string
+ *
+ * @param styleValue style string in the form: <code>RGB foreground (#rrggbb) | RGB background (#rrggbb) | bold (true/false) | italic (true/false) | strikethrough (true/false) | underline (true/false)</code>
+ * @return text attribute created from the <code>styleValue</code> or null if the <code>styleValue</code> is invalid
+ */
+ private TextAttribute createTextAttribute(String styleValue) {
+ String[] values = ColorHelper.unpackStylePreferences(styleValue);
+ if (values.length < 6)
+ return null;
+
+ RGB foreground = ColorHelper.toRGB(values[0]);
+ RGB background = ColorHelper.toRGB(values[1]);
+ boolean bold = Boolean.valueOf(values[2]).booleanValue();
+ boolean italic = Boolean.valueOf(values[3]).booleanValue();
+ boolean strikethrough = Boolean.valueOf(values[4]).booleanValue();
+ boolean underline = Boolean.valueOf(values[5]).booleanValue();
+
+ int style = SWT.NORMAL;
+ if (bold)
+ style = style | SWT.BOLD;
+ if (italic)
+ style = style | SWT.ITALIC;
+ if (strikethrough)
+ style = style | TextAttribute.STRIKETHROUGH;
+ if (underline)
+ style = style | TextAttribute.UNDERLINE;
+
+ return createTextAttribute(foreground, background, style);
+ }
+
+ private TextAttribute createTextAttribute(RGB foreground, RGB background, int style) {
+ return new TextAttribute((foreground != null) ? EditorUtility.getColor(foreground) : null, (background != null) ? EditorUtility.getColor(background) : null, style);
+ }
+
+ /**
+ * Looks up a boolean preference by <code>key</code> from the preference store
+ * @param store the preference store to lookup the preference from
+ * @param key the key the preference is stored under
+ * @return the preference value from the preference store iff key is not null
+ */
+ private boolean getBoolean(IPreferenceStore store, String key) {
+ return (key == null) ? false : store.getBoolean(key);
+ }
+
+ /**
+ * Looks up a String preference by <code>key</code> from the preference store
+ * @param store the preference store to lookup the preference from
+ * @param key the key the preference is stored under
+ * @return the preference value from the preference store iff key is not null
+ */
+ private String getString(IPreferenceStore store, String key) {
+ return (key == null) ? null : store.getString(key);
+ }
+
+ /**
+ * Enable semantic highlighting.
+ */
+ private void enable() {
+
+ loadSemanticHighlightings();
+
+ fPresenter = new SemanticHighlightingPresenter();
+ fPresenter.install(fSourceViewer, fPresentationReconciler);
+// if (fEditor != null) {
+ fReconciler = new SemanticHighlightingReconciler();
+ fReconciler.install(fSourceViewer, fPresenter, fHighlightings, fHighlightingStyles);
+ IReconciler reconciler = fConfiguration.getReconciler(fSourceViewer);
+ if (reconciler instanceof DocumentRegionProcessor)
+ ((DocumentRegionProcessor) reconciler).setSemanticHighlightingStrategy(fReconciler);
+// } else {
+// fPresenter.updatePresentation(null, createHardcodedPositions(), new HighlightedPosition[0]);
+// }
+ }
+
+ /**
+ * Disable semantic highlighting
+ */
+ private void disable() {
+ if (fReconciler != null) {
+ fReconciler.uninstall();
+ fReconciler = null;
+ }
+
+ if (fPresenter != null) {
+ fPresenter.uninstall();
+ fPresenter = null;
+ }
+
+ if (fHighlightings != null)
+ disposeHighlightings();
+ }
+
+ private void disposeHighlightings() {
+ /* Remove the property change listener before clearing the lists */
+ if (fHighlightings != null) {
+ for (int i = 0; i < fHighlightings.length; i++) {
+ IPreferenceStore store = fHighlightings[i].getPreferenceStore();
+ if (store != null)
+ store.removePropertyChangeListener(fHighlightingChangeListener);
+ }
+ }
+
+ fHighlightings = null;
+ fHighlightingStyles = null;
+ fHighlightingStyleStringKeys = null;
+ }
+
+ /**
+ * Handles property change events for individual semantic highlightings.
+ * @param event
+ */
+ private void handleHighlightingPropertyChange(PropertyChangeEvent event) {
+ String property = event.getProperty();
+ if (property == null)
+ return;
+
+ boolean refreshRequired = false;
+
+ for (int i = 0; i < fHighlightings.length; i++) {
+ ISemanticHighlighting highlighting = fHighlightings[i];
+
+ if (fHighlightingStyleStringKeys[i] != null) {
+ if (property.equals(fHighlightingStyleStringKeys[i])) {
+ adaptToStyleChange(fHighlightingStyles[i], event);
+ fPresenter.highlightingStyleChanged(fHighlightingStyles[i]);
+ refreshRequired = true;
+ continue;
+ }
+ }
+
+ if (property.equals(highlighting.getBoldPreferenceKey())) {
+ adaptToTextStyleChange(fHighlightingStyles[i], event, SWT.BOLD);
+ fPresenter.highlightingStyleChanged(fHighlightingStyles[i]);
+ refreshRequired = true;
+ continue;
+ }
+
+ if (property.equals(highlighting.getColorPreferenceKey())) {
+ adaptToTextForegroundChange(fHighlightingStyles[i], event);
+ fPresenter.highlightingStyleChanged(fHighlightingStyles[i]);
+ refreshRequired = true;
+ continue;
+ }
+
+ if (property.equals(highlighting.getEnabledPreferenceKey())) {
+ adaptToEnablementChange(fHighlightingStyles[i], event);
+ fPresenter.highlightingStyleChanged(fHighlightingStyles[i]);
+ refreshRequired = true;
+ continue;
+ }
+
+ if (property.equals(highlighting.getItalicPreferenceKey())) {
+ adaptToTextStyleChange(fHighlightingStyles[i], event, SWT.ITALIC);
+ fPresenter.highlightingStyleChanged(fHighlightingStyles[i]);
+ refreshRequired = true;
+ continue;
+ }
+
+ if (property.equals(highlighting.getStrikethroughPreferenceKey())) {
+ adaptToTextStyleChange(fHighlightingStyles[i], event, TextAttribute.STRIKETHROUGH);
+ fPresenter.highlightingStyleChanged(fHighlightingStyles[i]);
+ refreshRequired = true;
+ continue;
+ }
+
+ if (property.equals(highlighting.getUnderlinePreferenceKey())) {
+ adaptToTextStyleChange(fHighlightingStyles[i], event, TextAttribute.UNDERLINE);
+ fPresenter.highlightingStyleChanged(fHighlightingStyles[i]);
+ refreshRequired = true;
+ continue;
+ }
+
+ if (highlighting instanceof ISemanticHighlightingExtension2 && property.equals(((ISemanticHighlightingExtension2) highlighting).getBackgroundColorPreferenceKey())) {
+ adaptToTextBackgroundChange(fHighlightingStyles[i], event);
+ fPresenter.highlightingStyleChanged(fHighlightingStyles[i]);
+ refreshRequired = true;
+ continue;
+ }
+ }
+
+ if (refreshRequired && fReconciler != null)
+ fReconciler.refresh();
+ }
+
+ /**
+ * Handles property changes for enabling and disabling semantic highlighting for
+ * Structured Source Editors
+ * @param event
+ */
+ private void handlePropertyChange(PropertyChangeEvent event) {
+ String property = event.getProperty();
+ if (property == null || !property.equals(EditorPreferenceNames.SEMANTIC_HIGHLIGHTING))
+ return;
+
+ Object newValue = event.getNewValue();
+ if (newValue instanceof Boolean) {
+ if (((Boolean) newValue).booleanValue())
+ enable();
+ else
+ disable();
+ }
+
+ if (fReconciler != null)
+ fReconciler.refresh();
+ }
+
+ private void adaptToEnablementChange(HighlightingStyle highlighting, PropertyChangeEvent event) {
+ Object value = event.getNewValue();
+ boolean eventValue;
+ if (value instanceof Boolean)
+ eventValue = ((Boolean) value).booleanValue();
+ else if (IPreferenceStore.TRUE.equals(value))
+ eventValue = true;
+ else
+ eventValue = false;
+ highlighting.setEnabled(eventValue);
+ }
+
+ private void adaptToTextForegroundChange(HighlightingStyle highlighting, PropertyChangeEvent event) {
+ RGB rgb = null;
+
+ Object value = event.getNewValue();
+ if (value instanceof RGB)
+ rgb= (RGB) value;
+ else if (value instanceof String)
+ rgb= ColorHelper.toRGB( (String) value);
+
+ if (rgb != null) {
+ Color color= EditorUtility.getColor(rgb);
+ TextAttribute oldAttr= highlighting.getTextAttribute();
+ highlighting.setTextAttribute(new TextAttribute(color, oldAttr.getBackground(), oldAttr.getStyle()));
+ }
+ }
+
+ private void adaptToTextBackgroundChange(HighlightingStyle highlighting, PropertyChangeEvent event) {
+ RGB rgb = null;
+
+ Object value = event.getNewValue();
+ if (value instanceof RGB)
+ rgb = (RGB) value;
+ else if (value instanceof String)
+ rgb = ColorHelper.toRGB( (String) value);
+
+ if (rgb != null) {
+ Color color= EditorUtility.getColor(rgb);
+ TextAttribute oldAttr= highlighting.getTextAttribute();
+ highlighting.setTextAttribute(new TextAttribute(oldAttr.getForeground(), color, oldAttr.getStyle()));
+ }
+ }
+
+ private void adaptToTextStyleChange(HighlightingStyle highlighting, PropertyChangeEvent event, int styleAttribute) {
+ boolean eventValue = false;
+ Object value = event.getNewValue();
+ if (value instanceof Boolean)
+ eventValue = ((Boolean) value).booleanValue();
+ else if (IPreferenceStore.TRUE.equals(value))
+ eventValue = true;
+
+ TextAttribute oldAttr = highlighting.getTextAttribute();
+ boolean activeValue = (oldAttr.getStyle() & styleAttribute) == styleAttribute;
+
+ if (activeValue != eventValue)
+ highlighting.setTextAttribute(new TextAttribute(oldAttr.getForeground(), oldAttr.getBackground(), eventValue ? oldAttr.getStyle() | styleAttribute : oldAttr.getStyle() & ~styleAttribute));
+ }
+
+ /**
+ * Adapts to a style string change
+ *
+ * @param highlighting the highlighting style to update
+ * @param event the event that triggered the change
+ */
+ private void adaptToStyleChange(HighlightingStyle highlighting, PropertyChangeEvent event) {
+ Object value = event.getNewValue();
+ if (value instanceof String) {
+ TextAttribute attr = createTextAttribute((String) value);
+ if (attr != null)
+ highlighting.setTextAttribute(attr);
+ }
+ }
+
+ /**
+ * @return <code>true</code> iff semantic highlighting is enabled in the preferences
+ */
+ private boolean isEnabled() {
+ return (fPreferenceStore != null) ? fPreferenceStore.getBoolean(EditorPreferenceNames.SEMANTIC_HIGHLIGHTING) : false;
+ }
+
+ public void uninstall() {
+ disable();
+
+ if (fPreferenceStore != null) {
+ fPreferenceStore.removePropertyChangeListener(this);
+ fPreferenceStore = null;
+ }
+
+ fSourceViewer = null;
+ fConfiguration = null;
+ fPresentationReconciler = null;
+ }
+
+}

Back to the top