From eda17772c9595003d5d7df38ec23b8f761b7e1d6 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sat, 13 Jun 2009 14:18:49 -0400 Subject: [PATCH] Enhancement - color - Color routines are now table driven and much smaller. - Implemented Text::guessColor. --- src/color.cpp | 304 +++++++++++++++++++------------------------------- src/color.h | 1 + src/main.h | 1 - src/valid.cpp | 96 +--------------- 4 files changed, 120 insertions(+), 282 deletions(-) diff --git a/src/color.cpp b/src/color.cpp index 29aa3c201..5de690c04 100644 --- a/src/color.cpp +++ b/src/color.cpp @@ -26,6 +26,8 @@ //////////////////////////////////////////////////////////////////////////////// #include #include "Context.h" +#include "text.h" +#include "util.h" #include "i18n.h" #include "color.h" @@ -35,138 +37,96 @@ extern Context context; namespace Text { +static struct +{ + color id; + int string_id; + std::string english_name; + std::string escape_sequence; +} allColors[] = +{ +// Text::color i18n.h English vt220? xterm? + { nocolor, 0, "", "" }, + { off, COLOR_OFF, "off", "" }, + + { bold, COLOR_BOLD, "bold", "\033[1m" }, + { underline, COLOR_UL, "underline", "\033[4m" }, + { bold_underline, COLOR_B_UL, "bold_underline", "\033[1;4m" }, + + { black, COLOR_BLACK, "black", "\033[30m" }, + { red, COLOR_RED, "red", "\033[31m" }, + { green, COLOR_GREEN, "green", "\033[32m" }, + { yellow, COLOR_YELLOW, "yellow", "\033[33m" }, + { blue, COLOR_BLUE, "blue", "\033[34m" }, + { magenta, COLOR_MAGENTA, "magenta", "\033[35m" }, + { cyan, COLOR_CYAN, "cyan", "\033[36m" }, + { white, COLOR_WHITE, "white", "\033[37m" }, + + { bold_black, COLOR_B_BLACK, "bold_black", "\033[90m" }, + { bold_red, COLOR_B_RED, "bold_red", "\033[91m" }, + { bold_green, COLOR_B_GREEN, "bold_green", "\033[92m" }, + { bold_yellow, COLOR_B_YELLOW, "bold_yellow", "\033[93m" }, + { bold_blue, COLOR_B_BLUE, "bold_blue", "\033[94m" }, + { bold_magenta, COLOR_B_MAGENTA, "bold_magenta", "\033[95m" }, + { bold_cyan, COLOR_B_CYAN, "bold_cyan", "\033[96m" }, + { bold_white, COLOR_B_WHITE, "bold_white", "\033[97m" }, + + { underline_black, COLOR_UL_BLACK, "underline_black", "\033[4;30m" }, + { underline_red, COLOR_UL_RED, "underline_red", "\033[4;31m" }, + { underline_green, COLOR_UL_GREEN, "underline_green", "\033[4;32m" }, + { underline_yellow, COLOR_UL_YELLOW, "underline_yellow", "\033[4;33m" }, + { underline_blue, COLOR_UL_BLUE, "underline_blue", "\033[4;34m" }, + { underline_magenta, COLOR_UL_MAGENTA, "underline_magenta", "\033[4;35m" }, + { underline_cyan, COLOR_UL_CYAN, "underline_cyan", "\033[4;36m" }, + { underline_white, COLOR_UL_WHITE, "underline_white", "\033[4;37m" }, + + { bold_underline_black, COLOR_B_UL_BLACK, "bold_underline_black", "\033[1;4;30m" }, + { bold_underline_red, COLOR_B_UL_RED, "bold_underline_red", "\033[1;4;31m" }, + { bold_underline_green, COLOR_B_UL_GREEN, "bold_underline_green", "\033[1;4;32m" }, + { bold_underline_yellow, COLOR_B_UL_YELLOW, "bold_underline_yellow", "\033[1;4;33m" }, + { bold_underline_blue, COLOR_B_UL_BLUE, "bold_underline_blue", "\033[1;4;34m" }, + { bold_underline_magenta, COLOR_B_UL_MAGENTA, "bold_underline_magenta", "\033[1;4;35m" }, + { bold_underline_cyan, COLOR_B_UL_CYAN, "bold_underline_cyan", "\033[1;4;36m" }, + { bold_underline_white, COLOR_B_UL_WHITE, "bold_underline_white", "\033[1;4;37m" }, + + { on_black, COLOR_ON_BLACK, "on_black", "\033[40m" }, + { on_red, COLOR_ON_RED, "on_red", "\033[41m" }, + { on_green, COLOR_ON_GREEN, "on_green", "\033[42m" }, + { on_yellow, COLOR_ON_YELLOW, "on_yellow", "\033[43m" }, + { on_blue, COLOR_ON_BLUE, "on_blue", "\033[44m" }, + { on_magenta, COLOR_ON_MAGENTA, "on_magenta", "\033[45m" }, + { on_cyan, COLOR_ON_CYAN, "on_cyan", "\033[46m" }, + { on_white, COLOR_ON_WHITE, "on_white", "\033[47m" }, + + { on_bright_black, COLOR_ON_BRIGHT_BLACK, "on_bright_black", "\033[100m" }, + { on_bright_red, COLOR_ON_BRIGHT_RED, "on_bright_red", "\033[101m" }, + { on_bright_green, COLOR_ON_BRIGHT_GREEN, "on_bright_green", "\033[102m" }, + { on_bright_yellow, COLOR_ON_BRIGHT_YELLOW, "on_bright_yellow", "\033[103m" }, + { on_bright_blue, COLOR_ON_BRIGHT_BLUE, "on_bright_blue", "\033[104m" }, + { on_bright_magenta, COLOR_ON_BRIGHT_MAGENTA, "on_bright_magenta", "\033[105m" }, + { on_bright_cyan, COLOR_ON_BRIGHT_CYAN, "on_bright_cyan", "\033[106m" }, + { on_bright_white, COLOR_ON_BRIGHT_WHITE, "on_bright_white", "\033[107m" }, +}; + +#define NUM_COLORS (sizeof (allColors) / sizeof (allColors[0])) + +//////////////////////////////////////////////////////////////////////////////// std::string colorName (color c) { - switch (c) - { - case nocolor: return ""; - case off: return context.stringtable.get (COLOR_OFF, "off"); - - case bold: return context.stringtable.get (COLOR_BOLD, "bold"); - case underline: return context.stringtable.get (COLOR_UL, "underline"); - case bold_underline: return context.stringtable.get (COLOR_B_UL, "bold_underline"); - - case black: return context.stringtable.get (COLOR_BLACK, "black"); - case red: return context.stringtable.get (COLOR_RED, "red"); - case green: return context.stringtable.get (COLOR_GREEN, "green"); - case yellow: return context.stringtable.get (COLOR_YELLOW, "yellow"); - case blue: return context.stringtable.get (COLOR_BLUE, "blue"); - case magenta: return context.stringtable.get (COLOR_MAGENTA, "magenta"); - case cyan: return context.stringtable.get (COLOR_CYAN, "cyan"); - case white: return context.stringtable.get (COLOR_WHITE, "white"); - - case bold_black: return context.stringtable.get (COLOR_B_BLACK, "bold_black"); - case bold_red: return context.stringtable.get (COLOR_B_RED, "bold_red"); - case bold_green: return context.stringtable.get (COLOR_B_GREEN, "bold_green"); - case bold_yellow: return context.stringtable.get (COLOR_B_YELLOW, "bold_yellow"); - case bold_blue: return context.stringtable.get (COLOR_B_BLUE, "bold_blue"); - case bold_magenta: return context.stringtable.get (COLOR_B_MAGENTA, "bold_magenta"); - case bold_cyan: return context.stringtable.get (COLOR_B_CYAN, "bold_cyan"); - case bold_white: return context.stringtable.get (COLOR_B_WHITE, "bold_white"); - - case underline_black: return context.stringtable.get (COLOR_UL_BLACK, "underline_black"); - case underline_red: return context.stringtable.get (COLOR_UL_RED, "underline_red"); - case underline_green: return context.stringtable.get (COLOR_UL_GREEN, "underline_green"); - case underline_yellow: return context.stringtable.get (COLOR_UL_YELLOW, "underline_yellow"); - case underline_blue: return context.stringtable.get (COLOR_UL_BLUE, "underline_blue"); - case underline_magenta: return context.stringtable.get (COLOR_UL_MAGENTA, "underline_magenta"); - case underline_cyan: return context.stringtable.get (COLOR_UL_CYAN, "underline_cyan"); - case underline_white: return context.stringtable.get (COLOR_UL_WHITE, "underline_white"); - - case bold_underline_black: return context.stringtable.get (COLOR_B_UL_BLACK, "bold_underline_black"); - case bold_underline_red: return context.stringtable.get (COLOR_B_UL_RED, "bold_underline_red"); - case bold_underline_green: return context.stringtable.get (COLOR_B_UL_GREEN, "bold_underline_green"); - case bold_underline_yellow: return context.stringtable.get (COLOR_B_UL_YELLOW, "bold_underline_yellow"); - case bold_underline_blue: return context.stringtable.get (COLOR_B_UL_BLUE, "bold_underline_blue"); - case bold_underline_magenta: return context.stringtable.get (COLOR_B_UL_MAGENTA, "bold_underline_magenta"); - case bold_underline_cyan: return context.stringtable.get (COLOR_B_UL_CYAN, "bold_underline_cyan"); - case bold_underline_white: return context.stringtable.get (COLOR_B_UL_WHITE, "bold_underline_white"); - - case on_black: return context.stringtable.get (COLOR_ON_BLACK, "on_black"); - case on_red: return context.stringtable.get (COLOR_ON_RED, "on_red"); - case on_green: return context.stringtable.get (COLOR_ON_GREEN, "on_green"); - case on_yellow: return context.stringtable.get (COLOR_ON_YELLOW, "on_yellow"); - case on_blue: return context.stringtable.get (COLOR_ON_BLUE, "on_blue"); - case on_magenta: return context.stringtable.get (COLOR_ON_MAGENTA, "on_magenta"); - case on_cyan: return context.stringtable.get (COLOR_ON_CYAN, "on_cyan"); - case on_white: return context.stringtable.get (COLOR_ON_WHITE, "on_white"); - - case on_bright_black: return context.stringtable.get (COLOR_ON_BRIGHT_BLACK, "on_bright_black"); - case on_bright_red: return context.stringtable.get (COLOR_ON_BRIGHT_RED, "on_bright_red"); - case on_bright_green: return context.stringtable.get (COLOR_ON_BRIGHT_GREEN, "on_bright_green"); - case on_bright_yellow: return context.stringtable.get (COLOR_ON_BRIGHT_YELLOW, "on_bright_yellow"); - case on_bright_blue: return context.stringtable.get (COLOR_ON_BRIGHT_BLUE, "on_bright_blue"); - case on_bright_magenta: return context.stringtable.get (COLOR_ON_BRIGHT_MAGENTA, "on_bright_magenta"); - case on_bright_cyan: return context.stringtable.get (COLOR_ON_BRIGHT_CYAN, "on_bright_cyan"); - case on_bright_white: return context.stringtable.get (COLOR_ON_BRIGHT_WHITE, "on_bright_white"); - - default: throw context.stringtable.get (COLOR_UNKNOWN, "Unknown color value"); - } + for (unsigned int i = 0; i < NUM_COLORS; ++i) + if (allColors[i].id == c) + return allColors[i].english_name; + throw context.stringtable.get (COLOR_UNKNOWN, "Unknown color value"); return ""; } //////////////////////////////////////////////////////////////////////////////// color colorCode (const std::string& c) { - if (c == context.stringtable.get (COLOR_OFF, "off")) return off; - else if (c == context.stringtable.get (COLOR_BOLD, "bold")) return bold; - else if (c == context.stringtable.get (COLOR_UL, "underline")) return underline; - else if (c == context.stringtable.get (COLOR_B_UL, "bold_underline")) return bold_underline; - - else if (c == context.stringtable.get (COLOR_BLACK, "black")) return black; - else if (c == context.stringtable.get (COLOR_RED, "red")) return red; - else if (c == context.stringtable.get (COLOR_GREEN, "green")) return green; - else if (c == context.stringtable.get (COLOR_YELLOW, "yellow")) return yellow; - else if (c == context.stringtable.get (COLOR_BLUE, "blue")) return blue; - else if (c == context.stringtable.get (COLOR_MAGENTA, "magenta")) return magenta; - else if (c == context.stringtable.get (COLOR_CYAN, "cyan")) return cyan; - else if (c == context.stringtable.get (COLOR_WHITE, "white")) return white; - - else if (c == context.stringtable.get (COLOR_B_BLACK, "bold_black")) return bold_black; - else if (c == context.stringtable.get (COLOR_B_RED, "bold_red")) return bold_red; - else if (c == context.stringtable.get (COLOR_B_GREEN, "bold_green")) return bold_green; - else if (c == context.stringtable.get (COLOR_B_YELLOW, "bold_yellow")) return bold_yellow; - else if (c == context.stringtable.get (COLOR_B_BLUE, "bold_blue")) return bold_blue; - else if (c == context.stringtable.get (COLOR_B_MAGENTA, "bold_magenta")) return bold_magenta; - else if (c == context.stringtable.get (COLOR_B_CYAN, "bold_cyan")) return bold_cyan; - else if (c == context.stringtable.get (COLOR_B_WHITE, "bold_white")) return bold_white; - - else if (c == context.stringtable.get (COLOR_UL_BLACK, "underline_black")) return underline_black; - else if (c == context.stringtable.get (COLOR_UL_RED, "underline_red")) return underline_red; - else if (c == context.stringtable.get (COLOR_UL_GREEN, "underline_green")) return underline_green; - else if (c == context.stringtable.get (COLOR_UL_YELLOW, "underline_yellow")) return underline_yellow; - else if (c == context.stringtable.get (COLOR_UL_BLUE, "underline_blue")) return underline_blue; - else if (c == context.stringtable.get (COLOR_UL_MAGENTA, "underline_magenta")) return underline_magenta; - else if (c == context.stringtable.get (COLOR_UL_CYAN, "underline_cyan")) return underline_cyan; - else if (c == context.stringtable.get (COLOR_UL_WHITE, "underline_white")) return underline_white; - - else if (c == context.stringtable.get (COLOR_B_UL_BLACK, "bold_underline_black")) return bold_underline_black; - else if (c == context.stringtable.get (COLOR_B_UL_RED, "bold_underline_red")) return bold_underline_red; - else if (c == context.stringtable.get (COLOR_B_UL_GREEN, "bold_underline_green")) return bold_underline_green; - else if (c == context.stringtable.get (COLOR_B_UL_YELLOW, "bold_underline_yellow")) return bold_underline_yellow; - else if (c == context.stringtable.get (COLOR_B_UL_BLUE, "bold_underline_blue")) return bold_underline_blue; - else if (c == context.stringtable.get (COLOR_B_UL_MAGENTA, "bold_underline_magenta")) return bold_underline_magenta; - else if (c == context.stringtable.get (COLOR_B_UL_CYAN, "bold_underline_cyan")) return bold_underline_cyan; - else if (c == context.stringtable.get (COLOR_B_UL_WHITE, "bold_underline_white")) return bold_underline_white; - - else if (c == context.stringtable.get (COLOR_ON_BLACK, "on_black")) return on_black; - else if (c == context.stringtable.get (COLOR_ON_RED, "on_red")) return on_red; - else if (c == context.stringtable.get (COLOR_ON_GREEN, "on_green")) return on_green; - else if (c == context.stringtable.get (COLOR_ON_YELLOW, "on_yellow")) return on_yellow; - else if (c == context.stringtable.get (COLOR_ON_BLUE, "on_blue")) return on_blue; - else if (c == context.stringtable.get (COLOR_ON_MAGENTA, "on_magenta")) return on_magenta; - else if (c == context.stringtable.get (COLOR_ON_CYAN, "on_cyan")) return on_cyan; - else if (c == context.stringtable.get (COLOR_ON_WHITE, "on_white")) return on_white; - - else if (c == context.stringtable.get (COLOR_ON_BRIGHT_BLACK, "on_bright_black")) return on_bright_black; - else if (c == context.stringtable.get (COLOR_ON_BRIGHT_RED, "on_bright_red")) return on_bright_red; - else if (c == context.stringtable.get (COLOR_ON_BRIGHT_GREEN, "on_bright_green")) return on_bright_green; - else if (c == context.stringtable.get (COLOR_ON_BRIGHT_YELLOW, "on_bright_yellow")) return on_bright_yellow; - else if (c == context.stringtable.get (COLOR_ON_BRIGHT_BLUE, "on_bright_blue")) return on_bright_blue; - else if (c == context.stringtable.get (COLOR_ON_BRIGHT_MAGENTA, "on_bright_magenta")) return on_bright_magenta; - else if (c == context.stringtable.get (COLOR_ON_BRIGHT_CYAN, "on_bright_cyan")) return on_bright_cyan; - else if (c == context.stringtable.get (COLOR_ON_BRIGHT_WHITE, "on_bright_white")) return on_bright_white; + for (unsigned int i = 0; i < NUM_COLORS; ++i) + if (context.stringtable.get (allColors[i].string_id, allColors[i].english_name) == c) + return allColors[i].id; return nocolor; } @@ -174,72 +134,11 @@ color colorCode (const std::string& c) //////////////////////////////////////////////////////////////////////////////// std::string decode (color c) { - switch (c) - { - case nocolor: return ""; - case off: return "\033[0m"; - - case bold: return "\033[1m"; - case underline: return "\033[4m"; - case bold_underline: return "\033[1;4m"; - - case black: return "\033[30m"; - case red: return "\033[31m"; - case green: return "\033[32m"; - case yellow: return "\033[33m"; - case blue: return "\033[34m"; - case magenta: return "\033[35m"; - case cyan: return "\033[36m"; - case white: return "\033[37m"; - - case bold_black: return "\033[90m"; - case bold_red: return "\033[91m"; - case bold_green: return "\033[92m"; - case bold_yellow: return "\033[93m"; - case bold_blue: return "\033[94m"; - case bold_magenta: return "\033[95m"; - case bold_cyan: return "\033[96m"; - case bold_white: return "\033[97m"; - - case underline_black: return "\033[4;30m"; - case underline_red: return "\033[4;31m"; - case underline_green: return "\033[4;32m"; - case underline_yellow: return "\033[4;33m"; - case underline_blue: return "\033[4;34m"; - case underline_magenta: return "\033[4;35m"; - case underline_cyan: return "\033[4;36m"; - case underline_white: return "\033[4;37m"; - - case bold_underline_black: return "\033[1;4;30m"; - case bold_underline_red: return "\033[1;4;31m"; - case bold_underline_green: return "\033[1;4;32m"; - case bold_underline_yellow: return "\033[1;4;33m"; - case bold_underline_blue: return "\033[1;4;34m"; - case bold_underline_magenta: return "\033[1;4;35m"; - case bold_underline_cyan: return "\033[1;4;36m"; - case bold_underline_white: return "\033[1;4;37m"; - - case on_black: return "\033[40m"; - case on_red: return "\033[41m"; - case on_green: return "\033[42m"; - case on_yellow: return "\033[43m"; - case on_blue: return "\033[44m"; - case on_magenta: return "\033[45m"; - case on_cyan: return "\033[46m"; - case on_white: return "\033[47m"; - - case on_bright_black: return "\033[100m"; - case on_bright_red: return "\033[101m"; - case on_bright_green: return "\033[102m"; - case on_bright_yellow: return "\033[103m"; - case on_bright_blue: return "\033[104m"; - case on_bright_magenta: return "\033[105m"; - case on_bright_cyan: return "\033[106m"; - case on_bright_white: return "\033[107m"; - - default: throw context.stringtable.get (COLOR_UNKNOWN, "Unknown color value"); - } + for (unsigned int i = 0; i < NUM_COLORS; ++i) + if (allColors[i].id == c) + return allColors[i].escape_sequence; + throw context.stringtable.get (COLOR_UNKNOWN, "Unknown color value"); return ""; } @@ -265,5 +164,34 @@ std::string colorize () return decode (off); } +//////////////////////////////////////////////////////////////////////////////// +std::string guessColor (const std::string& name) +{ + std::vector all; + for (unsigned int i = 0; i < NUM_COLORS; ++i) + all.push_back (context.stringtable.get ( + allColors[i].string_id, + allColors[i].english_name)); + + std::vector matches; + autoComplete (name, all, matches); + + if (matches.size () == 0) + throw std::string ("Unrecognized color '") + name + "'"; + + else if (matches.size () != 1) + { + std::string error = "Ambiguous color '" + name + "' - could be either of "; // TODO i18n + + std::string combined; + join (combined, ", ", matches); + error += combined; + + throw error + combined; + } + + return matches[0]; +} + //////////////////////////////////////////////////////////////////////////////// } diff --git a/src/color.h b/src/color.h index d90b47c8d..02c842dcd 100644 --- a/src/color.h +++ b/src/color.h @@ -50,6 +50,7 @@ namespace Text std::string colorize (color, color, const std::string& string); std::string colorize (color, color); std::string colorize (); + std::string guessColor (const std::string&); } #endif diff --git a/src/main.h b/src/main.h index aa1d36284..f008b1bbe 100644 --- a/src/main.h +++ b/src/main.h @@ -43,7 +43,6 @@ bool validDescription (const std::string&); bool validDuration (std::string&); void validReportColumns (const std::vector &); void validSortColumns (const std::vector &, const std::vector &); -bool isModifiableAttribute (const std::string&); bool validAttribute (std::string&, std::string&); bool validId (const std::string&); bool validTag (const std::string&); diff --git a/src/valid.cpp b/src/valid.cpp index 3b183fa5a..9fefbb80d 100644 --- a/src/valid.cpp +++ b/src/valid.cpp @@ -36,74 +36,13 @@ #include "T.h" #include "text.h" #include "util.h" +#include "color.h" extern Context context; //////////////////////////////////////////////////////////////////////////////// // NOTE: These are static arrays only because there is no initializer list for -// std::vector. -// TODO Obsolete -static const char* colors[] = -{ - "bold", - "underline", - "bold_underline", - - "black", - "red", - "green", - "yellow", - "blue", - "magenta", - "cyan", - "white", - - "bold_black", - "bold_red", - "bold_green", - "bold_yellow", - "bold_blue", - "bold_magenta", - "bold_cyan", - "bold_white", - - "underline_black", - "underline_red", - "underline_green", - "underline_yellow", - "underline_blue", - "underline_magenta", - "underline_cyan", - "underline_white", - - "bold_underline_black", - "bold_underline_red", - "bold_underline_green", - "bold_underline_yellow", - "bold_underline_blue", - "bold_underline_magenta", - "bold_underline_cyan", - "bold_underline_white", - - "on_black", - "on_red", - "on_green", - "on_yellow", - "on_blue", - "on_magenta", - "on_cyan", - "on_white", - - "on_bright_black", - "on_bright_red", - "on_bright_green", - "on_bright_yellow", - "on_bright_blue", - "on_bright_magenta", - "on_bright_cyan", - "on_bright_white", - "", -}; +// std::vector until C++0x. // TODO Obsolete static const char* attributes[] = @@ -124,18 +63,6 @@ static const char* attributes[] = "", }; -static const char* modifiableAttributes[] = -{ - "project", - "priority", - "fg", - "bg", - "due", - "recur", - "until", - "", -}; - // TODO Relocate inside Context. static std::vector customReports; @@ -166,23 +93,6 @@ bool validPriority (const std::string& input) return true; } -//////////////////////////////////////////////////////////////////////////////// -// Only attributes that are written to the data files. -// TODO Relocate to Att.cpp. -bool isModifiableAttribute (const std::string& name) -{ - if (name == "project" || - name == "priority" || - name == "fg" || - name == "bg" || - name == "due" || - name == "recur" || - name == "until") - return true; - - return false; -} - //////////////////////////////////////////////////////////////////////////////// // All attributes, regardless of usage. // TODO Relocate to Att.cpp. @@ -192,7 +102,7 @@ bool validAttribute (std::string& name, std::string& value) if (name != "") { if ((name == "fg" || name == "bg") && value != "") - guess ("color", colors, value); + Text::guessColor (value); else if (name == "due" && value != "") Date (value);