/*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems, Inc. 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:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.cdt.internal.ui.LineBackgroundPainter;
/**
* <code>SourceViewerDecorationSupport</code> with extension(s):
* <ul>
* <li>inactive code painter</li>
* </ul>
*
* @author anton.leherbauer@windriver.com
*
* @since 4.0
*/
public class CSourceViewerDecorationSupport extends SourceViewerDecorationSupport {
/** The key to use for the {@link LineBackgroundPainter} */
private static final String INACTIVE_CODE_KEY = "inactiveCode"; //$NON-NLS-1$
/** The preference key for the inactive code highlight color */
private String fInactiveCodeColorKey;
/** The preference key for the inactive code highlight enablement */
private String fInactiveCodeEnableKey;
/** The generic line background painter instance. */
private LineBackgroundPainter fLineBackgroundPainter;
/** The shared colors instance (duplicate of private base class member) */
private ISharedTextColors fSharedColors;
/** The preference store (duplicate of private base class member) */
private IPreferenceStore fPrefStore;
/** The preference key for the cursor line highlight color (duplicate of private base class member) */
private String fCLPColorKey;
/** The preference key for the cursor line highlight enablement (duplicate of private base class member) */
private String fCLPEnableKey;
/** The source viewer (duplicate of private base class member) */
protected ISourceViewer fViewer;
/** The editor we are associated with */
private CEditor fEditor;
/** The inactive code highlighting */
private InactiveCodeHighlighting fInactiveCodeHighlighting;
/**
* Inherited constructor.
*
* @param sourceViewer
* @param overviewRuler
* @param annotationAccess
* @param sharedTextColors
*/
CSourceViewerDecorationSupport(
CEditor editor,
ISourceViewer sourceViewer,
IOverviewRuler overviewRuler,
IAnnotationAccess annotationAccess,
ISharedTextColors sharedTextColors) {
super(sourceViewer, overviewRuler, annotationAccess, sharedTextColors);
fEditor = editor;
// we have to save our own references, because super class members are all private
fViewer = sourceViewer;
fSharedColors = sharedTextColors;
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#dispose()
*/
@Override
public void dispose() {
super.dispose();
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent)
*/
@Override
protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
String p = event.getProperty();
if (p.equals(fCLPEnableKey)) {
if (isCLPActive()) {
showCLP();
} else {
hideCLP();
}
} else if (p.equals(fCLPColorKey)) {
updateCLPColor();
} else if (p.equals(fInactiveCodeEnableKey)) {
if (isInactiveCodePositionsActive()) {
showInactiveCodePositions(true);
} else {
hideInactiveCodePositions();
}
} else if (p.equals(fInactiveCodeColorKey)) {
updateInactiveCodeColor();
}
super.handlePreferenceStoreChanged(event);
}
/**
* Update the color for inactive code positions.
*/
private void updateInactiveCodeColor() {
if (fLineBackgroundPainter != null) {
fLineBackgroundPainter.setBackgroundColor(INACTIVE_CODE_KEY, getColor(fInactiveCodeColorKey));
if (isInactiveCodePositionsActive()) {
fLineBackgroundPainter.redraw();
}
}
}
/**
* Update the color for the cursor line highlighting.
*/
private void updateCLPColor() {
if (fLineBackgroundPainter != null) {
fLineBackgroundPainter.setCursorLineColor(getColor(fCLPColorKey));
if (isCLPActive()) {
fLineBackgroundPainter.redraw();
}
}
}
/**
* Hide cursor line highlighting.
*/
private void hideCLP() {
if (fLineBackgroundPainter != null) {
if (!isInactiveCodePositionsActive()) {
uninstallLineBackgroundPainter();
} else {
fLineBackgroundPainter.enableCursorLine(false);
fLineBackgroundPainter.redraw();
}
}
}
/**
* Show cursor line highlighting.
*/
private void showCLP() {
installLineBackgroundPainter();
if (fLineBackgroundPainter != null) {
fLineBackgroundPainter.enableCursorLine(true);
fLineBackgroundPainter.redraw();
}
}
/**
* @return true if cursor line highlighting is active.
*/
private boolean isCLPActive() {
if (fPrefStore != null) {
return fPrefStore.getBoolean(fCLPEnableKey);
}
return false;
}
/**
* @return true if inactive code highlighting is active.
*/
private boolean isInactiveCodePositionsActive() {
if (fPrefStore != null) {
return fPrefStore.getBoolean(fInactiveCodeEnableKey);
}
return false;
}
/**
* Returns the shared color for the given key.
*
* @param key the color key string
* @return the shared color for the given key
*/
private Color getColor(String key) {
if (fPrefStore != null) {
RGB rgb = PreferenceConverter.getColor(fPrefStore, key);
return getColor(rgb);
}
return null;
}
/**
* Returns the shared color for the given RGB.
*
* @param rgb the rgb
* @return the shared color for the given rgb
*/
private Color getColor(RGB rgb) {
return fSharedColors.getColor(rgb);
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#install(org.eclipse.jface.preference.IPreferenceStore)
*/
@Override
public void install(IPreferenceStore store) {
super.install(store);
fPrefStore = store;
if (isCLPActive()) {
showCLP();
}
if (isInactiveCodePositionsActive()) {
showInactiveCodePositions(false);
}
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#uninstall()
*/
@Override
public void uninstall() {
uninstallLineBackgroundPainter();
super.uninstall();
}
/**
* Install line background painter (inactive code/cursor line).
*/
private void installLineBackgroundPainter() {
if (fLineBackgroundPainter == null) {
if (fViewer instanceof ITextViewerExtension2) {
fLineBackgroundPainter = new LineBackgroundPainter(fViewer);
fLineBackgroundPainter.setBackgroundColor(INACTIVE_CODE_KEY, getColor(fInactiveCodeColorKey));
fLineBackgroundPainter.setCursorLineColor(getColor(fCLPColorKey));
fLineBackgroundPainter.enableCursorLine(isCLPActive());
((ITextViewerExtension2)fViewer).addPainter(fLineBackgroundPainter);
}
}
}
/**
* Uninstall line background painter (inactive code/cursor line).
*/
private void uninstallLineBackgroundPainter() {
if (fLineBackgroundPainter != null) {
if (fInactiveCodeHighlighting != null) {
fInactiveCodeHighlighting.uninstall();
fInactiveCodeHighlighting= null;
}
if (fViewer instanceof ITextViewerExtension2) {
((ITextViewerExtension2)fViewer).removePainter(fLineBackgroundPainter);
}
fLineBackgroundPainter.deactivate(true);
fLineBackgroundPainter.dispose();
fLineBackgroundPainter = null;
}
}
/**
* Show inactive code positions.
*
* @param refresh trigger a refresh of the positions
*/
private void showInactiveCodePositions(boolean refresh) {
installLineBackgroundPainter();
if (fLineBackgroundPainter != null) {
fInactiveCodeHighlighting= new InactiveCodeHighlighting(INACTIVE_CODE_KEY);
fInactiveCodeHighlighting.install(fEditor, fLineBackgroundPainter);
if (refresh) {
fInactiveCodeHighlighting.refresh();
}
}
}
/**
* Hide inactive code positions.
*/
private void hideInactiveCodePositions() {
if (fLineBackgroundPainter != null) {
if (fInactiveCodeHighlighting != null) {
fInactiveCodeHighlighting.uninstall();
fInactiveCodeHighlighting= null;
}
if (!isCLPActive()) {
uninstallLineBackgroundPainter();
}
}
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#setCursorLinePainterPreferenceKeys(java.lang.String, java.lang.String)
*/
@Override
public void setCursorLinePainterPreferenceKeys(String enableKey, String colorKey) {
// this is a dirty hack to override the original cursor line painter
// and replace it with the generic BackgroundLinePainter
fCLPEnableKey = enableKey;
fCLPColorKey = colorKey;
super.setCursorLinePainterPreferenceKeys(enableKey + "-overridden", colorKey); //$NON-NLS-1$
}
/**
* Set the preference keys for the inactive code painter.
* @param enableKey
* @param colorKey
*/
public void setInactiveCodePainterPreferenceKeys(String enableKey, String colorKey) {
fInactiveCodeEnableKey = enableKey;
fInactiveCodeColorKey = colorKey;
}
}