Feature - 256-color support

- Integrated new Color object into task.
- Debugging needed - the cyan, green, and yellow colors are mixed up!
This commit is contained in:
Paul Beckingham 2009-09-22 17:01:59 -04:00
parent 58730a48b3
commit ff3b7cf337
11 changed files with 157 additions and 441 deletions

View file

@ -319,8 +319,8 @@ bool Att::validNameValue (
else if (name == "fg" || name == "bg") else if (name == "fg" || name == "bg")
{ {
if (value != "") // TODO Determine whether color abbreviations are supported, and if so,
Text::guessColor (value); // modify 'value' here accordingly.
} }
else if (name == "due" || else if (name == "due" ||

View file

@ -471,6 +471,15 @@ std::string Color::colorize (const std::string& input, const std::string& spec)
return c.colorize (input); return c.colorize (input);
} }
////////////////////////////////////////////////////////////////////////////////
bool Color::nontrivial ()
{
if (value != (_COLOR_NOFG | _COLOR_NOBG))
return true;
return false;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int Color::find (const std::string& input) int Color::find (const std::string& input)
{ {

View file

@ -61,6 +61,8 @@ public:
std::string colorize (const std::string&); std::string colorize (const std::string&);
std::string colorize (const std::string&, const std::string&); std::string colorize (const std::string&, const std::string&);
bool nontrivial ();
private: private:
int find (const std::string&); int find (const std::string&);
std::string fg (); std::string fg ();

View file

@ -582,7 +582,7 @@ void TDB::undo ()
row = table.addRow (); row = table.addRow ();
table.addCell (row, 0, *name); table.addCell (row, 0, *name);
table.addCell (row, 1, renderAttribute (*name, before.get (*name))); table.addCell (row, 1, renderAttribute (*name, before.get (*name)));
table.setCellFg (row, 1, Text::red); table.setCellColor (row, 1, Color (Color::red));
} }
foreach (name, before) foreach (name, before)
@ -599,8 +599,8 @@ void TDB::undo ()
if (priorValue != currentValue) if (priorValue != currentValue)
{ {
table.setCellFg (row, 1, Text::red); table.setCellColor (row, 1, Color (Color::red));
table.setCellFg (row, 2, Text::green); table.setCellColor (row, 2, Color (Color::green));
} }
} }
} }
@ -610,7 +610,7 @@ void TDB::undo ()
row = table.addRow (); row = table.addRow ();
table.addCell (row, 0, *name); table.addCell (row, 0, *name);
table.addCell (row, 2, renderAttribute (*name, after.get (*name))); table.addCell (row, 2, renderAttribute (*name, after.get (*name)));
table.setCellFg (row, 2, Text::green); table.setCellColor (row, 2, Color (Color::green));
} }
} }
else else
@ -621,7 +621,7 @@ void TDB::undo ()
row = table.addRow (); row = table.addRow ();
table.addCell (row, 0, name->first); table.addCell (row, 0, name->first);
table.addCell (row, 2, renderAttribute (name->first, after.get (name->first))); table.addCell (row, 2, renderAttribute (name->first, after.get (name->first)));
table.setCellFg (row, 2, Text::green); table.setCellColor (row, 2, Color (Color::green));
} }
} }

View file

@ -70,22 +70,9 @@ Table::~Table ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Table::setTableColor (Text::color fg, Text::color bg) void Table::setTableColor (const Color& c)
{ {
mFg["table"] = Text::colorName (fg); mColor["table"] = c;
mBg["table"] = Text::colorName (bg);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setTableFg (Text::color c)
{
mFg["table"] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setTableBg (Text::color c)
{
mBg["table"] = Text::colorName (c);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -126,28 +113,11 @@ int Table::addColumn (const std::string& col)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Table::setColumnColor (int column, Text::color fg, Text::color bg) void Table::setColumnColor (int column, const Color& c)
{ {
char id[12]; char id[12];
sprintf (id, "col:%d", column); sprintf (id, "col:%d", column);
mFg[id] = Text::colorName (fg); mColor[id] = c;
mBg[id] = Text::colorName (bg);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setColumnFg (int column, Text::color c)
{
char id[12];
sprintf (id, "col:%d", column);
mFg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setColumnBg (int column, Text::color c)
{
char id[12];
sprintf (id, "col:%d", column);
mBg[id] = Text::colorName (c);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -155,7 +125,7 @@ void Table::setColumnUnderline (int column)
{ {
char id[12]; char id[12];
sprintf (id, "col:%d", column); sprintf (id, "col:%d", column);
mUnderline[id] = Text::underline; mUnderline[id] = Color (Color::nocolor, Color::nocolor, true, false, false);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -203,28 +173,11 @@ int Table::addRow ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Table::setRowColor (const int row, const Text::color fg, const Text::color bg) void Table::setRowColor (const int row, const Color& c)
{ {
char id[12]; char id[12];
sprintf (id, "row:%d", row); sprintf (id, "row:%d", row);
mFg[id] = Text::colorName (fg); mColor[id] = c;
mBg[id] = Text::colorName (bg);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setRowFg (const int row, const Text::color c)
{
char id[12];
sprintf (id, "row:%d", row);
mFg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setRowBg (const int row, const Text::color c)
{
char id[12];
sprintf (id, "row:%d", row);
mBg[id] = Text::colorName (c);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -336,28 +289,11 @@ void Table::addCell (const int row, const int col, const double data)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Table::setCellColor (const int row, const int col, const Text::color fg, const Text::color bg) void Table::setCellColor (const int row, const int col, const Color& c)
{ {
char id[24]; char id[24];
sprintf (id, "cell:%d,%d", row, col); sprintf (id, "cell:%d,%d", row, col);
mFg[id] = Text::colorName (fg); mColor[id] = c;
mBg[id] = Text::colorName (bg);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setCellFg (const int row, const int col, const Text::color c)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
mFg[id] = Text::colorName (c);
}
////////////////////////////////////////////////////////////////////////////////
void Table::setCellBg (const int row, const int col, const Text::color c)
{
char id[24];
sprintf (id, "cell:%d,%d", row, col);
mBg[id] = Text::colorName (c);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -371,83 +307,48 @@ std::string Table::getCell (const int row, const int col)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Text::color Table::getFg (const int row, const int col) Color Table::getColor (const int row, const int col)
{ {
char idCell[24]; char idCell[24];
sprintf (idCell, "cell:%d,%d", row, col); sprintf (idCell, "cell:%d,%d", row, col);
if (mFg.find (idCell) != mFg.end ()) if (mColor.find (idCell) != mColor.end ())
return Text::colorCode (mFg[idCell]); return mColor[idCell];
char idRow[12]; char idRow[12];
sprintf (idRow, "row:%d", row); sprintf (idRow, "row:%d", row);
if (mFg.find (idRow) != mFg.end ()) if (mColor.find (idRow) != mColor.end ())
return Text::colorCode (mFg[idRow]); return mColor[idRow];
char idCol[12]; char idCol[12];
sprintf (idCol, "col:%d", col); sprintf (idCol, "col:%d", col);
if (mFg.find (idCol) != mFg.end ()) if (mColor.find (idCol) != mColor.end ())
return Text::colorCode (mFg[idCol]); return mColor[idCol];
if (mFg.find ("table") != mFg.end ()) if (mColor.find ("table") != mColor.end ())
return Text::colorCode (mFg["table"]); return mColor["table"];
return Text::nocolor; return Color ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Text::color Table::getHeaderFg (int col) Color Table::getHeaderColor (int col)
{ {
char idCol[12]; char idCol[12];
sprintf (idCol, "col:%d", col); sprintf (idCol, "col:%d", col);
return mFg.find (idCol) != mFg.end () ? Text::colorCode (mFg[idCol]) return mColor.find (idCol) != mColor.end () ? mColor[idCol]
: mFg.find ("table") != mFg.end () ? Text::colorCode (mFg["table"]) : mColor.find ("table") != mColor.end () ? mColor["table"]
: Text::nocolor; : Color ();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Text::color Table::getBg (const int row, const int col) Color Table::getHeaderUnderline (int col)
{
char idCell[24];
sprintf (idCell, "cell:%d,%d", row, col);
if (mBg.find (idCell) != mBg.end ())
return Text::colorCode (mBg[idCell]);
char idRow[12];
sprintf (idRow, "row:%d", row);
if (mBg.find (idRow) != mBg.end ())
return Text::colorCode (mBg[idRow]);
char idCol[12];
sprintf (idCol, "col:%d", col);
if (mBg.find (idCol) != mBg.end ())
return Text::colorCode (mBg[idCol]);
if (mBg.find ("table") != mBg.end ())
return Text::colorCode (mBg["table"]);
return Text::nocolor;
}
////////////////////////////////////////////////////////////////////////////////
Text::color Table::getHeaderBg (int col)
{ {
char idCol[12]; char idCol[12];
sprintf (idCol, "col:%d", col); sprintf (idCol, "col:%d", col);
return mBg.find (idCol) != mBg.end () ? Text::colorCode (mBg[idCol]) return mUnderline.find (idCol) != mUnderline.end () ? mUnderline[idCol]
: mBg.find ("table") != mBg.end () ? Text::colorCode (mBg["table"]) : Color ();
: Text::nocolor;
}
////////////////////////////////////////////////////////////////////////////////
Text::color Table::getHeaderUnderline (int col)
{
char idCol[12];
sprintf (idCol, "col:%d", col);
return mUnderline.find (idCol) != mUnderline.end () ? Text::underline
: Text::nocolor;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -584,10 +485,9 @@ const std::string Table::formatHeader (
{ {
assert (width > 0); assert (width > 0);
Text::color fg = getHeaderFg (col); Color c = getHeaderColor (col);
Text::color bg = getHeaderBg (col);
std::string data = mColumns[col]; std::string data = mColumns[col];
Text::color decoration = getHeaderUnderline (col); c.blend (getHeaderUnderline (col));
std::string pad = ""; std::string pad = "";
std::string intraPad = ""; std::string intraPad = "";
@ -609,11 +509,7 @@ const std::string Table::formatHeader (
for (int i = 0; i < getIntraPadding (); ++i) for (int i = 0; i < getIntraPadding (); ++i)
intraPad += " "; intraPad += " ";
return Text::colorize ( return c.colorize (pad + preJust + data + postJust + pad) + intraPad;
fg, bg,
Text::colorize (
decoration, Text::nocolor,
pad + preJust + data + postJust + pad) + intraPad);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -638,9 +534,8 @@ const std::string Table::formatHeaderDashedUnderline (
{ {
assert (width > 0); assert (width > 0);
Text::color fg = getHeaderFg (col); Color c = getHeaderColor (col);
Text::color bg = getHeaderBg (col); c.blend (getHeaderUnderline (col));
Text::color decoration = getHeaderUnderline (col);
std::string data = ""; std::string data = "";
for (int i = 0; i < width; ++i) for (int i = 0; i < width; ++i)
@ -659,11 +554,7 @@ const std::string Table::formatHeaderDashedUnderline (
for (int i = 0; i < getIntraPadding (); ++i) for (int i = 0; i < getIntraPadding (); ++i)
intraPad += " "; intraPad += " ";
return Text::colorize ( return c.colorize (pad + data + pad) + intraPad;
fg, bg,
Text::colorize (
decoration, Text::nocolor,
pad + data + pad) + intraPad);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -677,8 +568,7 @@ void Table::formatCell (
{ {
assert (width > 0); assert (width > 0);
Text::color fg = getFg (row, col); Color c = getColor (row, col);
Text::color bg = getBg (row, col);
just justification = getJustification (row, col); just justification = getJustification (row, col);
std::string data = getCell (row, col); std::string data = getCell (row, col);
@ -722,8 +612,7 @@ void Table::formatCell (
postJust += " "; postJust += " ";
} }
lines.push_back ( lines.push_back (c.colorize (pad + preJust + chunks[chunk] + postJust + pad + intraPad));
Text::colorize (fg, bg, pad + preJust + chunks[chunk] + postJust + pad + intraPad));
} }
// The blank is used to vertically pad cells that have blank lines. // The blank is used to vertically pad cells that have blank lines.
@ -731,7 +620,7 @@ void Table::formatCell (
for (int i = 0; i < width; ++i) for (int i = 0; i < width; ++i)
pad += " "; pad += " ";
blank = Text::colorize (fg, bg, pad + intraPad); blank = c.colorize (pad + intraPad);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -55,18 +55,14 @@ public:
Table (const Table&); Table (const Table&);
Table& operator= (const Table&); Table& operator= (const Table&);
void setTableColor (Text::color, Text::color); void setTableColor (const Color&);
void setTableFg (Text::color);
void setTableBg (Text::color);
void setTablePadding (int); void setTablePadding (int);
void setTableIntraPadding (int); void setTableIntraPadding (int);
void setTableWidth (int); void setTableWidth (int);
void setTableDashedUnderline (); void setTableDashedUnderline ();
int addColumn (const std::string&); int addColumn (const std::string&);
void setColumnColor (int, Text::color, Text::color); void setColumnColor (int, const Color&);
void setColumnFg (int, Text::color);
void setColumnBg (int, Text::color);
void setColumnUnderline (int); void setColumnUnderline (int);
void setColumnPadding (int, int); void setColumnPadding (int, int);
void setColumnWidth (int, int); void setColumnWidth (int, int);
@ -76,18 +72,14 @@ public:
void sortOn (int, order); void sortOn (int, order);
int addRow (); int addRow ();
void setRowColor (int, Text::color, Text::color); void setRowColor (int, const Color&);
void setRowFg (int, Text::color);
void setRowBg (int, Text::color);
void addCell (int, int, const std::string&); void addCell (int, int, const std::string&);
void addCell (int, int, char); void addCell (int, int, char);
void addCell (int, int, int); void addCell (int, int, int);
void addCell (int, int, float); void addCell (int, int, float);
void addCell (int, int, double); void addCell (int, int, double);
void setCellColor (int, int, Text::color, Text::color); void setCellColor (int, int, const Color&);
void setCellFg (int, int, Text::color);
void setCellBg (int, int, Text::color);
void suppressWS (); void suppressWS ();
void setDateFormat (const std::string&); void setDateFormat (const std::string&);
@ -98,11 +90,9 @@ public:
private: private:
std::string getCell (const int, const int); std::string getCell (const int, const int);
Text::color getFg (const int, const int); Color getColor (const int, const int);
Text::color getHeaderFg (const int); Color getHeaderColor (const int);
Text::color getBg (const int, const int); Color getHeaderUnderline (const int);
Text::color getHeaderBg (const int);
Text::color getHeaderUnderline (const int);
int getPadding (const int); int getPadding (const int);
int getIntraPadding (); int getIntraPadding ();
void calculateColumnWidths (); void calculateColumnWidths ();
@ -119,9 +109,8 @@ private:
std::vector <std::string> mColumns; std::vector <std::string> mColumns;
int mRows; int mRows;
int mIntraPadding; int mIntraPadding;
std::map <std::string, std::string> mFg; std::map <std::string, Color> mColor;
std::map <std::string, std::string> mBg; std::map <std::string, Color> mUnderline;
std::map <std::string, std::string> mUnderline;
bool mDashedUnderline; bool mDashedUnderline;
// Padding... // Padding...

View file

@ -476,14 +476,16 @@ int handleVersion (std::string &outs)
} }
} }
Color bold ("bold");
out << "Copyright (C) 2006 - 2009, P. Beckingham." out << "Copyright (C) 2006 - 2009, P. Beckingham."
<< std::endl << std::endl
<< ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) << ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
? Text::colorize (Text::bold, Text::nocolor, PACKAGE) ? bold.colorize (PACKAGE)
: PACKAGE) : PACKAGE)
<< " " << " "
<< ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) << ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
? Text::colorize (Text::bold, Text::nocolor, VERSION) ? bold.colorize (VERSION)
: VERSION) : VERSION)
<< std::endl << std::endl
<< disclaimer.render () << disclaimer.render ()
@ -1139,8 +1141,9 @@ int handleDuplicate (std::string &outs)
void handleShell () void handleShell ()
{ {
// Display some kind of welcome message. // Display some kind of welcome message.
Color bold (Color::nocolor, Color::nocolor, false, true, false);
std::cout << ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) std::cout << ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
? Text::colorize (Text::bold, Text::nocolor, PACKAGE_STRING) ? bold.colorize (PACKAGE_STRING)
: PACKAGE_STRING) : PACKAGE_STRING)
<< " shell" << " shell"
<< std::endl << std::endl
@ -1216,77 +1219,8 @@ int handleColor (std::string &outs)
std::stringstream out; std::stringstream out;
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
{ {
out << optionalBlankLine () << "Foreground" << std::endl out
<< " " // TODO Add new "color" command here.
<< Text::colorize (Text::bold, Text::nocolor, "bold") << " "
<< Text::colorize (Text::underline, Text::nocolor, "underline") << " "
<< Text::colorize (Text::bold_underline, Text::nocolor, "bold_underline") << std::endl
<< " " << Text::colorize (Text::black, Text::nocolor, "black") << " "
<< Text::colorize (Text::bold_black, Text::nocolor, "bold_black") << " "
<< Text::colorize (Text::underline_black, Text::nocolor, "underline_black") << " "
<< Text::colorize (Text::bold_underline_black, Text::nocolor, "bold_underline_black") << std::endl
<< " " << Text::colorize (Text::red, Text::nocolor, "red") << " "
<< Text::colorize (Text::bold_red, Text::nocolor, "bold_red") << " "
<< Text::colorize (Text::underline_red, Text::nocolor, "underline_red") << " "
<< Text::colorize (Text::bold_underline_red, Text::nocolor, "bold_underline_red") << std::endl
<< " " << Text::colorize (Text::green, Text::nocolor, "green") << " "
<< Text::colorize (Text::bold_green, Text::nocolor, "bold_green") << " "
<< Text::colorize (Text::underline_green, Text::nocolor, "underline_green") << " "
<< Text::colorize (Text::bold_underline_green, Text::nocolor, "bold_underline_green") << std::endl
<< " " << Text::colorize (Text::yellow, Text::nocolor, "yellow") << " "
<< Text::colorize (Text::bold_yellow, Text::nocolor, "bold_yellow") << " "
<< Text::colorize (Text::underline_yellow, Text::nocolor, "underline_yellow") << " "
<< Text::colorize (Text::bold_underline_yellow, Text::nocolor, "bold_underline_yellow") << std::endl
<< " " << Text::colorize (Text::blue, Text::nocolor, "blue") << " "
<< Text::colorize (Text::bold_blue, Text::nocolor, "bold_blue") << " "
<< Text::colorize (Text::underline_blue, Text::nocolor, "underline_blue") << " "
<< Text::colorize (Text::bold_underline_blue, Text::nocolor, "bold_underline_blue") << std::endl
<< " " << Text::colorize (Text::magenta, Text::nocolor, "magenta") << " "
<< Text::colorize (Text::bold_magenta, Text::nocolor, "bold_magenta") << " "
<< Text::colorize (Text::underline_magenta, Text::nocolor, "underline_magenta") << " "
<< Text::colorize (Text::bold_underline_magenta, Text::nocolor, "bold_underline_magenta") << std::endl
<< " " << Text::colorize (Text::cyan, Text::nocolor, "cyan") << " "
<< Text::colorize (Text::bold_cyan, Text::nocolor, "bold_cyan") << " "
<< Text::colorize (Text::underline_cyan, Text::nocolor, "underline_cyan") << " "
<< Text::colorize (Text::bold_underline_cyan, Text::nocolor, "bold_underline_cyan") << std::endl
<< " " << Text::colorize (Text::white, Text::nocolor, "white") << " "
<< Text::colorize (Text::bold_white, Text::nocolor, "bold_white") << " "
<< Text::colorize (Text::underline_white, Text::nocolor, "underline_white") << " "
<< Text::colorize (Text::bold_underline_white, Text::nocolor, "bold_underline_white") << std::endl
<< std::endl << "Background" << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_black, "on_black") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_black, "on_bright_black") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_red, "on_red") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_red, "on_bright_red") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_green, "on_green") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_green, "on_bright_green") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_yellow, "on_yellow") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_yellow, "on_bright_yellow") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_blue, "on_blue") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_blue, "on_bright_blue") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_magenta, "on_magenta") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_magenta, "on_bright_magenta") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_cyan, "on_cyan") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_cyan, "on_bright_cyan") << std::endl
<< " " << Text::colorize (Text::nocolor, Text::on_white, "on_white") << " "
<< Text::colorize (Text::nocolor, Text::on_bright_white, "on_bright_white") << std::endl
<< optionalBlankLine (); << optionalBlankLine ();
} }
else else

View file

@ -494,6 +494,9 @@ int runCustomReport (
} }
// Now auto colorize all rows. // Now auto colorize all rows.
Color color_due (context.config.get ("color.due", "yellow"));
Color color_overdue (context.config.get ("color.overdue", "red"));
std::string due; std::string due;
bool imminent; bool imminent;
bool overdue; bool overdue;
@ -515,21 +518,14 @@ int runCustomReport (
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
{ {
Text::color fg = Text::colorCode (tasks[row].get ("fg")); Color c (tasks[row].get ("fg") + " " + tasks[row].get ("bg"));
Text::color bg = Text::colorCode (tasks[row].get ("bg")); autoColorize (tasks[row], c);
autoColorize (tasks[row], fg, bg); table.setRowColor (row, c);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{
if (dueColumn != -1) if (dueColumn != -1)
{ {
if (overdue) c.blend (overdue ? color_overdue : color_due);
table.setCellFg (row, columnCount, Text::colorCode (context.config.get ("color.overdue", "red"))); table.setCellColor (row, columnCount, c);
else if (imminent)
table.setCellFg (row, columnCount, Text::colorCode (context.config.get ("color.due", "yellow")));
}
} }
} }
} }

View file

@ -112,7 +112,7 @@ void validSortColumns (const std::vector <std::string>&, const std::vector <std:
// rules.cpp // rules.cpp
void initializeColorRules (); void initializeColorRules ();
void autoColorize (Task&, Text::color&, Text::color&); void autoColorize (Task&, Color&);
std::string colorizeHeader (const std::string&); std::string colorizeHeader (const std::string&);
std::string colorizeMessage (const std::string&); std::string colorizeMessage (const std::string&);
std::string colorizeFootnote (const std::string&); std::string colorizeFootnote (const std::string&);

View file

@ -414,9 +414,9 @@ int handleInfo (std::string &outs)
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
{ {
if (overdue) if (overdue)
table.setCellFg (row, 1, Text::colorCode (context.config.get ("color.overdue", "red"))); table.setCellColor (row, 1, Color (context.config.get ("color.overdue", "red")));
else if (imminent) else if (imminent)
table.setCellFg (row, 1, Text::colorCode (context.config.get ("color.due", "yellow"))); table.setCellColor (row, 1, Color (context.config.get ("color.due", "yellow")));
} }
} }
@ -886,7 +886,8 @@ int handleReportHistory (std::string &outs)
table.addCell (row, 5, net); table.addCell (row, 5, net);
if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) && net) if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) && net)
table.setCellFg (row, 5, net > 0 ? Text::red: Text::green); table.setCellColor (row, 5, net > 0 ? Color (Color::red) :
Color (Color::green));
} }
if (table.rowCount ()) if (table.rowCount ())
@ -895,7 +896,8 @@ int handleReportHistory (std::string &outs)
row = table.addRow (); row = table.addRow ();
table.addCell (row, 1, "Average"); table.addCell (row, 1, "Average");
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) table.setRowFg (row, Text::bold); if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
table.setRowColor (row, Color (Color::nocolor, Color::nocolor, false, true, false));
table.addCell (row, 2, totalAdded / (table.rowCount () - 2)); table.addCell (row, 2, totalAdded / (table.rowCount () - 2));
table.addCell (row, 3, totalCompleted / (table.rowCount () - 2)); table.addCell (row, 3, totalCompleted / (table.rowCount () - 2));
table.addCell (row, 4, totalDeleted / (table.rowCount () - 2)); table.addCell (row, 4, totalDeleted / (table.rowCount () - 2));
@ -987,6 +989,10 @@ int handleReportGHistory (std::string &outs)
else else
table.setTableDashedUnderline (); table.setTableDashedUnderline ();
Color color_added (Color::black, Color::red);
Color color_completed (Color::black, Color::green);
Color color_deleted (Color::black, Color::yellow);
// Determine the longest line, and the longest "added" line. // Determine the longest line, and the longest "added" line.
int maxAddedLine = 0; int maxAddedLine = 0;
int maxRemovedLine = 0; int maxRemovedLine = 0;
@ -1000,7 +1006,6 @@ int handleReportGHistory (std::string &outs)
} }
int maxLine = maxAddedLine + maxRemovedLine; int maxLine = maxAddedLine + maxRemovedLine;
if (maxLine > 0) if (maxLine > 0)
{ {
unsigned int leftOffset = (widthOfBar * maxAddedLine) / maxLine; unsigned int leftOffset = (widthOfBar * maxAddedLine) / maxLine;
@ -1068,9 +1073,9 @@ int handleReportGHistory (std::string &outs)
while (bar.length () < leftOffset - aBar.length ()) while (bar.length () < leftOffset - aBar.length ())
bar += " "; bar += " ";
bar += Text::colorize (Text::black, Text::on_red, aBar); bar += color_added.colorize (aBar);
bar += Text::colorize (Text::black, Text::on_green, cBar); bar += color_completed.colorize (cBar);
bar += Text::colorize (Text::black, Text::on_yellow, dBar); bar += color_deleted.colorize (dBar);
} }
else else
{ {
@ -1097,11 +1102,11 @@ int handleReportGHistory (std::string &outs)
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
out << "Legend: " out << "Legend: "
<< Text::colorize (Text::black, Text::on_red, "added") << color_added.colorize ("added")
<< ", " << ", "
<< Text::colorize (Text::black, Text::on_green, "completed") << color_completed.colorize ("completed")
<< ", " << ", "
<< Text::colorize (Text::black, Text::on_yellow, "deleted") << color_deleted.colorize ("deleted")
<< optionalBlankLine () << optionalBlankLine ()
<< std::endl; << std::endl;
else else
@ -1157,12 +1162,14 @@ int handleReportTimesheet (std::string &outs)
{ {
Date endString (end); Date endString (end);
endString -= 86400; endString -= 86400;
out << std::endl
<< (color ? Text::colorize (Text::bold, Text::nocolor) : "") std::string title = start.toString (context.config.get ("dateformat", "m/d/Y"))
<< start.toString (context.config.get ("dateformat", "m/d/Y")) + " - "
<< " - " + endString.toString (context.config.get ("dateformat", "m/d/Y"));
<< endString.toString (context.config.get ("dateformat", "m/d/Y"))
<< (color ? Text::colorize () : "") Color bold (Color::nocolor, Color::nocolor, false, true, false);
std::cout << std::endl
<< (color ? bold.colorize (title) : title)
<< std::endl; << std::endl;
// Render the completed table. // Render the completed table.
@ -1207,11 +1214,9 @@ int handleReportTimesheet (std::string &outs)
if (color) if (color)
{ {
Text::color fg = Text::colorCode (task->get ("fg")); Color c (task->get ("fg") + " " + task->get ("bg"));
Text::color bg = Text::colorCode (task->get ("bg")); autoColorize (*task, c);
autoColorize (*task, fg, bg); completed.setRowColor (row, c);
completed.setRowFg (row, fg);
completed.setRowBg (row, bg);
} }
} }
} }
@ -1265,11 +1270,9 @@ int handleReportTimesheet (std::string &outs)
if (color) if (color)
{ {
Text::color fg = Text::colorCode (task->get ("fg")); Color c (task->get ("fg") + " " + task->get ("bg"));
Text::color bg = Text::colorCode (task->get ("bg")); autoColorize (*task, c);
autoColorize (*task, fg, bg); started.setRowColor (row, c);
started.setRowFg (row, fg);
started.setRowBg (row, bg);
} }
} }
} }
@ -1423,7 +1426,7 @@ std::string renderMonths (
today.day () == d && today.day () == d &&
today.month () == months.at (mpl) && today.month () == months.at (mpl) &&
today.year () == years.at (mpl)) today.year () == years.at (mpl))
table.setCellFg (row, thisCol, Text::cyan); table.setCellColor (row, thisCol, Color (Color::cyan));
foreach (task, all) foreach (task, all)
{ {
@ -1437,8 +1440,8 @@ std::string renderMonths (
due.month () == months.at (mpl) && due.month () == months.at (mpl) &&
due.year () == years.at (mpl)) due.year () == years.at (mpl))
{ {
table.setCellFg (row, thisCol, Text::black); Color c (Color::black, (due < today ? Color::red : Color::yellow));
table.setCellBg (row, thisCol, due < today ? Text::on_red : Text::on_yellow); table.setCellColor (row, thisCol, c);
} }
} }
} }
@ -1617,13 +1620,17 @@ int handleReportCalendar (std::string &outs)
} }
} }
Color color_today (Color::cyan);
Color color_due (Color::black, Color::yellow);
Color color_overdue (Color::black, Color::red);
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
out << "Legend: " out << "Legend: "
<< Text::colorize (Text::cyan, Text::nocolor, "today") << color_today.colorize ("today")
<< ", " << ", "
<< Text::colorize (Text::black, Text::on_yellow, "due") << color_due.colorize ("due")
<< ", " << ", "
<< Text::colorize (Text::black, Text::on_red, "overdue") << color_overdue.colorize ("overdue")
<< "." << "."
<< optionalBlankLine () << optionalBlankLine ()
<< std::endl; << std::endl;

View file

@ -35,34 +35,7 @@
extern Context context; extern Context context;
static std::map <std::string, Text::color> gsFg; static std::map <std::string, Color> gsColor;
static std::map <std::string, Text::color> gsBg;
////////////////////////////////////////////////////////////////////////////////
// There are three supported variants:
// 1) "fg"
// 2) "bg"
// 3) "fg bg"
static void parseColorRule (
const std::string& rule,
Text::color& fg,
Text::color& bg)
{
fg = Text::nocolor;
bg = Text::nocolor;
std::vector <std::string> words;
split (words, rule, ' ');
std::vector <std::string>::iterator it;
for (it = words.begin (); it != words.end (); ++it)
{
if (it->substr (0, 3) == "on_")
bg = Text::colorCode (*it);
else
fg = Text::colorCode (*it);
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void initializeColorRules () void initializeColorRules ()
@ -73,131 +46,80 @@ void initializeColorRules ()
{ {
if (it->substr (0, 6) == "color.") if (it->substr (0, 6) == "color.")
{ {
Text::color fg; Color c (context.config.get (*it));
Text::color bg; gsColor[*it] = c;
parseColorRule (context.config.get (*it), fg, bg);
gsFg[*it] = fg;
gsBg[*it] = bg;
} }
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void autoColorize ( void autoColorize (Task& task, Color& c)
Task& task,
Text::color& fg,
Text::color& bg)
{ {
// Note: fg, bg already contain colors specifically assigned via command. // Note: fg, bg already contain colors specifically assigned via command.
// Note: These rules form a hierarchy - the last rule is King. // Note: These rules form a hierarchy - the last rule is King.
// Colorization of the tagged. // Colorization of the tagged.
if (gsFg["color.tagged"] != Text::nocolor || if (gsColor["color.tagged"].nontrivial ())
gsBg["color.tagged"] != Text::nocolor)
{
if (task.getTagCount ()) if (task.getTagCount ())
{ c.blend (gsColor["color.tagged"]);
fg = gsFg["color.tagged"];
bg = gsBg["color.tagged"];
}
}
// Colorization of the low priority. // Colorization of the low priority.
if (gsFg["color.pri.L"] != Text::nocolor || if (gsColor["color.pri.L"].nontrivial ())
gsBg["color.pri.L"] != Text::nocolor)
{
if (task.get ("priority") == "L") if (task.get ("priority") == "L")
{ c.blend (gsColor["color.pri.L"]);
fg = gsFg["color.pri.L"];
bg = gsBg["color.pri.L"];
}
}
// Colorization of the medium priority. // Colorization of the medium priority.
if (gsFg["color.pri.M"] != Text::nocolor || if (gsColor["color.pri.M"].nontrivial ())
gsBg["color.pri.M"] != Text::nocolor)
{
if (task.get ("priority") == "M") if (task.get ("priority") == "M")
{ c.blend (gsColor["color.pri.M"]);
fg = gsFg["color.pri.M"];
bg = gsBg["color.pri.M"];
}
}
// Colorization of the high priority. // Colorization of the high priority.
if (gsFg["color.pri.H"] != Text::nocolor || if (gsColor["color.pri.H"].nontrivial ())
gsBg["color.pri.H"] != Text::nocolor)
{
if (task.get ("priority") == "H") if (task.get ("priority") == "H")
{ c.blend (gsColor["color.pri.H"]);
fg = gsFg["color.pri.H"];
bg = gsBg["color.pri.H"];
}
}
// Colorization of the priority-less. // Colorization of the priority-less.
if (gsFg["color.pri.none"] != Text::nocolor || if (gsColor["color.pri.none"].nontrivial ())
gsBg["color.pri.none"] != Text::nocolor)
{
if (task.get ("priority") == "") if (task.get ("priority") == "")
{ c.blend (gsColor["color.pri.none"]);
fg = gsFg["color.pri.none"];
bg = gsBg["color.pri.none"];
}
}
// Colorization of the active. // Colorization of the active.
if (gsFg["color.active"] != Text::nocolor || if (gsColor["color.active"].nontrivial ())
gsBg["color.active"] != Text::nocolor)
{
if (task.has ("start")) if (task.has ("start"))
{ c.blend (gsColor["color.active"]);
fg = gsFg["color.active"];
bg = gsBg["color.active"];
}
}
// Colorization by tag value. // Colorization by tag value.
std::map <std::string, Text::color>::iterator it; std::map <std::string, Color>::iterator it;
for (it = gsFg.begin (); it != gsFg.end (); ++it) for (it = gsColor.begin (); it != gsColor.end (); ++it)
{ {
if (it->first.substr (0, 10) == "color.tag.") if (it->first.substr (0, 10) == "color.tag.")
{ {
std::string value = it->first.substr (10, std::string::npos); std::string value = it->first.substr (10, std::string::npos);
if (task.hasTag (value)) if (task.hasTag (value))
{ c.blend (it->second);
fg = gsFg[it->first];
bg = gsBg[it->first];
}
} }
} }
// Colorization by project name. // Colorization by project name.
for (it = gsFg.begin (); it != gsFg.end (); ++it) for (it = gsColor.begin (); it != gsColor.end (); ++it)
{ {
if (it->first.substr (0, 14) == "color.project.") if (it->first.substr (0, 14) == "color.project.")
{ {
std::string value = it->first.substr (14, std::string::npos); std::string value = it->first.substr (14, std::string::npos);
if (task.get ("project") == value) if (task.get ("project") == value)
{ c.blend (it->second);
fg = gsFg[it->first];
bg = gsBg[it->first];
}
} }
} }
// Colorization by keyword. // Colorization by keyword.
for (it = gsFg.begin (); it != gsFg.end (); ++it) for (it = gsColor.begin (); it != gsColor.end (); ++it)
{ {
if (it->first.substr (0, 14) == "color.keyword.") if (it->first.substr (0, 14) == "color.keyword.")
{ {
std::string value = lowerCase (it->first.substr (14, std::string::npos)); std::string value = lowerCase (it->first.substr (14, std::string::npos));
std::string desc = lowerCase (task.get ("description")); std::string desc = lowerCase (task.get ("description"));
if (desc.find (value) != std::string::npos) if (desc.find (value) != std::string::npos)
{ c.blend (it->second);
fg = gsFg[it->first];
bg = gsBg[it->first];
}
} }
} }
@ -208,13 +130,11 @@ void autoColorize (
switch (getDueState (due)) switch (getDueState (due))
{ {
case 1: // imminent case 1: // imminent
fg = gsFg["color.due"]; c.blend (gsColor["color.due"]);
bg = gsBg["color.due"];
break; break;
case 2: // overdue case 2: // overdue
fg = gsFg["color.overdue"]; c.blend (gsColor["color.overdue"]);
bg = gsBg["color.overdue"];
break; break;
case 0: // not due at all case 0: // not due at all
@ -224,28 +144,16 @@ void autoColorize (
} }
// Colorization of the recurring. // Colorization of the recurring.
if (gsFg["color.recurring"] != Text::nocolor || if (gsColor["color.recurring"].nontrivial ())
gsBg["color.recurring"] != Text::nocolor)
{
if (task.has ("recur")) if (task.has ("recur"))
{ c.blend (gsColor["color.recurring"]);
fg = gsFg["color.recurring"];
bg = gsBg["color.recurring"];
}
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string colorizeHeader (const std::string& input) std::string colorizeHeader (const std::string& input)
{ {
if (gsFg["color.header"] != Text::nocolor || if (gsColor["color.header"].nontrivial ())
gsBg["color.header"] != Text::nocolor) return gsColor["color.header"].colorize (input);
{
return Text::colorize (
gsFg["color.header"],
gsBg["color.header"],
input);
}
return input; return input;
} }
@ -253,14 +161,8 @@ std::string colorizeHeader (const std::string& input)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string colorizeMessage (const std::string& input) std::string colorizeMessage (const std::string& input)
{ {
if (gsFg["color.message"] != Text::nocolor || if (gsColor["color.message"].nontrivial ())
gsBg["color.message"] != Text::nocolor) return gsColor["color.message"].colorize (input);
{
return Text::colorize (
gsFg["color.message"],
gsBg["color.message"],
input);
}
return input; return input;
} }
@ -268,14 +170,8 @@ std::string colorizeMessage (const std::string& input)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string colorizeFootnote (const std::string& input) std::string colorizeFootnote (const std::string& input)
{ {
if (gsFg["color.footnote"] != Text::nocolor || if (gsColor["color.footnote"].nontrivial ())
gsBg["color.footnote"] != Text::nocolor) return gsColor["color.footnote"].colorize (input);
{
return Text::colorize (
gsFg["color.footnote"],
gsBg["color.footnote"],
input);
}
return input; return input;
} }
@ -283,14 +179,8 @@ std::string colorizeFootnote (const std::string& input)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::string colorizeDebug (const std::string& input) std::string colorizeDebug (const std::string& input)
{ {
if (gsFg["color.debug"] != Text::nocolor || if (gsColor["color.debug"].nontrivial ())
gsBg["color.debug"] != Text::nocolor) return gsColor["color.debug"].colorize (input);
{
return Text::colorize (
gsFg["color.debug"],
gsBg["color.debug"],
input);
}
return input; return input;
} }