Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
editor.GosuStyleContext Maven / Gradle / Ivy
/*
*
* Copyright 2010 Guidewire Software, Inc.
*
*/
package editor;
import editor.util.EditorUtilities;
import editor.util.Pair;
import gw.lang.parser.ISourceCodeTokenizer;
import gw.lang.parser.exceptions.ParseWarningForDeprecatedMember;
import gw.util.GosuObjectUtil;
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.Segment;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.TabExpander;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.WrappedPlainView;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A collection of styles used to render gosu source.
*/
public class GosuStyleContext extends StyleContext implements ViewFactory
{
public static final int KEY_WORD = -99;
public static final int PARSE_ERROR = -98;
public static final int DEPRECATED = -97;
public static final int PARSE_WARNING = -96;
public static final int TYPE_LITERAL = -95;
public static final int NESTED_TYPE_LITERAL = -94;
public static final int METHOD_CALL = -93;
public static final int USES = -92;
public static final int DEFAULT = -91;
public static final int FIELD_ERROR = -90;
public static final int FIELD_WARNING = -89;
public static final int PACKAGE = -88;
public static final int PROPERTY = -87;
public static final int ENHANCEMENT_METHOD_CALL = -86;
public static final int ENHANCEMENT_PROPERTY = -85;
public static final Integer KEY_WORD_KEY = new Integer( KEY_WORD );
public static final Integer PARSE_ERROR_KEY = new Integer( PARSE_ERROR );
public static final Integer DEPRECATED_KEY = new Integer( DEPRECATED );
public static final Integer TYPE_LITERAL_KEY = new Integer( TYPE_LITERAL );
public static final Integer NESTED_TYPE_LITERAL_KEY = new Integer( NESTED_TYPE_LITERAL );
public static final Integer PARSE_WARNING_KEY = new Integer( PARSE_WARNING );
public static final Integer METHOD_CALL_KEY = new Integer( METHOD_CALL );
public static final Integer PROPERTY_KEY = new Integer( PROPERTY );
public static final Integer ENHANCEMENT_METHOD_CALL_KEY = new Integer( ENHANCEMENT_METHOD_CALL );
public static final Integer ENHANCEMENT_PROPERTY_KEY = new Integer( ENHANCEMENT_PROPERTY );
public static final Integer USES_KEY = new Integer( USES );
public static final Integer PACKAGE_KEY = new Integer( PACKAGE );
public static final Integer FIELD_ERROR_KEY = new Integer( FIELD_ERROR );
public static final Integer FIELD_WARNING_KEY = new Integer( FIELD_WARNING );
public static final String DASHED = "_dashed";
private static final Component THISISSTUPID = new Component()
{
};
//private static String g_defFontFamily = EditorUtilities.getFontFamilyOrDefault( "Consolas", "Monospaced" );
private static String g_defFontFamily = EditorUtilities.getFontFamilyOrDefault( "Monospaced", "Monospaced" );
private static int g_defFontSize = 12;
public static final String STYLE_EOL = "EOL";
public static final String STYLE_EOF = "EOF";
public static final String STYLE_Whitespace = "Whitespace";
public static final String STYLE_Comment = "Comment";
public static final String STYLE_Caret = "Caret";
public static final String STYLE_Number = "Number";
public static final String STYLE_Integer = "Integer";
public static final String STYLE_Word = "Word";
public static final String STYLE_Operator = "Operator";
public static final String STYLE_StringLiteral = "StringLiteral";
public static final String STYLE_KeyWord = "KeyWord";
public static final String STYLE_ParseError = "ParseError";
public static final String STYLE_ParseWarning = "ParseWarning";
public static final String STYLE_DeprecatedMember = "DeprecatedMember";
public static final String STYLE_TypeLiteral = "ITypeLiteralExpression";
public static final String STYLE_NestedTypeLiteral = "NestedTypeLiteral";
public static final String STYLE_MethodCall = "MethodCall";
public static final String STYLE_Property = "Property";
public static final String STYLE_EnhancementMethodCall = "EnhancementMethodCall";
public static final String STYLE_EnhancementProperty = "EnhancementProperty";
public static final String STYLE_FieldError = "FieldError";
public static final String STYLE_FieldWarning = "FieldWarning";
private String _strFontFamily;
private int _iFontSize;
private HashMap _fontCache;
private HashMap _tokenStyles;
/**
* Constructs a set of styles to represent gosu lexical tokens.
*/
public GosuStyleContext()
{
super();
Style root = getStyle( DEFAULT_STYLE );
_tokenStyles = new HashMap<>();
_tokenStyles.put( new Integer( ISourceCodeTokenizer.TT_EOL ), addStyle( STYLE_EOL, root ) );
_tokenStyles.put( new Integer( ISourceCodeTokenizer.TT_EOF ), addStyle( STYLE_EOF, root ) );
_tokenStyles.put( new Integer( ISourceCodeTokenizer.TT_WHITESPACE ), addStyle( STYLE_Whitespace, root ) );
_tokenStyles.put( new Integer( ISourceCodeTokenizer.TT_COMMENT ), addStyle( STYLE_Comment, root ) );
_tokenStyles.put( new Integer( ISourceCodeTokenizer.TT_NUMBER ), addStyle( STYLE_Number, root ) );
_tokenStyles.put( new Integer( ISourceCodeTokenizer.TT_INTEGER ), addStyle( STYLE_Integer, root ) );
_tokenStyles.put( new Integer( ISourceCodeTokenizer.TT_WORD ), addStyle( STYLE_Word, root ) );
_tokenStyles.put( new Integer( ISourceCodeTokenizer.TT_OPERATOR ), addStyle( STYLE_Operator, root ) );
_tokenStyles.put( new Integer( (int)'"' ), addStyle( STYLE_StringLiteral, root ) );
_tokenStyles.put( (int)'\'', addStyle( STYLE_StringLiteral, root ) );
_tokenStyles.put( KEY_WORD_KEY, addStyle( STYLE_KeyWord, root ) );
_tokenStyles.put( PARSE_ERROR_KEY, addStyle( STYLE_ParseError, root ) );
_tokenStyles.put( PARSE_WARNING_KEY, addStyle( STYLE_ParseWarning, root ) );
_tokenStyles.put( DEPRECATED_KEY, addStyle( STYLE_DeprecatedMember, root ) );
_tokenStyles.put( TYPE_LITERAL_KEY, addStyle( STYLE_TypeLiteral, root ) );
_tokenStyles.put( NESTED_TYPE_LITERAL_KEY, addStyle( STYLE_NestedTypeLiteral, root ) );
_tokenStyles.put( METHOD_CALL_KEY, addStyle( STYLE_MethodCall, root ) );
_tokenStyles.put( PROPERTY_KEY, addStyle( STYLE_Property, root ) );
_tokenStyles.put( ENHANCEMENT_METHOD_CALL_KEY, addStyle( STYLE_EnhancementMethodCall, root ) );
_tokenStyles.put( ENHANCEMENT_PROPERTY_KEY, addStyle( STYLE_EnhancementProperty, root ) );
_tokenStyles.put( FIELD_ERROR_KEY, addStyle( STYLE_FieldError, root ) );
_tokenStyles.put( FIELD_WARNING_KEY, addStyle( STYLE_FieldWarning, root ) );
addStyle( STYLE_Caret, root );
_strFontFamily = g_defFontFamily;
_iFontSize = g_defFontSize;
_fontCache = new HashMap<>();
setDefaultStyles();
}
public void setForeground( Style style, Color colorFore )
{
setAttribute( style, StyleConstants.Foreground, colorFore );
}
public void setBackground( Style style, Color colorBack )
{
setAttribute( style, StyleConstants.Background, colorBack );
}
public void setBold( Style style, boolean bBold )
{
setAttribute( style, StyleConstants.Bold, bBold );
}
public void setItalic( Style style, boolean bItalic )
{
setAttribute( style, StyleConstants.Italic, bItalic );
}
public void setUnderline( Style style, boolean bUnderline )
{
setAttribute( style, StyleConstants.Underline, bUnderline );
}
public void setStrikeThrough( Style style, boolean bStrikeThrough )
{
setAttribute( style, StyleConstants.StrikeThrough, bStrikeThrough );
}
public void setAttribute( Style style, Object attr, Object value )
{
Style defStyle = getStyle( DEFAULT_STYLE );
if( defStyle == style )
{
style.addAttribute( attr, value );
for( Enumeration> names = getStyleNames(); names.hasMoreElements(); )
{
Style csr = getStyle( (String)names.nextElement() );
if( csr != defStyle &&
GosuObjectUtil.equals( csr.getAttribute( attr ), value ) )
{
// Remove attr for child attrs having same value
csr.removeAttribute( attr );
}
}
return;
}
Object defValue = defStyle.getAttribute( attr );
if( GosuObjectUtil.equals( defValue, value ) )
{
style.removeAttribute( attr );
}
else
{
style.addAttribute( attr, value );
}
}
public void setDefaultStyles()
{
boolean bAllowBold = true;
// Default
Style style = getStyle( DEFAULT_STYLE );
setBackground( style, Scheme.active().getCodeWindow() );
setForeground( style, Scheme.active().getCodeWindowText() );
// Caret
// style = getStyle( STYLE_Caret );
// Whitespace
// style = getStyleForScanValue( SourceCodeTokenizer.TT_WHITESPACE );
// Comments
style = getStyleForScanValue( ISourceCodeTokenizer.TT_COMMENT );
setForeground( style, Scheme.active().getCodeComment() );
setItalic( style, true );
// EOL (same as Comment... to handle multiline comments)
style = getStyleForScanValue( ISourceCodeTokenizer.TT_EOL );
setForeground( style, Scheme.active().getCodeMultilineComment() );
setItalic( style, true );
// EOF (same as Comment... to handle multiline comments)
style = getStyleForScanValue( ISourceCodeTokenizer.TT_EOF );
setForeground( style, Scheme.active().getCodeMultilineComment() );
setItalic( style, true );
// String Literals
style = getStyleForScanValue( (int)'"' );
setForeground( style, Scheme.active().getCodeStringLiteral() );
setBold( style, bAllowBold );
// Number Literals
style = getStyleForScanValue( ISourceCodeTokenizer.TT_NUMBER );
setForeground( style, Scheme.active().getCodeNumberLiteral() );
// Integer Literals
style = getStyleForScanValue( ISourceCodeTokenizer.TT_INTEGER );
setForeground( style, Scheme.active().getCodeNumberLiteral() );
// Non-key Words (identifiers and bean member access paths)
// style = getStyleForScanValue( ISourceCodeTokenizer.TT_WORD );
// Key Words
style = getStyleForScanValue( GosuStyleContext.KEY_WORD );
setForeground( style, Scheme.active().getCodeKeyword() );
setBold( style, bAllowBold );
// Parse Errors
style = getStyleForScanValue( GosuStyleContext.PARSE_ERROR );
setForeground( style, Scheme.active().getCodeError() );
// Parse Warnings
style = getStyleForScanValue( GosuStyleContext.PARSE_WARNING );
setForeground( style, Scheme.active().getCodeWarning() );
setUnderline( style, true );
// Deprecated Member
style = getStyleForScanValue( GosuStyleContext.DEPRECATED );
setForeground( style, Scheme.active().getCodeDeprecated() );
setStrikeThrough( style, true );
// Operators
style = getStyleForScanValue( ISourceCodeTokenizer.TT_OPERATOR );
setForeground( style, Scheme.active().getCodeOperator() );
setBold( style, bAllowBold );
// Type Literals
style = getStyleForScanValue( GosuStyleContext.TYPE_LITERAL );
setForeground( style, Scheme.active().getCodeTypeLiteral() );
setBold( style, bAllowBold );
// Type Literals (namespaces and type-parameters)
style = getStyleForScanValue( GosuStyleContext.NESTED_TYPE_LITERAL );
setForeground( style, Scheme.active().getCodeTypeLiteralNested() );
// Type Literals (namespaces and type-parameters)
style = getStyleForScanValue( GosuStyleContext.FIELD_ERROR );
setBackground( style, new Color( 255, 230, 230 ) );
// Type Literals (namespaces and type-parameters)
style = getStyleForScanValue( GosuStyleContext.FIELD_WARNING );
setBackground( style, new Color( 254, 251, 94 ) );
}
public static void setDefaultFontFamily( String defFontFamily )
{
g_defFontFamily = defFontFamily;
}
public static String getDefaultFontFamily()
{
return g_defFontFamily;
}
public static void setDefaultFontSize( int defFontSize )
{
g_defFontSize = defFontSize;
}
public static int getDefaultFontSize()
{
return g_defFontSize;
}
/**
* Fetch the foreground color to use for a lexical token with the given value.
*/
public Color getForeground( int code )
{
Style s = _tokenStyles.get( new Integer( code ) );
if( s == null )
{
s = getStyle( DEFAULT_STYLE );
}
return getForeground( s );
}
public Color getBackground( int code )
{
Style s = _tokenStyles.get( new Integer( code ) );
if( s == null )
{
s = getStyle( DEFAULT_STYLE );
}
return getBackground( s );
}
/**
* Fetch the font to use for a lexical token with the given scan value.
*/
public Font getFont( int code )
{
Style s = _tokenStyles.get( new Integer( code ) );
if( s == null )
{
s = getStyle( DEFAULT_STYLE );
}
return getFont( s );
}
/**
* Fetches the attribute set to use for the given scan code. The set is
* stored in a table to facilitate relatively fast access to use in
* conjunction with the scanner.
*/
public Style getStyleForScanValue( int code )
{
Style s = _tokenStyles.get( new Integer( code ) );
if( s == null )
{
s = getStyle( DEFAULT_STYLE );
}
return s;
}
/**
* Fetch the font to use for a given attribute set.
*/
@Override
public Font getFont( AttributeSet attr )
{
boolean bUnderline = StyleConstants.isUnderline( attr );
boolean bStrikethrough = StyleConstants.isStrikeThrough( attr );
if( !bUnderline && !bStrikethrough )
{
// StyleContext ignores the Underline and Strikethrough attribute
return getFont( attr, getFontFamily( attr ) );
}
// Must build the font via TextAttribute map to support Underlined and Strikethrough text
Map map = new HashMap();
map.put( TextAttribute.FAMILY, getFontFamily( attr ) );
map.put( TextAttribute.SIZE, (float)getFontSize() );
map.put( TextAttribute.WEIGHT, StyleConstants.isBold( attr ) ? TextAttribute.WEIGHT_BOLD : TextAttribute.WEIGHT_REGULAR );
map.put( TextAttribute.POSTURE, StyleConstants.isItalic( attr ) ? TextAttribute.POSTURE_OBLIQUE : TextAttribute.POSTURE_REGULAR );
if( bUnderline )
{
map.put( TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON );
if( attr.getAttribute( DASHED ) != null )
{
map.put( TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_LOW_GRAY );
}
}
if( bStrikethrough )
{
map.put( TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON );
}
Font font = _fontCache.get( attr );
if( font == null )
{
font = new Font( map );
_fontCache.put( attr, font );
}
return font;
}
private Font getFont( AttributeSet attr, String strFamily )
{
int iStyle = Font.PLAIN;
if( StyleConstants.isBold( attr ) )
{
iStyle |= Font.BOLD;
}
if( StyleConstants.isItalic( attr ) )
{
iStyle |= Font.ITALIC;
}
int iSize = getFontSize();
// If either superscript or subscript is is set, we need to reduce the font
// size by 2.
if( StyleConstants.isSuperscript( attr ) ||
StyleConstants.isSubscript( attr ) )
{
iSize -= 2;
}
return getFont( strFamily, iStyle, iSize );
}
public String getFontFamily( AttributeSet a )
{
String strFamily = (String)a.getAttribute( StyleConstants.FontFamily );
if( strFamily == null )
{
strFamily = getFontFamily();
}
return strFamily;
}
public String getFontFamily()
{
return _strFontFamily;
}
public void setFontFamily( String strFamily )
{
_strFontFamily = strFamily;
_fontCache.clear();
}
public int getFontSize()
{
return _iFontSize;
}
public void setFontSize( int iSize )
{
_iFontSize = iSize;
_fontCache.clear();
}
//----------------------------------------------------------------------------------------------
//-- ViewFactory methods --
@Override
public View create( Element elem )
{
return new GosuSourceView( elem );
}
public List