blob: a12b4af394d3e23938c0ba47a78702000d8d5589 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 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 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.SourceViewerConfiguration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.wst.sse.ui.StructuredTextEditor;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
import org.eclipse.wst.sse.ui.internal.provisional.style.StructuredPresentationReconciler;
import org.eclipse.wst.sse.ui.internal.reconcile.DocumentRegionProcessor;
/**
* 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
*
*/
public class SemanticHighlightingManager {
/**
* 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 StructuredTextEditor fEditor;
private StructuredTextViewer fSourceViewer;
private SourceViewerConfiguration fConfiguration;
private StructuredPresentationReconciler fPresentationReconciler;
private SemanticHighlightingPresenter fPresenter;
private SemanticHighlightingReconciler fReconciler;
public void install(StructuredTextEditor editor, StructuredTextViewer sourceViewer, IPreferenceStore preferenceStore, SourceViewerConfiguration configuration, String contentTypeId) {
fEditor = editor;
fSourceViewer = sourceViewer;
fConfiguration = configuration;
// fContentTypeId = contentTypeId;
fPresentationReconciler = (StructuredPresentationReconciler) fConfiguration.getPresentationReconciler(fSourceViewer);
if (isEnabled()) {
enable();
}
}
/**
* Load the semantic highlightings defined for this content type.
*/
private void loadSemanticHighlightings() {
}
/**
* Enable semantic highlighting.
*/
private void enable() {
loadSemanticHighlightings();
fPresenter = new SemanticHighlightingPresenter();
fPresenter.install(fSourceViewer, fPresentationReconciler);
if (fEditor != null) {
fReconciler = new SemanticHighlightingReconciler();
fReconciler.install(fEditor, fSourceViewer, fPresenter);
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;
}
}
/**
* @return <code>true</code> iff semantic highlighting is enabled in the preferences
*/
private boolean isEnabled() {
return true;
}
public void uninstall() {
disable();
fEditor = null;
fSourceViewer = null;
fConfiguration = null;
fPresentationReconciler = null;
}
}