/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package org.python.pydev.django_templates.editor; import java.util.ArrayList; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.jface.text.presentation.PresentationReconciler; import org.eclipse.jface.text.rules.DefaultDamagerRepairer; import org.eclipse.jface.text.rules.IPredicateRule; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.ITokenScanner; import org.eclipse.jface.text.rules.RuleBasedScanner; import org.eclipse.jface.text.rules.SingleLineRule; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.templates.Template; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.python.pydev.core.docutils.StringUtils; import org.python.pydev.django_templates.IDjConstants; import org.python.pydev.django_templates.completions.DjContentAssistProcessor; import org.python.pydev.django_templates.completions.templates.DjContextType; import org.python.pydev.django_templates.completions.templates.TemplateHelper; import org.python.pydev.editor.PyCodeScanner; import org.python.pydev.plugin.preferences.PydevPrefs; import org.python.pydev.ui.ColorAndStyleCache; import com.aptana.editor.common.AbstractThemeableEditor; import com.aptana.editor.common.CommonUtil; import com.aptana.editor.common.IPartitioningConfiguration; import com.aptana.editor.common.ISourceViewerConfiguration; import com.aptana.editor.common.text.rules.ISubPartitionScanner; import com.aptana.editor.common.text.rules.SubPartitionScanner; /** * @author Fabio Zadrozny */ public abstract class DjSourceConfiguration implements IPartitioningConfiguration, ISourceViewerConfiguration { protected static final String SOURCE_DJ = "source.dj"; protected static final String STRING_QUOTED_DOUBLE_DJ = "string.quoted.double.dj"; protected static final String STRING_QUOTED_SINGLE_DJ = "string.quoted.single.dj"; protected static final String COMMENT_DJ = "comment.dj"; public final static String PREFIX = "__dj_"; public final static String DEFAULT = "__dj" + IDocument.DEFAULT_CONTENT_TYPE; public final static String STRING_SINGLE = PREFIX + "string_single"; public final static String STRING_DOUBLE = PREFIX + "string_double"; public final static String COMMENT = PREFIX + "comment"; public static final String[] CONTENT_TYPES = new String[] { DEFAULT, STRING_SINGLE, STRING_DOUBLE, COMMENT }; protected static final String[][] TOP_CONTENT_TYPES = new String[][] { { IDjConstants.CONTENT_TYPE_DJANGO_HTML } }; protected IPredicateRule[] partitioningRules = new IPredicateRule[] { new SingleLineRule("\"", "\"", getToken(STRING_DOUBLE), '\\'), new SingleLineRule("\'", "\'", getToken(STRING_SINGLE), '\\'), new SingleLineRule("{#", "#}", getToken(COMMENT)) }; private String contentType; public DjSourceConfiguration(String contentType) { this.contentType = contentType; } /** * @see com.aptana.editor.common.IPartitioningConfiguration#getContentTypes() */ public String[] getContentTypes() { return CONTENT_TYPES; } /* * (non-Javadoc) * * @see * com.aptana.editor.common.ITopContentTypesProvider#getTopContentTypes() */ public String[][] getTopContentTypes() { return TOP_CONTENT_TYPES; } /** * @see com.aptana.editor.common.IPartitioningConfiguration#getPartitioningRules() */ public IPredicateRule[] getPartitioningRules() { return partitioningRules; } /** * @see com.aptana.editor.common.IPartitioningConfiguration#createSubPartitionScanner() */ public ISubPartitionScanner createSubPartitionScanner() { return new SubPartitionScanner(partitioningRules, CONTENT_TYPES, getToken(DEFAULT)); } /* * (non-Javadoc) * * @see com.aptana.editor.common.IPartitioningConfiguration# * getDocumentDefaultContentType() */ public String getDocumentContentType(String contentType) { if (contentType.startsWith(PREFIX)) { return this.contentType; } return null; } /** * @see com.aptana.editor.common.ISourceViewerConfiguration#setupPresentationReconciler(org.eclipse.jface.text.presentation.PresentationReconciler, * org.eclipse.jface.text.source.ISourceViewer) */ public void setupPresentationReconciler(PresentationReconciler reconciler, ISourceViewer sourceViewer) { DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getCodeScanner()); reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); reconciler.setDamager(dr, DEFAULT); reconciler.setRepairer(dr, DEFAULT); dr = new DefaultDamagerRepairer(getSingleQuotedStringScanner()); reconciler.setDamager(dr, DjSourceConfiguration.STRING_SINGLE); reconciler.setRepairer(dr, DjSourceConfiguration.STRING_SINGLE); dr = new DefaultDamagerRepairer(getDoubleQuotedStringScanner()); reconciler.setDamager(dr, DjSourceConfiguration.STRING_DOUBLE); reconciler.setRepairer(dr, DjSourceConfiguration.STRING_DOUBLE); dr = new DefaultDamagerRepairer(getCommentScanner()); reconciler.setDamager(dr, DjSourceConfiguration.COMMENT); reconciler.setRepairer(dr, DjSourceConfiguration.COMMENT); } /* (non-Javadoc) * @see com.aptana.editor.common.ISourceViewerConfiguration#getContentAssistProcessor(com.aptana.editor.common.AbstractThemeableEditor, java.lang.String) */ public IContentAssistProcessor getContentAssistProcessor(AbstractThemeableEditor editor, String contentType) { return new DjContentAssistProcessor(contentType, null); } public PyCodeScanner getCodeScanner() { PyCodeScanner codeScanner = new PyCodeScanner(getColorCache(), getKeywordsFromTemplates()); return codeScanner; } public String[] getKeywordsFromTemplates() { Template[] templates = TemplateHelper.getTemplateStore().getTemplates( DjContextType.DJ_TAGS_COMPLETIONS_CONTEXT_TYPE); ArrayList<String> templateNames = new ArrayList<String>(); for (Template template : templates) { String name = template.getName(); if (StringUtils.containsWhitespace(name)) { continue; } templateNames.add(name); } String[] keywords = templateNames.toArray(new String[templateNames.size()]); return keywords; } protected ITokenScanner getSingleQuotedStringScanner() { RuleBasedScanner singleQuotedStringScanner = new RuleBasedScanner(); singleQuotedStringScanner.setDefaultReturnToken(getToken(STRING_QUOTED_SINGLE_DJ)); return singleQuotedStringScanner; } protected ITokenScanner getCommentScanner() { RuleBasedScanner commentScanner = new RuleBasedScanner(); commentScanner.setDefaultReturnToken(getToken(COMMENT_DJ)); return commentScanner; } protected ITokenScanner getDoubleQuotedStringScanner() { RuleBasedScanner doubleQuotedStringScanner = new RuleBasedScanner(); doubleQuotedStringScanner.setDefaultReturnToken(getToken(STRING_QUOTED_DOUBLE_DJ)); return doubleQuotedStringScanner; } protected static IToken getToken(String tokenName) { return CommonUtil.getToken(tokenName); } protected ColorAndStyleCache colorCache; public ColorAndStyleCache getColorCache() { if (colorCache == null) { IPreferenceStore prefStore = PydevPrefs.getChainedPrefStore(); colorCache = new ColorAndStyleCache(prefStore); prefStore.addPropertyChangeListener(new IPropertyChangeListener() { public void propertyChange(PropertyChangeEvent event) { String property = event.getProperty(); if (ColorAndStyleCache.isColorOrStyleProperty(property)) { colorCache.reloadNamedColor(property); updateSyntaxColorAndStyle(); } } }); } return colorCache; } public void updateSyntaxColorAndStyle() { this.getCodeScanner().updateColors(); } }