Code Search for Developers
 
 
  

PovClipseHoverPresenter.java from PovClipse at Krugle


Show PovClipseHoverPresenter.java syntax highlighted

/*
 * PovClipse - Eclipse plugin for editing and rendering Povray sceene files.
 * Copyright (C) 2006-2007  Wolfgang Moestl  wmoestl@web.de
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

package com.wm.povclipse.common;

import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.DefaultInformationControl.IInformationPresenter;
import org.eclipse.jface.text.DefaultInformationControl.IInformationPresenterExtension;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Drawable;
import org.eclipse.swt.widgets.Display;

import com.wm.povclipse.editors.scanners.PovrayStringScanner;
import com.wm.povclipse.i18n.I18nCommon;
import com.wm.povclipse.preferences.PovrayPreferenceConstants;
import com.wm.povclipse.preferences.PovrayPreferences;
import com.wm.povclipse.validator.FloatValidator;

/**
 * <code>IInformationPresenter</code> used by text hovers.
 * 
 * @author Wolfgang Mouml;stl
 */
public class PovClipseHoverPresenter implements IInformationPresenter,
		IInformationPresenterExtension {

	public static final int HOVER_TYPE_COLOR_MAP	= 6;
	public static final int HOVER_TYPE_COLOR 		= 5;
	public static final int HOVER_TYPE_DECLARATION 	= 4;
	public static final int HOVER_TYPE_INCLUDE 		= 3;
	public static final int HOVER_TYPE_MACRO   		= 2;
	public static final int HOVER_TYPE_CODE    		= 1;
	public static final int HOVER_TYPE_DEFAULT 		= 0;
	
	private Color colKeywordCommon;
	private Color colString;
	private Color colBracketGeschweift;
	private Color colBracketSpitz;
	private Color colComment;
	private Color colColor;
	private Color colGradient;
	private Color colMath;
	private Color colModifier;
	private Color colObject;
	private Color colTexture;
	private Color colNumber;
	
	private Color colIncludeHoverFile;
	private Color colIncludeHoverMacro;
	private Color colIncludeHoverDecl;
	private Color colIncludeHoverFileLight;
	private Color colIncludeHoverMacroLight;
	private Color colIncludeHoverDeclLight;
	
	private PovrayStringScanner stringScanner;
	
	/**
	 * Construcotr reading the colors from the preference store.
	 */
	public PovClipseHoverPresenter(PovrayStringScanner stringScanner) {
		this.stringScanner = stringScanner;
		PovrayPreferences prefs = PovrayPreferences.getInstance();
		
		colBracketGeschweift 	= prefs.getColor(PovrayPreferenceConstants.P_COLOR_BRACE);
		colBracketSpitz 		= prefs.getColor(PovrayPreferenceConstants.P_COLOR_ANGLE_BRACKET);
		colComment 				= prefs.getColor(PovrayPreferenceConstants.P_COLOR_COMMENT);
		colColor 				= prefs.getColor(PovrayPreferenceConstants.P_COLOR_KEYWORD_COLOR);
		colKeywordCommon 		= prefs.getColor(PovrayPreferenceConstants.P_COLOR_KEYWORD_COMMON);
		colGradient 			= prefs.getColor(PovrayPreferenceConstants.P_COLOR_KEYWORD_GRADIENT);
		colMath 				= prefs.getColor(PovrayPreferenceConstants.P_COLOR_KEYWORD_MATH);
		colModifier 			= prefs.getColor(PovrayPreferenceConstants.P_COLOR_KEYWORD_MODIFIER);
		colObject 				= prefs.getColor(PovrayPreferenceConstants.P_COLOR_KEYWORD_OBJECT);
		colTexture 				= prefs.getColor(PovrayPreferenceConstants.P_COLOR_KEYWORD_TEXTURE);
		colNumber 				= prefs.getColor(PovrayPreferenceConstants.P_COLOR_NUMBER);
		colString 				= prefs.getColor(PovrayPreferenceConstants.P_COLOR_STRING);
		
		colIncludeHoverFile  = new Color(colString.getDevice(), 190, 0  , 0  );
		colIncludeHoverMacro = new Color(colString.getDevice(), 0  , 190, 0  );
		colIncludeHoverDecl  = new Color(colString.getDevice(), 0  , 0  , 190);
		
		colIncludeHoverFileLight  = new Color(colString.getDevice(), 190, 150, 150);
		colIncludeHoverMacroLight = new Color(colString.getDevice(), 150, 190, 150);
		colIncludeHoverDeclLight  = new Color(colString.getDevice(), 150, 150, 190);
	}
	
	/**
	 * Default implemtation, not uased by the framework as this
	 * class implements <code>IInformationPresenterExtension</code> as well!
	 * @see org.eclipse.jface.text.DefaultInformationControl$IInformationPresenter#updatePresentation(org.eclipse.swt.widgets.Display, java.lang.String, org.eclipse.jface.text.TextPresentation, int, int)
	 */
	public String updatePresentation(Display display, String hoverInfo,
			TextPresentation presentation, int maxWidth, int maxHeight) {
		return hoverInfo;
	}

	/**
	 * @see org.eclipse.jface.text.DefaultInformationControl$IInformationPresenterExtension#updatePresentation(org.eclipse.swt.graphics.Drawable, java.lang.String, org.eclipse.jface.text.TextPresentation, int, int)
	 */
	public String updatePresentation(Drawable drawable, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
		int hoverType = getHoverType(hoverInfo);
		hoverInfo = getStrippedHoverMessage(hoverInfo);
		
		switch (hoverType) {
			case HOVER_TYPE_MACRO:
				presentation.clear();
				createMacroStyling(presentation, hoverInfo);			
				break;
			case HOVER_TYPE_CODE:
				presentation.clear();
				createCodeStyling(presentation, hoverInfo);				
				break;
			case HOVER_TYPE_INCLUDE:
				presentation.clear();
				createIncludeStyling(presentation, hoverInfo);				
				break;
			case HOVER_TYPE_DECLARATION:
				presentation.clear();
				createDeclarationStyling(presentation, hoverInfo);				
				break;
			default: /* no styles added */ break;
		}
				
		return hoverInfo;
	}
	
	/**
	 * Creates the presentation styling for '#macro' hovers
	 * @param presentation The <code>TextPresentation</code> to receive the styling
	 * @param message The complete hover text.
	 */
	private void createMacroStyling(TextPresentation presentation, String message) {
		int index = message.indexOf("#macro");			
		// '#macro' is italic and in the color used by common keywords
		presentation.addStyleRange(new StyleRange(index, 6, colKeywordCommon, null, SWT.ITALIC | SWT.BOLD));
		
		int indexStart = message.indexOf('(');
		if (indexStart >= index + 6) {
			// the macro name is bold
			presentation.addStyleRange(new StyleRange(index+6, indexStart-(index+6), null, null, SWT.BOLD));
			
			int indexEnd = message.indexOf(')', indexStart);
			if (indexEnd == -1) {
				indexEnd = message.indexOf('\n', indexStart);
				if (indexEnd == -1)
					indexEnd = message.length()-1;
			}
			// parameters are drawn bold and in the color used by string literals.
			styleCommaSeparatedList(presentation, message, indexStart, indexEnd, colString, null, SWT.BOLD);
			
			// the rest is drawn using the comment color
			presentation.addStyleRange(new StyleRange(indexEnd+1, message.length()-(indexEnd+1), colComment, null, SWT.NORMAL));
		}	
	}
	
	/**
	 * Creates the presentation styling for 'declaration' hovers
	 * @param presentation The <code>TextPresentation</code> to receive the styling
	 * @param message The complete hover text.
	 */
	private void createDeclarationStyling(TextPresentation presentation, String message) {
		createCodeStyling(presentation, message, message.indexOf("#declare"));
	}
	
	/**
	 * Creates the presentation styling for 'include' hovers
	 * @param presentation The <code>TextPresentation</code> to receive the styling
	 * @param message The complete hover text.
	 */
	private void createIncludeStyling(TextPresentation presentation, String message) {
		boolean highlightMode = false;
		int separatorIndex = 0;
		int lineStart = 0;
		for (int i=0; i<message.length(); i++) {
			char c = message.charAt(i);
			
			if (c == ':' && false == highlightMode) {
				highlightMode = true;
				separatorIndex = i+1;
			} else if (c == '\n') {
				if (highlightMode) {
					setIncludePresentation(presentation, message, lineStart, separatorIndex, i);
				}
				highlightMode = false;
				lineStart = i+1;
			}
		}
		// the last line
		if (highlightMode) {
			setIncludePresentation(presentation, message, lineStart, separatorIndex, message.length());
		}
	}
	
	private void setIncludePresentation(TextPresentation presentation, String message, int start, int separator, int end) {
		String prefix = message.substring(start, separator-1).trim();
		boolean isIndirect = message.substring(separator, end).trim().endsWith("*");
		
		Color col = isIndirect ? colIncludeHoverFileLight : colIncludeHoverFile;
		if (I18nCommon.macro.indexOf(prefix) >= 0)
			col = isIndirect ? colIncludeHoverMacroLight : colIncludeHoverMacro;
		else if (I18nCommon.declaration.indexOf(prefix) >= 0)
			col = isIndirect ? colIncludeHoverDeclLight : colIncludeHoverDecl;
		
		presentation.addStyleRange(new StyleRange(start, separator-start, col, null, SWT.ITALIC));
		presentation.addStyleRange(new StyleRange(separator+1, end-separator-1, col, null, SWT.BOLD));
		
	}
	
	/**
	 * Creates the presentation styling for 'code-folding' hovers
	 * @param presentation The <code>TextPresentation</code> to receive the styling
	 * @param message The complete hover text.
	 */
	private void createCodeStyling(TextPresentation presentation, String message) {
		createCodeStyling(presentation, message, 0);
	}
	
	/**
	 * Creates the presentation styling for 'code-folding' hovers
	 * @param presentation The <code>TextPresentation</code> to receive the styling
	 * @param message The complete hover text.
	 */
	private void createCodeStyling(TextPresentation presentation, String message, int switchIndex) {
		if (switchIndex < 0)
			switchIndex = 0;
		
		if (switchIndex > 0)
			presentation.addStyleRange(new StyleRange(0, switchIndex, colComment, null, SWT.NORMAL));
		
		StringBuffer sb = new StringBuffer();
		char c;
		for (int i=switchIndex; i<message.length(); i++) {
			c = message.charAt(i);
			if (Character.isLetterOrDigit(c) ||
				c == '_' ||
				c == '.' ||
				c == '-' ||
				c == '"' ||
				c == '\'') {
					sb.append(c);	
			} else if (c == '{' || c == '}') {
				sb = processStringBuffer(presentation, sb, i-1 - sb.length());
				presentation.addStyleRange(new StyleRange(i, 1, colBracketGeschweift, null, SWT.NORMAL));
			} else if (c == '<' || c == '>') {
				sb = processStringBuffer(presentation, sb, i-1 - sb.length());
				presentation.addStyleRange(new StyleRange(i, 1, colBracketSpitz, null, SWT.NORMAL));
			} else {
				// whitespace or similar
				if (sb.length() > 0) {
									
					sb = processStringBuffer(presentation, sb, i - sb.length());
				} // else do nothing at all
			}
		}
	}
	
	/**
	 * Adds a <code>StyleRange</code> to the <code>presentation</code> if necessary.<br>
	 * If <code>sb</code> can be parsed into a number (US-style), a <code>StyleRange</code> for numbers is applied.<br>
	 * If <code>sb</code> starts end ends either with &quot; or ', a <code>StyleRange</code> for strings is applied.<br>
	 * If <code>sb</code> sb can be found in the list of known keywords, a <code>StyleRange</code> for the specific keyword group is applied.<br>
	 * Else no <code>StyleRange</code> is added.
	 * @param presentation The <code>TextPresentation</code> to receive the <code>StyleRange</code>.
	 * @param sb The <code>StringBuffer</code> to be processed.
	 * @param indexFrom The index of the given <code>StringBuffer</code> within the processing message.
	 * @return A new, fresh, clear instance of a <code>StringBuffer</code>.
	 */
	private StringBuffer processStringBuffer(TextPresentation presentation, StringBuffer sb, int indexFrom) {
		if (sb.length() > 0) {
			
			// is it a number?
			if (FloatValidator.isNumber(sb.toString())) {
				presentation.addStyleRange(new StyleRange(indexFrom, sb.length(), colNumber, null, SWT.NORMAL));
				sb = new StringBuffer();
			} 
			// is it a string?
			else if ((sb.charAt(0) == '"' && sb.charAt(sb.length()-1) == '"') ||
					   (sb.charAt(0) == '\'' && sb.charAt(sb.length()-1) == '\'')) {
				presentation.addStyleRange(new StyleRange(indexFrom, sb.length(), colString, null, SWT.NORMAL));
				sb = new StringBuffer();
			} 
			// ceck the keyword lists
			else {					
				Color col = getKeywordColor(sb.toString());
				if (null != col) {
					presentation.addStyleRange(new StyleRange(indexFrom, sb.length(), col, null, SWT.NORMAL));				
				}
			}
		}	
		return new StringBuffer();
	}
	
	
	/**
	 * @param keyword The word to be searched within the list of known keywords.
	 * @return If the given word can be foundn in the list of known keywords the color
	 * for the specific keyword group is returned, otherwise <code>null</code>.
	 */
	private Color getKeywordColor(String word) {
		if (arrayContainsKeyword(stringScanner.getKeywordsColor(), word))
			return colColor;
		if (arrayContainsKeyword(stringScanner.getKeywordsCommon(), word))
				return colKeywordCommon;
		if (arrayContainsKeyword(stringScanner.getKeywordsGradient(), word))
				return colGradient;
		if (arrayContainsKeyword(stringScanner.getKeywordsMath(), word))
				return colMath;
		if (arrayContainsKeyword(stringScanner.getKeywordsModifier(), word))
				return colModifier;
		if (arrayContainsKeyword(stringScanner.getKeywordsObjects(), word))
				return colObject;
		if (arrayContainsKeyword(stringScanner.getKeywordsTexture(), word))
				return colTexture;
					
		return null;
	}
	
	/**
	 * @param array The array to be checked.
	 * @param keyword The keyword to be searched for
	 * @return <code>true</code> if the array contains the keyword,
	 * <code>false</code> otherwise.
	 */
	private boolean arrayContainsKeyword(String[] array, String keyword) {
		for (int i=0; i<array.length; i++) {
			if (array[i].equals(keyword)) return true;
		}
		return false;
	}
	

	/**
	 * Gets the hover type usingthe hover message.
	 * @param msg The hover message including the ttype prefix.
	 * @return One of the <code>HOVER_TYPE_*</code> constants. If the
	 * <code>msg</code> is null or the type is either unknown or not set 
	 * <code>HOVER_TYPE_DEFAULT</code> is returned.
	 */
	public static int getHoverType(String msg) {
		if (null == msg) return HOVER_TYPE_DEFAULT;
		
		int index = msg.indexOf(PovClipseMessageTypeIndication.TYPE_DELIMETER);
		if (index == -1)
			return HOVER_TYPE_DEFAULT;
		else {
			if (PovClipseMessageTypeIndication.TYPE_MACRO.equals(msg.substring(0, PovClipseMessageTypeIndication.TYPE_MACRO.length())))
				return HOVER_TYPE_MACRO;
			else if (PovClipseMessageTypeIndication.TYPE_CODE.equals(msg.substring(0, PovClipseMessageTypeIndication.TYPE_CODE.length())))
				return HOVER_TYPE_CODE;
			else if (PovClipseMessageTypeIndication.TYPE_INCLUDE.equals(msg.substring(0, PovClipseMessageTypeIndication.TYPE_INCLUDE.length())))
				return HOVER_TYPE_INCLUDE;			
			else if (PovClipseMessageTypeIndication.TYPE_DECLARATION.equals(msg.substring(0, PovClipseMessageTypeIndication.TYPE_DECLARATION.length())))
				return HOVER_TYPE_DECLARATION;			
			else if (PovClipseMessageTypeIndication.TYPE_COLOR.equals(msg.substring(0, PovClipseMessageTypeIndication.TYPE_COLOR.length())))
				return HOVER_TYPE_COLOR;			
			else if (PovClipseMessageTypeIndication.TYPE_COLOR_MAP.equals(msg.substring(0, PovClipseMessageTypeIndication.TYPE_COLOR_MAP.length())))
				return HOVER_TYPE_COLOR_MAP;			
			else
				return HOVER_TYPE_DEFAULT;
		}
	}
	
	/**
	 * Checks whether the hover message belongs to a color or not.
	 * @param msg The message to be processed.
	 * @return <code>true</code> it the message belongs to a color hover.
	 */
	public static boolean isHoverTypeColor(String msg) {
		return HOVER_TYPE_COLOR == getHoverType(msg);
	}
	
	/**
	 * Checks whether the hover message belongs to a color_map or not.
	 * @param msg The message to be processed.
	 * @return <code>true</code> it the message belongs to a color_map hover.
	 */
	public static boolean isHoverTypeColorMap(String msg) {
		return HOVER_TYPE_COLOR_MAP == getHoverType(msg);
	}
	
	/**
	 * Checks whether the hover message belongs to a macro or not.
	 * @param msg The message to be processed.
	 * @return <code>true</code> it the message belongs to a macro hover.
	 */
	public static boolean isHoverTypeMacro(String msg) {
		return HOVER_TYPE_MACRO == getHoverType(msg);
	}
	
	/**
	 * Checks whether the hover message belongs to a code-folding or not.
	 * @param msg The message to be processed.
	 * @return <code>true</code> it the message belongs to a code-folding hover.
	 */
	public static boolean isHoverTypeCode(String msg) {
		return HOVER_TYPE_CODE == getHoverType(msg);
	}
	
	/**
	 * Checks whether the hover message belongs to a include statement or not.
	 * @param msg The message to be processed.
	 * @return <code>true</code> it the message belongs to a include hover.
	 */
	public static boolean isHoverTypeInclude(String msg) {
		return HOVER_TYPE_INCLUDE == getHoverType(msg);
	}
	
	/**
	 * Checks whether the hover message belongs to a declare statement or not.
	 * @param msg The message to be processed.
	 * @return <code>true</code> it the message belongs to a declare hover.
	 */
	public static boolean isHoverTypeDeclaration(String msg) {
		return HOVER_TYPE_DECLARATION == getHoverType(msg);
	}
	
	
	/**
	 * Gets the extra information stored between the <code>TYPE</code> information
	 * and the <code>TYPE_DELIMETER</code>.
	 * @param msg The message to be processed.
	 * @return See above.
	 */
	public static String getExtraInfo(String msg) {
		int type = getHoverType(msg);
		if (type == HOVER_TYPE_DEFAULT) return "";
		
		int index = msg.indexOf(PovClipseMessageTypeIndication.TYPE_DELIMETER);
		if (index == -1) return "";
		
		if (type == HOVER_TYPE_MACRO) {
			return msg.substring(PovClipseMessageTypeIndication.TYPE_MACRO.length(),index);
		} 
		if (type == HOVER_TYPE_DECLARATION) {
			return msg.substring(PovClipseMessageTypeIndication.TYPE_DECLARATION.length(),index);
		}
		
		return "";
	}
	
	public static String getStrippedHoverMessage(String msg) {
		int index = msg.indexOf(PovClipseMessageTypeIndication.TYPE_DELIMETER);
		if (index == -1)
			return msg;
		else
			return msg.substring(index + PovClipseMessageTypeIndication.TYPE_DELIMETER.length());
	}
	
	/**
	 * Adds a new <code>StyleRange</code> for each comma separated entry found
	 * in the given string between the start and end position. 
	 * @param presentation The <code>TextPresentation</code> object to
	 * receive the styled ranges.
	 * @param msg The message to be processed
	 * @param start The start position of the comma separated list
	 * @param end The end position of the comma separated list
	 * @param foregroundColor The foreground color to be used or <code>NULL</code> to use the default color.
	 * @param backgroundColor The backround color to be used or <code>NULL</code> to use the default color.
	 * @param style The text style bits, <code>SWT.NORMAL</code>, <code>SWT.ITALIC</code> or <code>SWT.BOLD</code>.
	 */
	private void styleCommaSeparatedList(TextPresentation presentation, String msg, int start, int end, Color foregroundColor, Color backgroundColor, int style) {
		
		int indexLastComma = start;
		int indexComma = msg.indexOf(',', indexLastComma);
		if (indexComma == -1) { // only 1 parameter, no list!
			presentation.addStyleRange(new StyleRange(start+1, end-start-1, foregroundColor, backgroundColor, style));
		}
		else {
			while (indexComma > -1 && indexComma <= end && indexLastComma < indexComma) {
				// add the style
				presentation.addStyleRange(new StyleRange(indexLastComma+1, indexComma-indexLastComma-1, foregroundColor, backgroundColor, style));
				
				indexLastComma = indexComma; 
				indexComma = msg.indexOf(',', indexLastComma+1);
				if (indexComma > end)
					indexComma = end;
				
				// handle the last list entry
				if (indexComma == -1) {
					presentation.addStyleRange(new StyleRange(indexLastComma+1, end-indexLastComma-1, foregroundColor, backgroundColor, style));						
				}
			}
		}
	}

}




See more files for this project here

PovClipse

PovClipse is an eclipse editor plugin for Povray (Persistence of Vision Raytracer) sceene- and include files.\r\nIt features syntax highlighting, code folding, code assist, outline view as well as running Povray using render configurations.

Project homepage: http://sourceforge.net/projects/povclipse
Programming language(s): Java
License: other

  ColorManager.java
  Formatter.java
  IPovrayColorConstants.java
  MessageData.java
  PovClipseHoverPresenter.java
  PovClipseMessageTypeIndication.java