1 19 20 package org.netbeans.modules.languages.features; 21 22 import java.util.List ; 23 import java.util.ListIterator ; 24 import java.util.Set ; 25 import javax.swing.text.AttributeSet ; 26 import javax.swing.text.StyleConstants ; 27 import java.awt.*; 28 import java.util.Iterator ; 29 import javax.swing.text.Document ; 30 import org.netbeans.api.languages.ASTItem; 31 import org.netbeans.api.languages.Highlighting; 32 import org.netbeans.api.languages.LanguagesManager; 33 import org.netbeans.api.languages.ParseException; 34 import org.netbeans.api.languages.ASTPath; 35 import org.netbeans.api.languages.ASTToken; 36 import org.netbeans.api.languages.Context; 37 import org.netbeans.api.editor.settings.EditorStyleConstants; 38 import org.netbeans.api.languages.SyntaxContext; 39 import org.netbeans.api.lexer.Token; 40 import org.netbeans.api.lexer.TokenSequence; 41 import org.netbeans.editor.DrawContext; 42 import org.netbeans.editor.DrawLayer; 43 import org.netbeans.editor.MarkFactory; 44 import org.netbeans.modules.editor.NbEditorDocument; 45 import org.netbeans.api.languages.ASTNode; 46 import org.netbeans.api.languages.ParseException; 47 import org.netbeans.api.languages.ASTToken; 48 import org.netbeans.api.lexer.TokenHierarchy; 49 import org.netbeans.modules.languages.Language; 50 import org.netbeans.modules.languages.LanguagesManagerImpl; 51 import org.netbeans.modules.languages.ParserManagerImpl; 52 53 57 public class MyFirstDrawLayer implements DrawLayer { 58 59 private String mimeType; 60 private Highlighting highlighting; 61 62 63 64 public MyFirstDrawLayer (String mimeType) { 65 this.mimeType = mimeType; 66 } 67 68 public String getName () { 69 return getClass ().getName (); 70 } 71 72 public boolean extendsEOL () { 73 return false; 74 } 75 76 public boolean extendsEmptyLine () { 77 return false; 78 } 79 80 public int getNextActivityChangeOffset (DrawContext ctx) { 81 return nextActivityChangeOffset; 82 } 83 84 public void init (DrawContext ctx) { 85 highlighting = Highlighting.getHighlighting 86 (ctx.getEditorUI ().getDocument ()); 87 } 88 89 public int updateLineNumberContext (int lineNumber, DrawContext ctx) { 90 return lineNumber; 91 } 92 93 public String toString () { 94 return "Layer " + getClass (); } 96 97 public boolean isActive (DrawContext ctx, MarkFactory.DrawMark mark) { 98 setNextActivityChangeOffset (ctx.getTokenOffset () + ctx.getTokenLength ()); 99 return true; 100 } 101 102 public void updateContext (DrawContext ctx) { 103 NbEditorDocument doc = (NbEditorDocument) ctx.getEditorUI ().getDocument (); 104 105 ASTNode ast = null; 106 try { 107 ast = ParserManagerImpl.get (doc).getAST (); 108 } catch (ParseException ex) { 109 ast = ex.getASTNode (); 110 } 111 if (ast == null) { 112 markToken (ctx, doc); 113 return; 114 } 115 ASTPath path = ast.findPath (ctx.getFragmentOffset ()); 116 if (path == null) { 117 markToken (ctx, doc); 118 return; 119 } 120 121 boolean isTrailing = isTrailing (path, ctx.getFragmentOffset ()); 122 ASTNode splitNode = isTrailing ? splitNode (path) : null; 123 int i, k = path.size (); 124 for ( i = 0; i < k; i++) { 125 ASTItem item = path.get (i); 126 if (isTrailing && splitNode == item) { 127 break; 128 } 129 try { 130 Language language = ((LanguagesManagerImpl) LanguagesManager.getDefault ()). 131 getLanguage (item.getMimeType ()); 132 AttributeSet as = null; 133 List <AttributeSet > colors = ColorsManager.getColors (language, path.subPath (i), doc); 134 if (colors != null) { 136 for (Iterator <AttributeSet > it = colors.iterator (); it.hasNext ();) { 137 as = it.next (); 138 apply (as, ctx); 139 } 140 } 141 as = highlighting.get (item); 142 if (as != null) 143 apply (as, ctx); 144 } catch (ParseException ex) { 145 } 146 } 147 } 148 149 private static boolean isTrailing (ASTPath path, int offset) { 150 try { 151 if (path.size () < 2 || 152 !(path.get (path.size () - 2) instanceof ASTNode) 153 ) 154 return false; 155 ASTNode lastNode = (ASTNode) path.get (path.size () - 2); 156 Language language = ((LanguagesManagerImpl) LanguagesManager.getDefault ()). 157 getLanguage (lastNode.getMimeType ()); 158 Set skipTokens = language.getSkipTokenTypes(); 159 if (!(path.getLeaf () instanceof ASTToken)) { 160 return false; 162 } 163 ASTToken leaf = (ASTToken) path.getLeaf (); 164 ASTNode split = null; 165 if (!skipTokens.contains (leaf.getType ())) 166 return false; 167 split = (ASTNode) path.getRoot(); 168 int size = path.size (); 169 List <ASTItem> list = lastNode.getChildren (); 170 for (ListIterator <ASTItem> iter = list.listIterator (list.size ()); iter.hasPrevious (); ) { 171 ASTItem item = iter.previous (); 172 if (item == leaf) 173 return true; 174 if (!(item instanceof ASTToken) || 175 !skipTokens.contains (((ASTToken) item).getType ()) 176 ) 177 break; 178 } } catch (ParseException ex) { 180 } 181 return false; 182 } 183 184 private static ASTNode splitNode (ASTPath path) { 185 Iterator iter = path.listIterator (); 186 Object o = iter.next(); 187 while (o instanceof ASTNode) { 188 List children = ((ASTNode)o).getChildren (); 189 o = iter.next(); 190 if (!(o instanceof ASTNode)) { 191 break; 192 } 193 if (children.get (children.size () - 1) != o) { 194 return (ASTNode) o; 195 } 196 } return null; 198 } 199 200 private void markToken (DrawContext ctx, Document doc) { 201 TokenHierarchy hierarchy = TokenHierarchy.get (doc); 202 TokenSequence ts = hierarchy.tokenSequence (); 203 AttributeSet as = null; 204 do { 205 ts.move (ctx.getFragmentOffset ()); 206 ts.moveNext (); 207 Token t = ts.token (); 208 if (t == null) return; 209 ASTToken stoken = ASTToken.create ( 210 ts.language ().mimeType (), 211 t.id ().name (), 212 t.text ().toString (), 213 ts.offset () 214 ); 215 as = highlighting.get (stoken); 216 ts = ts.embedded (); 217 } while (as == null && ts != null); 218 if (as != null) 219 apply (as, ctx); 220 } 221 222 225 private int nextActivityChangeOffset = Integer.MAX_VALUE; 226 227 private void setNextActivityChangeOffset (int nextActivityChangeOffset) { 228 this.nextActivityChangeOffset = nextActivityChangeOffset; 229 } 230 231 private static void apply (AttributeSet as, DrawContext ctx) { 232 Color c = (Color) as.getAttribute (StyleConstants.Background); 233 if (c != null) ctx.setBackColor (c); 234 c = (Color) as.getAttribute (StyleConstants.Foreground); 235 if (c != null) ctx.setForeColor (c); 236 c = (Color) as.getAttribute (StyleConstants.StrikeThrough); 237 if (c != null) ctx.setStrikeThroughColor (c); 238 c = (Color) as.getAttribute (StyleConstants.Underline); 239 if (c != null) ctx.setUnderlineColor (c); 240 c = (Color) as.getAttribute (EditorStyleConstants.WaveUnderlineColor); 241 if (c != null) ctx.setWaveUnderlineColor (c); 242 String fontName = (String ) as.getAttribute (StyleConstants.FontFamily); 243 Boolean bold = (Boolean ) as.getAttribute (StyleConstants.Bold); 244 Boolean italic = (Boolean ) as.getAttribute (StyleConstants.Italic); 245 if (fontName != null || bold != null || italic != null) { 246 Font f = ctx.getFont (); 247 if (fontName == null) fontName = f.getFamily (); 248 if (bold == null) bold = f.isBold () ? Boolean.TRUE : Boolean.FALSE; 249 if (italic == null) italic = f.isItalic () ? Boolean.TRUE : Boolean.FALSE; 250 f = new Font ( 251 fontName, 252 (bold.booleanValue () ? Font.BOLD : 0) + 253 (italic.booleanValue () ? Font.ITALIC : 0), 254 f.getSize () 255 ); 256 ctx.setFont (f); 257 } 258 } 259 } 260 261 262 | Popular Tags |