1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-09 18:56:02 +02:00

Implement Bugzilla 81511 - Unreachable #ifdef blocks should be marked in editor (part 1)

This is the highlighting part. Folding will follow.
This commit is contained in:
Anton Leherbauer 2006-07-14 13:21:47 +00:00
parent 5343674d38
commit 77d0b48df3
7 changed files with 1234 additions and 76 deletions

View file

@ -0,0 +1,464 @@
/*******************************************************************************
* Copyright (c) 2006 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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IPaintPositionManager;
import org.eclipse.jface.text.IPainter;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.TypedPosition;
import org.eclipse.swt.custom.LineBackgroundEvent;
import org.eclipse.swt.custom.LineBackgroundListener;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
/**
* A painter for configurable background painting a range of text lines.
* Replicates also the functionality of the
* {@link org.eclipse.jface.text.CursorLinePainter}
* because only one {@link LineBackgroundListener} is allowed
* per {@link StyledText} widget.
*
* @author anton.leherbauer@windriver.com
*
* @since 4.0
*/
public class LineBackgroundPainter implements IPainter, LineBackgroundListener {
/** The default position type for untyped positions */
private static final String DEFAULT_TYPE= "__default__"; //$NON-NLS-1$
/** The position type for the cursor line position */
private static final String CURSOR_LINE_TYPE= "__cursor_line__"; //$NON-NLS-1$
/** Manager for position changes */
private IPaintPositionManager fPositionManager;
/** Indicates whether this painter is active */
private boolean fIsActive= false;
/** The text viewer this painter is associated with */
private ITextViewer fTextViewer;
/** The viewer's widget */
private StyledText fTextWidget;
/** Text positions (cursor line position is always at index 0 */
private List fPositions= new ArrayList();
/** Cached text positions */
private List fLastPositions= new ArrayList();
/** Temporary changed positions */
private List fChangedPositions= new ArrayList();
/** Cursor line position */
private Position fCursorLine= new TypedPosition(0, 0, CURSOR_LINE_TYPE);
/** Saved cursor line position */
private Position fLastCursorLine= new Position(0, 0);
/** Enablement of the cursor line highlighting */
private boolean fCursorLineEnabled;
/** Map of position type to color */
private Map fColorMap= new HashMap();
/**
* Creates a new painter for the given text viewer.
* @param textViewer
*/
public LineBackgroundPainter(ITextViewer textViewer) {
super();
fTextViewer= textViewer;
fTextWidget= textViewer.getTextWidget();
fPositions.add(fCursorLine);
fLastPositions.add(fLastCursorLine);
}
/**
* Sets the color in which to draw the background of the given position type.
*
* @param positionType the position type for which to specify the background color
* @param color the color in which to draw the background of the given position type
*/
public void setBackgroundColor(String positionType, Color color) {
fColorMap.put(positionType, color);
}
/**
* Sets the color in which to draw the background of the cursor line.
*
* @param cursorLineColor the color in which to draw the background of the cursor line
*/
public void setCursorLineColor(Color cursorLineColor) {
fColorMap.put(CURSOR_LINE_TYPE, cursorLineColor);
}
/**
* Sets the color in which to draw the background of untyped positions.
*
* @param color the color in which to draw the background of untyped positions
*/
public void setDefaultColor(Color color) {
fColorMap.put(DEFAULT_TYPE, color);
}
/**
* Enable/disable cursor line highlighting.
*
* @param enable
*/
public void enableCursorLine(boolean enable) {
fCursorLineEnabled= enable;
if (fCursorLineEnabled) {
updateCursorLine();
}
}
/**
* Set highlight positions. It is assumed that all positions
* are up-to-date with respect to the text viewers document.
*
* @param positions a list of <code>Position</code>s
*/
public void setHighlightPositions(List positions) {
boolean isActive= fIsActive;
deactivate(isActive);
fPositions.clear();
fPositions.add(fCursorLine);
fPositions.addAll(positions);
if (isActive) {
activate(true);
}
}
/**
* Trigger redraw of managed positions.
*/
public void redraw() {
if(fIsActive) {
fTextWidget.redraw();
}
}
/**
* Manage all positions.
* @param positions
*/
private void managePositions(List positions) {
if (fPositionManager == null) {
return;
}
int sz= fPositions.size();
for (int i= 0; i < sz; ++i) {
Position position= (Position)positions.get(i);
fPositionManager.managePosition(position);
}
}
/**
* Unmanage all positions.
* @param positions
*/
private void unmanagePositions(List positions) {
if (fPositionManager == null) {
return;
}
int sz= fPositions.size();
for (int i= 0; i < sz; ++i) {
Position position= (Position)positions.get(i);
fPositionManager.unmanagePosition(position);
}
}
/*
* @see org.eclipse.jface.text.IPainter#dispose()
*/
public void dispose() {
// no deactivate!
fIsActive= false;
fTextViewer= null;
fTextWidget= null;
fCursorLine= null;
fLastCursorLine= null;
fPositions= null;
fLastPositions= null;
fChangedPositions= null;
fColorMap= null;
}
/*
* @see org.eclipse.jface.text.IPainter#paint(int)
*/
public void paint(int reason) {
IDocument document= fTextViewer.getDocument();
if (document == null) {
deactivate(false);
return;
}
activate(false);
if (fCursorLineEnabled) {
// redraw in case of text changes prior to update of current cursor line
if (!fLastCursorLine.equals(fCursorLine)) {
redrawPositions(Collections.singletonList(fLastCursorLine));
fLastCursorLine.offset= fCursorLine.offset;
fLastCursorLine.length= fCursorLine.length;
}
updateCursorLine();
}
List changedPositions= getChangedPositions();
if (changedPositions != null) {
redrawPositions(changedPositions);
updatePositions();
redrawPositions(changedPositions);
}
}
/**
* Activate the painter.
* @param redraw
*/
private void activate(boolean redraw) {
if (!fIsActive) {
fIsActive= true;
fTextWidget.addLineBackgroundListener(this);
if (redraw) {
if (fCursorLineEnabled) {
updateCursorLine();
}
updatePositions();
redrawPositions(fPositions);
}
managePositions(fPositions);
}
}
/**
* Copy positions from the current position list to the last position list.
*/
private void updatePositions() {
int sz= fPositions.size();
for (int i= 0; i < sz; ++i) {
Position position= (Position)fPositions.get(i);
Position copy;
if (i == fLastPositions.size()) {
copy= new Position(position.offset, position.length);
copy.isDeleted= position.isDeleted;
fLastPositions.add(copy);
} else {
copy= (Position)fLastPositions.get(i);
copy.offset= position.offset;
copy.length= position.length;
copy.isDeleted= position.isDeleted;
}
position.isDeleted= false;
}
int diff= fLastPositions.size() - sz;
while (diff > 0) {
--diff;
fLastPositions.remove(sz + diff);
}
}
/**
* Check which positions have changed since last redraw.
* @return a list of changed positions or <code>null</code> if none changed.
*/
private List getChangedPositions() {
if (fLastPositions.size() != fPositions.size()) {
return fLastPositions;
}
List changedPositions= null;
for (int i= 0, sz= fPositions.size(); i < sz; ++i) {
Position previous= (Position)fLastPositions.get(i);
Position current= (Position)fPositions.get(i);
if (!previous.equals(current)) {
if (changedPositions == null) {
changedPositions= fChangedPositions;
changedPositions.clear();
}
changedPositions.add(previous);
}
}
return changedPositions;
}
/**
* Trigger redraw of given text positions.
*/
private void redrawPositions(List positions) {
final int minOffset= fTextViewer.getTopIndexStartOffset();
final int maxOffset= fTextViewer.getBottomIndexEndOffset()+3;
Rectangle clientArea= fTextWidget.getClientArea();
int width= clientArea.width + fTextWidget.getHorizontalPixel();
int lineHeight= fTextWidget.getLineHeight();
for (int i= 0, sz= positions.size(); i < sz; ++i) {
Position position= (Position)positions.get(i);
// if the position that is about to be drawn was deleted then we can't
if (position.isDeleted()) {
continue;
}
// check if position overlaps with visible area
if (!position.overlapsWith(minOffset, maxOffset - minOffset + 1)) {
continue;
}
int widgetOffset= getWidgetOffset(position.offset);
if (widgetOffset < 0 || widgetOffset > fTextWidget.getCharCount()) {
continue;
}
// TLETODO [performance] SyledText.getLocationAtOffset() is very expensive
Point upperLeft= fTextWidget.getLocationAtOffset(widgetOffset);
int upperY= Math.max(Math.min(upperLeft.y, clientArea.height), 0);
int height;
if (position.length == 0) {
height= lineHeight;
} else {
int widgetEndOffset= Math.min(widgetOffset + position.length, fTextWidget.getCharCount());
Point lowerRight= fTextWidget.getLocationAtOffset(widgetEndOffset);
int lowerY= Math.min(lowerRight.y + lineHeight, clientArea.height);
height= lowerY - upperY;
}
if (height > 0) {
fTextWidget.redraw(0, upperY, width, height, false);
}
}
}
/*
* @see org.eclipse.jface.text.IPainter#deactivate(boolean)
*/
public void deactivate(boolean redraw) {
if (fIsActive) {
fIsActive= false;
fTextWidget.removeLineBackgroundListener(this);
if (redraw) {
redrawPositions(fLastPositions);
}
unmanagePositions(fPositions);
}
}
/*
* @see org.eclipse.jface.text.IPainter#setPositionManager(org.eclipse.jface.text.IPaintPositionManager)
*/
public void setPositionManager(IPaintPositionManager manager) {
fPositionManager= manager;
}
/**
* Convert a document offset to the corresponding widget offset.
* @param documentOffset
* @return widget offset
*/
private int getWidgetOffset(int documentOffset) {
if (fTextViewer instanceof ITextViewerExtension5) {
ITextViewerExtension5 extension= (ITextViewerExtension5)fTextViewer;
return extension.modelOffset2WidgetOffset(documentOffset);
} else {
IRegion visible= fTextViewer.getVisibleRegion();
int widgetOffset= documentOffset - visible.getOffset();
if (widgetOffset > visible.getLength()) {
return -1;
}
return widgetOffset;
}
}
/**
* Convert a widget offset to the corresponding document offset.
* @param widgetOffset
* @return document offset
*/
private int getDocumentOffset(int widgetOffset) {
if (fTextViewer instanceof ITextViewerExtension5) {
ITextViewerExtension5 extension= (ITextViewerExtension5)fTextViewer;
return extension.widgetOffset2ModelOffset(widgetOffset);
} else {
IRegion visible= fTextViewer.getVisibleRegion();
if (widgetOffset > visible.getLength()) {
return -1;
}
return widgetOffset + visible.getOffset();
}
}
/*
* @see org.eclipse.swt.custom.LineBackgroundListener#lineGetBackground(org.eclipse.swt.custom.LineBackgroundEvent)
*/
public void lineGetBackground(LineBackgroundEvent event) {
if (fTextWidget != null) {
Position match= findIncludingPosition(getDocumentOffset(event.lineOffset));
if (match != null) {
Color color= getColorForPosition(match);
if (color != null) {
event.lineBackground= color;
}
}
}
}
/**
* Get the color associated with given position.
* @param position
* @return the color associated with the position type
*/
private Color getColorForPosition(Position position) {
if (position == fCursorLine) {
if (fCursorLine.length == 0) {
return (Color)fColorMap.get(CURSOR_LINE_TYPE);
}
} else {
if (position instanceof TypedPosition) {
String type= ((TypedPosition)position).getType();
return (Color)fColorMap.get(type);
} else {
return (Color)fColorMap.get(DEFAULT_TYPE);
}
}
return null;
}
/**
* Find position which includes the (document-)offset.
* @param offset
* @return the first position including the offset or <code>null</code>.
*/
private Position findIncludingPosition(int offset) {
// TLETODO [performance] Use binary search?
for (int i= fCursorLineEnabled ? 0 : 1, sz= fPositions.size(); i < sz; ++i) {
Position position= (Position)fPositions.get(i);
if (position.offset == offset || position.includes(offset)) {
return position;
}
}
return null;
}
/**
* Updates the position of the cursor line.
*/
private void updateCursorLine() {
try {
IDocument document= fTextViewer.getDocument();
int lineNumber= document.getLineOfOffset(getDocumentOffset(fTextWidget.getCaretOffset()));
fCursorLine.isDeleted= false;
fCursorLine.offset= document.getLineOffset(lineNumber);
fCursorLine.length= 0;
} catch (BadLocationException e) {
// gracefully ignored
}
}
}

View file

@ -56,7 +56,6 @@ import org.eclipse.jface.text.source.IAnnotationHoverExtension;
import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.ICharacterPairMatcher; import org.eclipse.jface.text.source.ICharacterPairMatcher;
import org.eclipse.jface.text.source.ILineRange; import org.eclipse.jface.text.source.ILineRange;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.ISourceViewerExtension3; import org.eclipse.jface.text.source.ISourceViewerExtension3;
import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.IVerticalRuler;
@ -517,10 +516,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
public final static String MATCHING_BRACKETS = "matchingBrackets"; //$NON-NLS-1$ public final static String MATCHING_BRACKETS = "matchingBrackets"; //$NON-NLS-1$
/** Preference key for matching brackets color */ /** Preference key for matching brackets color */
public final static String MATCHING_BRACKETS_COLOR = "matchingBracketsColor"; //$NON-NLS-1$ public final static String MATCHING_BRACKETS_COLOR = "matchingBracketsColor"; //$NON-NLS-1$
/** Preference key for inactive code painter enablement */
public static final String INACTIVE_CODE_ENABLE = "inactiveCodeEnable"; //$NON-NLS-1$
/** Preference key for inactive code painter color */
public static final String INACTIVE_CODE_COLOR = "inactiveCodeColor"; //$NON-NLS-1$
/** Preference key for inserting spaces rather than tabs */ /** Preference key for inserting spaces rather than tabs */
public final static String SPACES_FOR_TABS = "spacesForTabs"; //$NON-NLS-1$ public final static String SPACES_FOR_TABS = "spacesForTabs"; //$NON-NLS-1$
/** Preference key for linked position color */
public final static String LINKED_POSITION_COLOR = "linkedPositionColor"; //$NON-NLS-1$
/** Preference key for compiler task tags */ /** Preference key for compiler task tags */
private final static String TRANSLATION_TASK_TAGS= CCorePreferenceConstants.TRANSLATION_TASK_TAGS; private final static String TRANSLATION_TASK_TAGS= CCorePreferenceConstants.TRANSLATION_TASK_TAGS;
@ -575,6 +576,11 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
if (fCEditorErrorTickUpdater != null) { if (fCEditorErrorTickUpdater != null) {
fCEditorErrorTickUpdater.updateEditorImage(getInputCElement()); fCEditorErrorTickUpdater.updateEditorImage(getInputCElement());
} }
if (getSourceViewer() != null) {
CSourceViewerDecorationSupport decoSupport = (CSourceViewerDecorationSupport) getSourceViewerDecorationSupport(getSourceViewer());
decoSupport.editorInputChanged(input);
}
} }
/** /**
@ -1211,6 +1217,29 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
dragSource.addDragListener(dragSourceListener); dragSource.addDragListener(dragSourceListener);
} }
/*
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#getSourceViewerDecorationSupport(org.eclipse.jface.text.source.ISourceViewer)
*/
protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(
ISourceViewer viewer) {
if (fSourceViewerDecorationSupport == null) {
fSourceViewerDecorationSupport= new CSourceViewerDecorationSupport(viewer, getOverviewRuler(), getAnnotationAccess(), getSharedColors());
configureSourceViewerDecorationSupport(fSourceViewerDecorationSupport);
}
return fSourceViewerDecorationSupport;
}
/*
* @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#configureSourceViewerDecorationSupport(org.eclipse.ui.texteditor.SourceViewerDecorationSupport)
*/
protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
super.configureSourceViewerDecorationSupport(support);
//Enhance the stock source viewer decorator with a bracket matcher
support.setCharacterPairMatcher(fBracketMatcher);
support.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
((CSourceViewerDecorationSupport)support).setInactiveCodePainterPreferenceKeys(INACTIVE_CODE_ENABLE, INACTIVE_CODE_COLOR);
}
/** /**
* Jumps to the matching bracket. * Jumps to the matching bracket.
*/ */
@ -1448,29 +1477,19 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
} }
/* /*
* @see AbstractTextEditor#createSourceViewer(Composite, IVerticalRuler, int) * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createSourceViewer(org.eclipse.swt.widgets.Composite, org.eclipse.jface.text.source.IVerticalRuler, int)
*/ */
protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) { protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles) {
fAnnotationAccess = createAnnotationAccess();
ISharedTextColors sharedColors = CUIPlugin.getDefault().getSharedTextColors();
fOverviewRuler = createOverviewRuler(sharedColors);
ISourceViewer sourceViewer = ISourceViewer sourceViewer =
new CSourceViewer( new CSourceViewer(
this, parent, this, parent,
ruler, ruler,
styles, styles,
fOverviewRuler, getOverviewRuler(),
isOverviewRulerVisible()); isOverviewRulerVisible());
fSourceViewerDecorationSupport =
new SourceViewerDecorationSupport(sourceViewer, fOverviewRuler, fAnnotationAccess, sharedColors);
configureSourceViewerDecorationSupport(fSourceViewerDecorationSupport); CSourceViewerDecorationSupport decoSupport = (CSourceViewerDecorationSupport) getSourceViewerDecorationSupport(sourceViewer);
decoSupport.editorInputChanged(getEditorInput());
//Enhance the stock source viewer decorator with a bracket matcher
fSourceViewerDecorationSupport.setCharacterPairMatcher(fBracketMatcher);
fSourceViewerDecorationSupport.setMatchingCharacterPainterPreferenceKeys(MATCHING_BRACKETS, MATCHING_BRACKETS_COLOR);
CUIHelp.setHelp(this, sourceViewer.getTextWidget(), ICHelpContextIds.CEDITOR_VIEW); CUIHelp.setHelp(this, sourceViewer.getTextWidget(), ICHelpContextIds.CEDITOR_VIEW);
@ -1620,6 +1639,10 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
// Do nothing the outliner is listener to the // Do nothing the outliner is listener to the
// CoreModel WorkingCopy changes instead. // CoreModel WorkingCopy changes instead.
// It will allow more fined grained. // It will allow more fined grained.
if (somethingHasChanged && getSourceViewer() != null) {
CSourceViewerDecorationSupport decoSupport = (CSourceViewerDecorationSupport) getSourceViewerDecorationSupport(getSourceViewer());
decoSupport.editorInputChanged(getEditorInput());
}
} }
public CSourceViewer getCSourceViewer() { public CSourceViewer getCSourceViewer() {

View file

@ -14,7 +14,10 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.text.DocumentCommand; import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.ITextViewerExtension; import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.contentassist.IContentAssistant;
@ -24,10 +27,16 @@ import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.ProjectionViewer; import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.editors.text.ILocationProvider;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.editor.CEditor.ITextConverter; import org.eclipse.cdt.internal.ui.editor.CEditor.ITextConverter;
@ -80,6 +89,35 @@ public class CSourceViewer extends ProjectionViewer implements ITextViewerExtens
} catch (CoreException e) { } catch (CoreException e) {
CUIPlugin.getDefault().log(e); CUIPlugin.getDefault().log(e);
} }
} else {
// compute the language from the plain editor input
IContentType contentType = null;
IEditorInput input = editor.getEditorInput();
IFile file = ResourceUtil.getFile(input);
if (file != null) {
contentType = CCorePlugin.getContentType(file.getProject(), file.getName());
try {
return LanguageManager.getInstance().getLanguage(contentType);
} catch (CoreException exc) {
CUIPlugin.getDefault().log(exc.getStatus());
}
} else if (input instanceof IPathEditorInput) {
IPath path = ((IPathEditorInput)input).getPath();
contentType = CCorePlugin.getContentType(path.lastSegment());
} else {
ILocationProvider locationProvider = (ILocationProvider)input.getAdapter(ILocationProvider.class);
if (locationProvider != null) {
IPath path = locationProvider.getPath(input);
contentType = CCorePlugin.getContentType(path.lastSegment());
}
}
if (contentType != null) {
try {
return LanguageManager.getInstance().getLanguage(contentType);
} catch (CoreException exc) {
CUIPlugin.getDefault().log(exc.getStatus());
}
}
} }
return null; return null;
} }

View file

@ -0,0 +1,528 @@
/*******************************************************************************
* Copyright (c) 2006 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 java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.Position;
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.IEditorInput;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IPositionConverter;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElseStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorEndifStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfdefStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIfndefStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.ui.CUIPlugin;
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 {
/**
* This job takes the current translation unit and produces an
* AST in the background. Upon completion, {@link #inactiveCodePositionsChanged}
* is called in the display thread.
*/
private class UpdateJob extends Job {
/**
* @param name
*/
public UpdateJob(String name) {
super(name);
setSystem(true);
setPriority(Job.DECORATE);
}
/*
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
protected IStatus run(IProgressMonitor monitor) {
IStatus result = Status.OK_STATUS;
if (fASTTranslationUnit == null && fTranslationUnit != null) {
try {
fParseTimeStamp = System.currentTimeMillis();
fASTTranslationUnit = fTranslationUnit.getLanguage().getASTTranslationUnit(fTranslationUnit, ILanguage.AST_SKIP_IF_NO_BUILD_INFO | ILanguage.AST_SKIP_INDEXED_HEADERS);
} catch (CoreException exc) {
result = exc.getStatus();
}
}
if (monitor.isCanceled() || fViewer == null) {
result = Status.CANCEL_STATUS;
} else {
final List inactiveCodePositions = collectInactiveCodePositions(fASTTranslationUnit);
Runnable updater = new Runnable() {
public void run() {
inactiveCodePositionsChanged(inactiveCodePositions);
}
};
fViewer.getTextWidget().getDisplay().asyncExec(updater);
}
return result;
}
}
/**
* Implementation of <code>IRegion</code> that can be reused
* by setting the offset and the length.
*/
private static class ReusableRegion extends Position implements IRegion {
public ReusableRegion(int offset, int length) {
super(offset, length);
}
public ReusableRegion(IRegion region) {
super(region.getOffset(), region.getLength());
}
}
/** 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 current translation unit */
private ITranslationUnit fTranslationUnit;
/** The corresponding AST translation unit */
private IASTTranslationUnit fASTTranslationUnit;
/** The time stamp when the parsing was initiated */
private long fParseTimeStamp;
/** The background job doing the AST parsing */
private Job fUpdateJob;
/**
* Inherited constructor.
*
* @param sourceViewer
* @param overviewRuler
* @param annotationAccess
* @param sharedTextColors
*/
CSourceViewerDecorationSupport(
ISourceViewer sourceViewer,
IOverviewRuler overviewRuler,
IAnnotationAccess annotationAccess,
ISharedTextColors sharedTextColors) {
super(sourceViewer, overviewRuler, annotationAccess, sharedTextColors);
// we have to save our own reference, because super class members are all private
fViewer = sourceViewer;
fSharedColors = sharedTextColors;
}
/**
* Notify that the associated editor got a new input.
* This is currently also used to notify of a reconcilation
* to update the inactive code while editing.
*
* @param input the new editor input
*/
void editorInputChanged(IEditorInput input) {
if (fUpdateJob != null) {
fUpdateJob.cancel();
}
fTranslationUnit = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(input);
fASTTranslationUnit = null;
if (isInactiveCodePositionsActive()) {
updateInactiveCodePositions();
}
}
/**
* Schedule update of the AST in the background.
*/
private void updateInactiveCodePositions() {
if (fUpdateJob == null) {
fUpdateJob = new UpdateJob("Update Inactive Code Positions"); //$NON-NLS-1$
}
if (fUpdateJob.getState() == Job.NONE) {
fUpdateJob.schedule();
}
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#dispose()
*/
public void dispose() {
super.dispose();
fViewer = null;
if (fUpdateJob != null) {
fUpdateJob.cancel();
}
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent)
*/
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();
} 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.setDefaultColor(getColor(fInactiveCodeColorKey));
if (isInactiveCodePositionsActive()) {
fLineBackgroundPainter.redraw();
}
}
}
/**
* Update the color for the cursor line painter.
*/
private void updateCLPColor() {
if (fLineBackgroundPainter != null) {
fLineBackgroundPainter.setCursorLineColor(getColor(fCLPColorKey));
if (isCLPActive()) {
fLineBackgroundPainter.redraw();
}
}
}
/**
* Hide cursor line painter.
*/
private void hideCLP() {
if (fLineBackgroundPainter != null) {
if (!isInactiveCodePositionsActive()) {
uninstallInactiveCodePainter();
} else {
fLineBackgroundPainter.enableCursorLine(false);
fLineBackgroundPainter.redraw();
}
}
}
/**
* Show cursor line painter.
*/
private void showCLP() {
installInactiveCodePainter();
if (fLineBackgroundPainter != null) {
fLineBackgroundPainter.enableCursorLine(true);
fLineBackgroundPainter.redraw();
}
}
/**
* @return true if cursor line painter is active.
*/
private boolean isCLPActive() {
if (fPrefStore != null) {
return fPrefStore.getBoolean(fCLPEnableKey);
}
return false;
}
/**
* @return true if inactive code painter 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)
*/
public void install(IPreferenceStore store) {
super.install(store);
fPrefStore = store;
if (isCLPActive()) {
showCLP();
}
if (isInactiveCodePositionsActive()) {
showInactiveCodePositions();
}
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#uninstall()
*/
public void uninstall() {
uninstallInactiveCodePainter();
super.uninstall();
}
/**
* Install inactive code/cursor line painter.
*/
private void installInactiveCodePainter() {
if (fLineBackgroundPainter == null) {
if (fViewer instanceof ITextViewerExtension2) {
fLineBackgroundPainter = new LineBackgroundPainter(fViewer);
fLineBackgroundPainter.setDefaultColor(getColor(fInactiveCodeColorKey));
fLineBackgroundPainter.setCursorLineColor(getColor(fCLPColorKey));
fLineBackgroundPainter.enableCursorLine(isCLPActive());
((ITextViewerExtension2)fViewer).addPainter(fLineBackgroundPainter);
}
}
}
/**
* Uninstall inactive code/cursor line painter.
*/
private void uninstallInactiveCodePainter() {
if (fLineBackgroundPainter != null) {
((ITextViewerExtension2)fViewer).removePainter(fLineBackgroundPainter);
fLineBackgroundPainter.deactivate(true);
fLineBackgroundPainter.dispose();
fLineBackgroundPainter = null;
}
}
/**
* Show inactive code positions.
*/
private void showInactiveCodePositions() {
installInactiveCodePainter();
updateInactiveCodePositions();
}
/**
* Hide inactive code positions.
*/
private void hideInactiveCodePositions() {
if (fLineBackgroundPainter != null) {
if (!isCLPActive()) {
uninstallInactiveCodePainter();
} else {
fLineBackgroundPainter.setHighlightPositions(Collections.EMPTY_LIST);
}
}
}
private void inactiveCodePositionsChanged(List inactiveCodePositions) {
if (fLineBackgroundPainter != null) {
if (!inactiveCodePositions.isEmpty()) {
IPositionConverter pt = CCorePlugin.getPositionTrackerManager().findPositionConverter(fTranslationUnit.getPath(), fParseTimeStamp);
if (pt != null) {
List convertedPositions = new ArrayList(inactiveCodePositions.size());
for (Iterator iter = inactiveCodePositions.iterator(); iter
.hasNext();) {
IRegion pos = (IRegion) iter.next();
convertedPositions.add(new ReusableRegion(pt.historicToActual(pos)));
}
inactiveCodePositions = convertedPositions;
}
}
fLineBackgroundPainter.setHighlightPositions(inactiveCodePositions);
}
}
/**
* Collect source positions of preprocessor-hidden branches
* in the given translation unit.
*
* @param translationUnit the {@link IASTTranslationUnit}, may be <code>null</code>
* @return a {@link List} of {@link IRegion}s
*/
private static List collectInactiveCodePositions(IASTTranslationUnit translationUnit) {
List positions = new ArrayList();
if (translationUnit == null) {
return positions;
}
int inactiveCodeStart = -1;
boolean inInactiveCode = false;
IASTPreprocessorStatement[] preprocStmts = translationUnit.getAllPreprocessorStatements();
for (int i = 0; i < preprocStmts.length; i++) {
IASTPreprocessorStatement statement = preprocStmts[i];
if (statement instanceof IASTPreprocessorIfStatement) {
IASTPreprocessorIfStatement ifStmt = (IASTPreprocessorIfStatement)statement;
if (!inInactiveCode && !ifStmt.taken()) {
IASTNodeLocation nodeLocation = ifStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inInactiveCode = true;
} else if (inInactiveCode && ifStmt.taken()) {
// should not happen!
assert false;
}
} else if (statement instanceof IASTPreprocessorIfdefStatement) {
IASTPreprocessorIfdefStatement ifdefStmt = (IASTPreprocessorIfdefStatement)statement;
if (!inInactiveCode && !ifdefStmt.taken()) {
IASTNodeLocation nodeLocation = ifdefStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inInactiveCode = true;
} else if (inInactiveCode && ifdefStmt.taken()) {
// should not happen!
assert false;
}
} else if (statement instanceof IASTPreprocessorIfndefStatement) {
IASTPreprocessorIfndefStatement ifndefStmt = (IASTPreprocessorIfndefStatement)statement;
if (!inInactiveCode && !ifndefStmt.taken()) {
IASTNodeLocation nodeLocation = ifndefStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inInactiveCode = true;
} else if (inInactiveCode && ifndefStmt.taken()) {
// should not happen!
assert false;
}
} else if (statement instanceof IASTPreprocessorElseStatement) {
IASTPreprocessorElseStatement elseStmt = (IASTPreprocessorElseStatement)statement;
if (!inInactiveCode && !elseStmt.taken()) {
IASTNodeLocation nodeLocation = elseStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inInactiveCode = true;
} else if (inInactiveCode && elseStmt.taken()) {
IASTNodeLocation nodeLocation = elseStmt.getNodeLocations()[0];
int inactiveCodeEnd = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
positions.add(new ReusableRegion(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart));
inInactiveCode = false;
}
} else if (statement instanceof IASTPreprocessorElifStatement) {
IASTPreprocessorElifStatement elifStmt = (IASTPreprocessorElifStatement)statement;
if (!inInactiveCode && !elifStmt.taken()) {
IASTNodeLocation nodeLocation = elifStmt.getNodeLocations()[0];
inactiveCodeStart = nodeLocation.getNodeOffset();
inInactiveCode = true;
} else if (inInactiveCode && elifStmt.taken()) {
IASTNodeLocation nodeLocation = elifStmt.getNodeLocations()[0];
int inactiveCodeEnd = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
positions.add(new ReusableRegion(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart));
inInactiveCode = false;
}
} else if (statement instanceof IASTPreprocessorEndifStatement) {
IASTPreprocessorEndifStatement endifStmt = (IASTPreprocessorEndifStatement)statement;
if (inInactiveCode) {
IASTNodeLocation nodeLocation = endifStmt.getNodeLocations()[0];
int inactiveCodeEnd = nodeLocation.getNodeOffset() + nodeLocation.getNodeLength();
positions.add(new ReusableRegion(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart));
inInactiveCode = false;
}
}
}
if (inInactiveCode) {
IASTNodeLocation[] nodeLocations = translationUnit.getNodeLocations();
IASTNodeLocation lastNode = nodeLocations[nodeLocations.length - 1];
int inactiveCodeEnd = lastNode.getNodeOffset() + lastNode.getNodeLength();
positions.add(new ReusableRegion(inactiveCodeStart, inactiveCodeEnd - inactiveCodeStart));
inInactiveCode = false;
}
return positions;
}
/*
* @see org.eclipse.ui.texteditor.SourceViewerDecorationSupport#setCursorLinePainterPreferenceKeys(java.lang.String, java.lang.String)
*/
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;
}
}

View file

@ -16,20 +16,13 @@ import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration;
import org.eclipse.cdt.internal.ui.text.CTextTools;
import org.eclipse.cdt.internal.ui.text.ICColorConstants;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.utils.ui.controls.TabFolderLayout;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.Document; import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.RGB;
@ -50,26 +43,36 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil; import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.texteditor.AbstractTextEditor; import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.utils.ui.controls.TabFolderLayout;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration;
import org.eclipse.cdt.internal.ui.text.CTextTools;
import org.eclipse.cdt.internal.ui.text.ICColorConstants;
/* /*
* The page for setting the editor options. * The page for setting the editor options.
*/ */
public class CEditorPreferencePage extends AbstractPreferencePage implements IWorkbenchPreferencePage { public class CEditorPreferencePage extends AbstractPreferencePage implements IWorkbenchPreferencePage {
protected final String[][] fListModel = new String[][] { { PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.MultiLine"), ICColorConstants.C_MULTI_LINE_COMMENT }, { //$NON-NLS-1$ protected final String[][] fListModel = new String[][] { { PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.MultiLine"), ICColorConstants.C_MULTI_LINE_COMMENT }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.singleLine"), ICColorConstants.C_SINGLE_LINE_COMMENT }, { //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.singleLine"), ICColorConstants.C_SINGLE_LINE_COMMENT }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.keywords"), ICColorConstants.C_KEYWORD }, { //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.keywords"), ICColorConstants.C_KEYWORD }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.builtInTypes"), ICColorConstants.C_TYPE }, { //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.builtInTypes"), ICColorConstants.C_TYPE }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.strings"), ICColorConstants.C_STRING }, { //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.strings"), ICColorConstants.C_STRING }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.operators"), ICColorConstants.C_OPERATOR }, { //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.operators"), ICColorConstants.C_OPERATOR }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.braces"), ICColorConstants.C_BRACES }, { //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.braces"), ICColorConstants.C_BRACES }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.numbers"), ICColorConstants.C_NUMBER }, { //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.numbers"), ICColorConstants.C_NUMBER }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags.others"), ICColorConstants.C_DEFAULT }, { //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.others"), ICColorConstants.C_DEFAULT }, { //$NON-NLS-1$
PreferencesMessages.getString("CEditorPreferencePage.cCommentTaskTags"), PreferenceConstants.EDITOR_TASK_TAG_COLOR } //$NON-NLS-1$ PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.cCommentTaskTags"), PreferenceConstants.EDITOR_TASK_TAG_COLOR } //$NON-NLS-1$
}; };
protected final String[][] fAppearanceColorListModel = new String[][] { protected final String[][] fAppearanceColorListModel = new String[][] {
{PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.matchingBracketColor"), CEditor.MATCHING_BRACKETS_COLOR, null }, //$NON-NLS-1$ {PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.matchingBracketColor"), CEditor.MATCHING_BRACKETS_COLOR, null }, //$NON-NLS-1$
{PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.linkedPositionColor"), CEditor.LINKED_POSITION_COLOR, null }, //$NON-NLS-1$ {PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.inactiveCodeColor"), CEditor.INACTIVE_CODE_COLOR, null }, //$NON-NLS-1$
}; };
private CTextTools fCTextTools; private CTextTools fCTextTools;
@ -82,6 +85,12 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
private CEditorHoverConfigurationBlock fCEditorHoverConfigurationBlock; private CEditorHoverConfigurationBlock fCEditorHoverConfigurationBlock;
private FoldingConfigurationBlock fFoldingConfigurationBlock; private FoldingConfigurationBlock fFoldingConfigurationBlock;
private List fAppearanceColorList;
private ColorEditor fAppearanceColorEditor;
private Button fAppearanceColorDefault;
public CEditorPreferencePage() { public CEditorPreferencePage() {
super(); super();
@ -111,9 +120,10 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ICColorConstants.C_OPERATOR + "_bold")); //$NON-NLS-1$ overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ICColorConstants.C_OPERATOR + "_bold")); //$NON-NLS-1$
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, CEditor.MATCHING_BRACKETS_COLOR)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, CEditor.MATCHING_BRACKETS_COLOR));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CEditor.MATCHING_BRACKETS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CEditor.MATCHING_BRACKETS));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, CEditor.INACTIVE_CODE_COLOR));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CEditor.INACTIVE_CODE_ENABLE));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CEditor.SPACES_FOR_TABS)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CEditor.SPACES_FOR_TABS));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, CEditor.LINKED_POSITION_COLOR));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TASK_TAG_COLOR)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TASK_TAG_COLOR));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_TAG_BOLD)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, PreferenceConstants.EDITOR_TASK_TAG_BOLD));
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TASK_INDICATION_COLOR)); overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, PreferenceConstants.EDITOR_TASK_INDICATION_COLOR));
@ -140,6 +150,9 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
store.setDefault(CEditor.MATCHING_BRACKETS, true); store.setDefault(CEditor.MATCHING_BRACKETS, true);
PreferenceConverter.setDefault(store, CEditor.MATCHING_BRACKETS_COLOR, new RGB(170,170,170)); PreferenceConverter.setDefault(store, CEditor.MATCHING_BRACKETS_COLOR, new RGB(170,170,170));
store.setDefault(CEditor.INACTIVE_CODE_ENABLE, true);
PreferenceConverter.setDefault(store, CEditor.INACTIVE_CODE_COLOR, new RGB(224, 224, 224));
store.setDefault(CEditor.SPACES_FOR_TABS, false); store.setDefault(CEditor.SPACES_FOR_TABS, false);
PreferenceConverter.setDefault(store, ICColorConstants.C_MULTI_LINE_COMMENT, new RGB(63, 127, 95)); PreferenceConverter.setDefault(store, ICColorConstants.C_MULTI_LINE_COMMENT, new RGB(63, 127, 95));
@ -169,8 +182,6 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
PreferenceConverter.setDefault(store, ICColorConstants.C_NUMBER, new RGB(0, 0, 0)); PreferenceConverter.setDefault(store, ICColorConstants.C_NUMBER, new RGB(0, 0, 0));
store.setDefault(ICColorConstants.C_DEFAULT + "_bold", false); //$NON-NLS-1$ store.setDefault(ICColorConstants.C_DEFAULT + "_bold", false); //$NON-NLS-1$
PreferenceConverter.setDefault(store, CEditor.LINKED_POSITION_COLOR, new RGB(0, 200, 100));
} }
/* /*
@ -328,11 +339,117 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
String label = PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.matchingBrackets"); //$NON-NLS-1$ String label = PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.matchingBrackets"); //$NON-NLS-1$
addCheckBox(behaviorComposite, label, CEditor.MATCHING_BRACKETS, 0); addCheckBox(behaviorComposite, label, CEditor.MATCHING_BRACKETS, 0);
label = PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.inactiveCode"); //$NON-NLS-1$
addCheckBox(behaviorComposite, label, CEditor.INACTIVE_CODE_ENABLE, 0);
label = PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.tabSpace"); //$NON-NLS-1$ label = PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.tabSpace"); //$NON-NLS-1$
addCheckBox(behaviorComposite, label, CEditor.SPACES_FOR_TABS, 0); addCheckBox(behaviorComposite, label, CEditor.SPACES_FOR_TABS, 0);
Label l = new Label(behaviorComposite, SWT.LEFT);
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.horizontalSpan = 2;
gd.heightHint = convertHeightInCharsToPixels(1) / 2;
l.setLayoutData(gd);
l = new Label(behaviorComposite, SWT.LEFT);
l.setText(PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.appearanceColorOptions")); //$NON-NLS-1$
gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gd.horizontalSpan = 2;
l.setLayoutData(gd);
Composite editorComposite = new Composite(behaviorComposite, SWT.NONE);
layout = new GridLayout();
layout.numColumns = 2;
layout.marginHeight = 0;
layout.marginWidth = 0;
editorComposite.setLayout(layout);
gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.FILL_VERTICAL);
gd.horizontalSpan = 2;
editorComposite.setLayoutData(gd);
fAppearanceColorList = new List(editorComposite, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER);
gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
gd.heightHint = convertHeightInCharsToPixels(8);
fAppearanceColorList.setLayoutData(gd);
Composite stylesComposite = new Composite(editorComposite, SWT.NONE);
layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.numColumns = 2;
stylesComposite.setLayout(layout);
stylesComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
l = new Label(stylesComposite, SWT.LEFT);
l.setText(PreferencesMessages.getString("CEditorPreferencePage.behaviorPage.Color")); //$NON-NLS-1$
gd = new GridData();
gd.horizontalAlignment = GridData.BEGINNING;
l.setLayoutData(gd);
fAppearanceColorEditor = new ColorEditor(stylesComposite);
Button foregroundColorButton = fAppearanceColorEditor.getButton();
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment = GridData.BEGINNING;
foregroundColorButton.setLayoutData(gd);
SelectionListener colorDefaultSelectionListener= new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
boolean systemDefault= fAppearanceColorDefault.getSelection();
fAppearanceColorEditor.getButton().setEnabled(!systemDefault);
int i= fAppearanceColorList.getSelectionIndex();
String key= fAppearanceColorListModel[i][2];
if (key != null)
fOverlayStore.setValue(key, systemDefault);
}
};
fAppearanceColorDefault= new Button(stylesComposite, SWT.CHECK);
fAppearanceColorDefault.setText(PreferencesMessages.getString("CEditorPreferencePage.colorPage.systemDefault")); //$NON-NLS-1$
gd= new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalAlignment= GridData.BEGINNING;
gd.horizontalSpan= 2;
fAppearanceColorDefault.setLayoutData(gd);
fAppearanceColorDefault.setVisible(false);
fAppearanceColorDefault.addSelectionListener(colorDefaultSelectionListener);
fAppearanceColorList.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
handleAppearanceColorListSelection();
}
});
foregroundColorButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
int i = fAppearanceColorList.getSelectionIndex();
String key = fAppearanceColorListModel[i][1];
PreferenceConverter.setValue(fOverlayStore, key, fAppearanceColorEditor.getColorValue());
}
});
return behaviorComposite; return behaviorComposite;
} }
private void handleAppearanceColorListSelection() {
int i = fAppearanceColorList.getSelectionIndex();
String key = fAppearanceColorListModel[i][1];
RGB rgb = PreferenceConverter.getColor(fOverlayStore, key);
fAppearanceColorEditor.setColorValue(rgb);
updateAppearanceColorWidgets(fAppearanceColorListModel[i][2]);
}
private void updateAppearanceColorWidgets(String systemDefaultKey) {
if (systemDefaultKey == null) {
fAppearanceColorDefault.setSelection(false);
fAppearanceColorDefault.setVisible(false);
fAppearanceColorEditor.getButton().setEnabled(true);
} else {
boolean systemDefault= fOverlayStore.getBoolean(systemDefaultKey);
fAppearanceColorDefault.setSelection(systemDefault);
fAppearanceColorDefault.setVisible(true);
fAppearanceColorEditor.getButton().setEnabled(!systemDefault);
}
}
private Control createHeader(Composite parent) { private Control createHeader(Composite parent) {
String text = PreferencesMessages.getString("CEditorPreferencePage.link"); //$NON-NLS-1$ String text = PreferencesMessages.getString("CEditorPreferencePage.link"); //$NON-NLS-1$
Link link = new Link(parent, SWT.NONE); Link link = new Link(parent, SWT.NONE);
@ -392,6 +509,16 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
initializeFields(); initializeFields();
for (int i = 0; i < fAppearanceColorListModel.length; i++) {
fAppearanceColorList.add(fAppearanceColorListModel[i][0]);
}
fAppearanceColorList.getDisplay().asyncExec(new Runnable() {
public void run() {
fAppearanceColorList.select(0);
handleAppearanceColorListSelection();
}
});
for (int i = 0; i < fListModel.length; i++) { for (int i = 0; i < fListModel.length; i++) {
fList.add(fListModel[i][0]); fList.add(fListModel[i][0]);
} }

View file

@ -59,8 +59,6 @@ TodoTaskInputDialog.error.comma=Name cannot contain a comma.
TodoTaskInputDialog.error.entryExists=Entry with the same name already exists. TodoTaskInputDialog.error.entryExists=Entry with the same name already exists.
TodoTaskInputDialog.error.noSpace=Name can not start or end with a whitespace. TodoTaskInputDialog.error.noSpace=Name can not start or end with a whitespace.
CEditorPreferencePage.cCommentTaskTags=Task Tags
CEditorPreferencePage.link=Note that some preferences may be set on the <a href="org.eclipse.ui.preferencePages.GeneralTextEditor">Text Editors</a> preference page. CEditorPreferencePage.link=Note that some preferences may be set on the <a href="org.eclipse.ui.preferencePages.GeneralTextEditor">Text Editors</a> preference page.
CEditorPreferencePage.generalTabTitle=Appeara&nce CEditorPreferencePage.generalTabTitle=Appeara&nce
CEditorPreferencePage.annotationTabTitle= &Annotations CEditorPreferencePage.annotationTabTitle= &Annotations
@ -91,20 +89,16 @@ CEditorPreferencePage.ContentAssistPage.completionProposalForegroundColor=&Foreg
CEditorPreferencePage.ContentAssistPage.parameterBackgroundColor=Bac&kground for method parameters: CEditorPreferencePage.ContentAssistPage.parameterBackgroundColor=Bac&kground for method parameters:
CEditorPreferencePage.ContentAssistPage.parameterForegroundColor=Fo&reground for method parameters: CEditorPreferencePage.ContentAssistPage.parameterForegroundColor=Fo&reground for method parameters:
CEditorPreferencePage.ContentAssistPage.autoActivationEnableDoubleColon=Enable "::" as trigger CEditorPreferencePage.ContentAssistPage.autoActivationEnableDoubleColon=Enable "::" as trigger
CEditorPreferencePage.cCommentTaskTags.MultiLine=Multi-line comment CEditorPreferencePage.syntaxPage.MultiLine=Multi-line comment
CEditorPreferencePage.cCommentTaskTags.singleLine=Single-line comment CEditorPreferencePage.syntaxPage.singleLine=Single-line comment
CEditorPreferencePage.cCommentTaskTags.keywords=Keywords CEditorPreferencePage.syntaxPage.keywords=Keywords
CEditorPreferencePage.cCommentTaskTags.builtInTypes=Built-in types CEditorPreferencePage.syntaxPage.builtInTypes=Built-in types
CEditorPreferencePage.cCommentTaskTags.strings=Strings CEditorPreferencePage.syntaxPage.strings=Strings
CEditorPreferencePage.cCommentTaskTags.operators=Operators CEditorPreferencePage.syntaxPage.operators=Operators
CEditorPreferencePage.cCommentTaskTags.braces=Braces CEditorPreferencePage.syntaxPage.braces=Braces
CEditorPreferencePage.cCommentTaskTags.numbers=Numbers CEditorPreferencePage.syntaxPage.numbers=Numbers
CEditorPreferencePage.cCommentTaskTags.others=Others CEditorPreferencePage.syntaxPage.others=Others
CEditorPreferencePage.annotationsPage.presentationOptions=Annotation Presentation Options CEditorPreferencePage.syntaxPage.cCommentTaskTags=Task Tags
CEditorPreferencePage.annotationsPage.showInText=Show In Text
CEditorPreferencePage.annotationsPage.showInOverview=Show In Overview Ruler
CEditorPreferencePage.annotationsPage.showInVertical=Show In Vertical Ruler
CEditorPreferencePage.annotationsPage.color=Annotations Color
CEditorPreferencePage.colorPage.backgroundColor=Bac&kground Color: CEditorPreferencePage.colorPage.backgroundColor=Bac&kground Color:
CEditorPreferencePage.colorPage.systemDefault=S&ystem Default CEditorPreferencePage.colorPage.systemDefault=S&ystem Default
CEditorPreferencePage.colorPage.custom=C&ustom CEditorPreferencePage.colorPage.custom=C&ustom
@ -112,30 +106,14 @@ CEditorPreferencePage.colorPage.foreground=Fo&reground:
CEditorPreferencePage.colorPage.color=C&olor: CEditorPreferencePage.colorPage.color=C&olor:
CEditorPreferencePage.colorPage.bold=&Bold CEditorPreferencePage.colorPage.bold=&Bold
CEditorPreferencePage.colorPage.preview=Preview: CEditorPreferencePage.colorPage.preview=Preview:
CEditorPreferencePage.behaviorPage.textFont=Text &font:
CEditorPreferencePage.behaviorPage.tabWidth=Displayed &tab width:
CEditorPreferencePage.behaviorPage.marginColumn=Print m&argin column:
CEditorPreferencePage.behaviorPage.tabSpace=&Insert space for tabs CEditorPreferencePage.behaviorPage.tabSpace=&Insert space for tabs
CEditorPreferencePage.behaviorPage.matchingBrackets=Highlight &matching brackets CEditorPreferencePage.behaviorPage.matchingBrackets=Highlight &matching brackets
CEditorPreferencePage.behaviorPage.highlightLine=&Highlight current line CEditorPreferencePage.behaviorPage.inactiveCode=Highlight &inactive code
CEditorPreferencePage.behaviorPage.printMargin=Show &print margin CEditorPreferencePage.behaviorPage.appearanceColorOptions=Appearance color options:
CEditorPreferencePage.behaviorPage.showLineNumbers=Show &line numbers CEditorPreferencePage.behaviorPage.matchingBracketColor=Matching brackets highlight
CEditorPreferencePage.behaviorPage.showOverviewRuler=Show &overview ruler CEditorPreferencePage.behaviorPage.inactiveCodeColor=Inactive code highlight
CEditorPreferencePage.behaviorPage.appearanceColorOptions=Appearance color options
CEditorPreferencePage.behaviorPage.lineNumberColor=Line number foreground
CEditorPreferencePage.behaviorPage.matchingBracketColor=Matching bracket highlight
CEditorPreferencePage.behaviorPage.currentLineHighlightColor=Current line highlight
CEditorPreferencePage.behaviorPage.printMarginColor=Print margin
CEditorPreferencePage.behaviorPage.linkedPositionColor=HyperLink
CEditorPreferencePage.behaviorPage.selectionForegroundColor=Selection foreground
CEditorPreferencePage.behaviorPage.selectionBackgroundColor=Selection background
CEditorPreferencePage.behaviorPage.systemDefault=System Default
CEditorPreferencePage.accessibility.disableCustomCarets= &Use custom caret
CEditorPreferencePage.accessibility.wideCaret= Enable thic&k caret
CEditorPreferencePage.behaviorPage.Color=Color: CEditorPreferencePage.behaviorPage.Color=Color:
CEditorPreferencePage.textFont.changeButton=C&hange... CEditorPreferencePage.textFont.changeButton=C&hange...
CEditorPreferencePage.Navigation=Navigation
CEditorPreferencePage.Enable_Hyperlink_Navigation=Enable Hyperlink Navigation
TemplatePreferencePage.Viewer.preview=Preview: TemplatePreferencePage.Viewer.preview=Preview:

View file

@ -168,7 +168,7 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
scanner = fTextTools.getCppCodeScanner(); scanner = fTextTools.getCppCodeScanner();
} else if (language instanceof GCCLanguage) { } else if (language instanceof GCCLanguage) {
scanner = fTextTools.getCCodeScanner(); scanner = fTextTools.getCCodeScanner();
} else { } else if (language != null) {
ILanguageUI languageUI = (ILanguageUI)language.getAdapter(ILanguageUI.class); ILanguageUI languageUI = (ILanguageUI)language.getAdapter(ILanguageUI.class);
if (languageUI != null) if (languageUI != null)
scanner = languageUI.getCodeScanner(); scanner = languageUI.getCodeScanner();