/** * 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.debug.newconsole.prefs; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; import org.eclipse.jface.text.TextAttribute; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; import org.python.pydev.core.ExtensionHelper; import org.python.pydev.core.docutils.StringUtils; import org.python.pydev.debug.core.PydevDebugPlugin; import org.python.pydev.debug.newconsole.PydevConsoleConstants; import org.python.pydev.plugin.preferences.IPydevPreferencesProvider; /** * Generic color manager. */ public class ColorManager { private static ColorManager fgColorManager; /** * Singleton */ private ColorManager() { } public static ColorManager getDefault() { if (fgColorManager == null) { fgColorManager = new ColorManager(); } return fgColorManager; } /** * Cache for colors */ protected Map<RGB, Color> fColorTable = new HashMap<RGB, Color>(10); public static final RGB dimBlack = new RGB(0.00f, 0.00f, 0.00f); public static final RGB dimRed = new RGB(0.000f, 1.000f, 0.502f); public static final RGB dimGreen = new RGB(0.333f, 1.000f, 0.502f); public static final RGB dimYellow = new RGB(0.167f, 1.000f, 0.502f); public static final RGB dimBlue = new RGB(0.667f, 1.000f, 0.502f); public static final RGB dimMagenta = new RGB(0.833f, 1.000f, 0.502f); public static final RGB dimCyan = new RGB(0.500f, 1.000f, 0.502f); public static final RGB dimWhite = new RGB(0.000f, 0.000f, 0.753f); public static final RGB brightBlack = new RGB(0.000f, 0.000f, 0.502f); public static final RGB brightRed = new RGB(0.000f, 1.000f, 1.000f); public static final RGB brightGreen = new RGB(0.333f, 1.000f, 1.000f); public static final RGB brightYellow = new RGB(0.167f, 1.000f, 1.000f); public static final RGB brightBlue = new RGB(0.667f, 1.000f, 1.000f); public static final RGB brightMagenta = new RGB(0.833f, 1.000f, 1.000f); public static final RGB brightCyan = new RGB(0.500f, 1.000f, 1.000f); public static final RGB brightWhite = new RGB(0.000f, 0.000f, 1.000f); /** * Receives a string such as: * * <ESC>[{attr1};...;{attrn}m * * Where {attr1}...{attrn} are numbers so that: * * Foreground Colors * 30 Black * 31 Red * 32 Green * 33 Yellow * 34 Blue * 35 Magenta * 36 Cyan * 37 White * * Background Colors * 40 Black * 41 Red * 42 Green * 43 Yellow * 44 Blue * 45 Magenta * 46 Cyan * 47 White * * If 0;30 is received, it means a 'dim' version of black, if 1;30 is received, it means a 'bright' version is used. * * If [0m is received, the attributes are reset (and null may be returned in this case). * * Reference: http://graphcomp.com/info/specs/ansi_col.html */ public TextAttribute getAnsiTextAttribute(String str, TextAttribute prevAttribute, TextAttribute resetAttribute) { if (str.startsWith("[")) { str = str.substring(1); } int foundM = str.indexOf('m'); if (foundM == -1) { return prevAttribute; } str = str.substring(0, foundM); if (str.equals("0")) { return resetAttribute; } boolean bright = false; Color foreground = null; Color background = null; List<String> split = StringUtils.split(str, ';'); for (String string : split) { try { int parsed = Integer.parseInt(string); switch (parsed) { case 0: bright = false; break; case 1: bright = true; break; case 30:// Black foreground = getColor(bright ? brightBlack : dimBlack); break; case 31:// Red foreground = getColor(bright ? brightRed : dimRed); break; case 32:// Green foreground = getColor(bright ? brightGreen : dimGreen); break; case 33:// Yellow foreground = getColor(bright ? brightYellow : dimYellow); break; case 34:// Blue foreground = getColor(bright ? brightBlue : dimBlue); break; case 35:// Magenta foreground = getColor(bright ? brightMagenta : dimMagenta); break; case 36:// Cyan foreground = getColor(bright ? brightCyan : dimCyan); break; case 37:// White foreground = getColor(bright ? brightWhite : dimWhite); break; case 40:// Black background = getColor(bright ? brightBlack : dimBlack); break; case 41:// Red background = getColor(bright ? brightRed : dimRed); break; case 42:// Green background = getColor(bright ? brightGreen : dimGreen); break; case 43:// Yellow background = getColor(bright ? brightYellow : dimYellow); break; case 44:// Blue background = getColor(bright ? brightBlue : dimBlue); break; case 45:// Magenta background = getColor(bright ? brightMagenta : dimMagenta); break; case 46:// Cyan background = getColor(bright ? brightCyan : dimCyan); break; case 47:// White background = getColor(bright ? brightWhite : dimWhite); break; default: break; } } catch (NumberFormatException e) { //ignore } } return new TextAttribute(foreground != null ? foreground : prevAttribute.getForeground(), background != null ? background : prevAttribute.getBackground(), prevAttribute.getStyle()); } public Color getColor(RGB rgb) { Color color = fColorTable.get(rgb); if (color == null) { color = new Color(Display.getCurrent(), rgb); fColorTable.put(rgb, color); } return color; } public void dispose() { Iterator<Color> e = fColorTable.values().iterator(); while (e.hasNext()) e.next().dispose(); } /** * * @param type: see constants at {@link PydevConsoleConstants} * @return a color to be used. */ private Color getPreferenceColor(String type) { PydevDebugPlugin plugin = PydevDebugPlugin.getDefault(); if (plugin == null) { return null; } IPreferenceStore preferenceStore = plugin.getPreferenceStore(); return getColor(PreferenceConverter.getColor(preferenceStore, type)); } //Note that to update the code below, the install.py of this plugin should be run. /*[[[cog import cog template = ''' @SuppressWarnings("unchecked") public TextAttribute get%sTextAttribute() { List<IPydevPreferencesProvider> participants = ExtensionHelper.getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { TextAttribute textAttribute = iPydevPreferencesProvider.get%sTextAttribute(); if(textAttribute != null){ return textAttribute; } } Color color = getPreferenceColor(PydevConsoleConstants.%s_COLOR); return new TextAttribute(color, null, 0); }''' for s in ( 'console_error', 'console_output', 'console_input', 'console_prompt'): cog.outl(template % (s.title().replace('_', ''), s.title().replace('_', ''), s.upper())) ]]]*/ @SuppressWarnings("unchecked") public TextAttribute getConsoleErrorTextAttribute() { List<IPydevPreferencesProvider> participants = ExtensionHelper .getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { TextAttribute textAttribute = iPydevPreferencesProvider.getConsoleErrorTextAttribute(); if (textAttribute != null) { return textAttribute; } } Color color = getPreferenceColor(PydevConsoleConstants.CONSOLE_ERROR_COLOR); return new TextAttribute(color, null, 0); } @SuppressWarnings("unchecked") public TextAttribute getConsoleOutputTextAttribute() { List<IPydevPreferencesProvider> participants = ExtensionHelper .getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { TextAttribute textAttribute = iPydevPreferencesProvider.getConsoleOutputTextAttribute(); if (textAttribute != null) { return textAttribute; } } Color color = getPreferenceColor(PydevConsoleConstants.CONSOLE_OUTPUT_COLOR); return new TextAttribute(color, null, 0); } @SuppressWarnings("unchecked") public TextAttribute getConsoleInputTextAttribute() { List<IPydevPreferencesProvider> participants = ExtensionHelper .getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { TextAttribute textAttribute = iPydevPreferencesProvider.getConsoleInputTextAttribute(); if (textAttribute != null) { return textAttribute; } } Color color = getPreferenceColor(PydevConsoleConstants.CONSOLE_INPUT_COLOR); return new TextAttribute(color, null, 0); } @SuppressWarnings("unchecked") public TextAttribute getConsolePromptTextAttribute() { List<IPydevPreferencesProvider> participants = ExtensionHelper .getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { TextAttribute textAttribute = iPydevPreferencesProvider.getConsolePromptTextAttribute(); if (textAttribute != null) { return textAttribute; } } Color color = getPreferenceColor(PydevConsoleConstants.CONSOLE_PROMPT_COLOR); return new TextAttribute(color, null, 0); } //[[[end]]] @SuppressWarnings("unchecked") public Color getConsoleBackgroundColor() { List<IPydevPreferencesProvider> participants = ExtensionHelper .getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { RGB textAttribute = iPydevPreferencesProvider.getConsoleBackgroundRGB(); if (textAttribute != null) { return getColor(textAttribute); } } Color color = getPreferenceColor(PydevConsoleConstants.CONSOLE_BACKGROUND_COLOR); return color; } /** * Default background color for debug console is set to light gray so that * the user is able to quickly differentiate between a REPL window and the * existing console window * * @return */ @SuppressWarnings("unchecked") public Color getDebugConsoleBackgroundColor() { List<IPydevPreferencesProvider> participants = ExtensionHelper .getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { RGB textAttribute = iPydevPreferencesProvider.getConsoleBackgroundRGB(); if (textAttribute != null) { return getColor(textAttribute); } } Color color = getPreferenceColor(PydevConsoleConstants.DEBUG_CONSOLE_BACKGROUND_COLOR); return color; } @SuppressWarnings("unchecked") public TextAttribute getHyperlinkTextAttribute() { List<IPydevPreferencesProvider> participants = ExtensionHelper .getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { TextAttribute textAttribute = iPydevPreferencesProvider.getHyperlinkTextAttribute(); if (textAttribute != null) { return textAttribute; } } return null; //use default } @SuppressWarnings("unchecked") public TextAttribute getForegroundTextAttribute() { List<IPydevPreferencesProvider> participants = ExtensionHelper .getParticipants(ExtensionHelper.PYDEV_PREFERENCES_PROVIDER); for (IPydevPreferencesProvider iPydevPreferencesProvider : participants) { TextAttribute textAttribute = iPydevPreferencesProvider.getCodeTextAttribute(); if (textAttribute != null) { return textAttribute; } } return null; //use default } }