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")
{
if (value != "")
Text::guessColor (value);
// TODO Determine whether color abbreviations are supported, and if so,
// modify 'value' here accordingly.
}
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);
}
////////////////////////////////////////////////////////////////////////////////
bool Color::nontrivial ()
{
if (value != (_COLOR_NOFG | _COLOR_NOBG))
return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////
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&, const std::string&);
bool nontrivial ();
private:
int find (const std::string&);
std::string fg ();

View file

@ -582,7 +582,7 @@ void TDB::undo ()
row = table.addRow ();
table.addCell (row, 0, *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)
@ -599,8 +599,8 @@ void TDB::undo ()
if (priorValue != currentValue)
{
table.setCellFg (row, 1, Text::red);
table.setCellFg (row, 2, Text::green);
table.setCellColor (row, 1, Color (Color::red));
table.setCellColor (row, 2, Color (Color::green));
}
}
}
@ -610,7 +610,7 @@ void TDB::undo ()
row = table.addRow ();
table.addCell (row, 0, *name);
table.addCell (row, 2, renderAttribute (*name, after.get (*name)));
table.setCellFg (row, 2, Text::green);
table.setCellColor (row, 2, Color (Color::green));
}
}
else
@ -621,7 +621,7 @@ void TDB::undo ()
row = table.addRow ();
table.addCell (row, 0, 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);
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);
mColor["table"] = 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];
sprintf (id, "col:%d", column);
mFg[id] = Text::colorName (fg);
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);
mColor[id] = c;
}
////////////////////////////////////////////////////////////////////////////////
@ -155,7 +125,7 @@ void Table::setColumnUnderline (int column)
{
char id[12];
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];
sprintf (id, "row:%d", row);
mFg[id] = Text::colorName (fg);
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);
mColor[id] = 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];
sprintf (id, "cell:%d,%d", row, col);
mFg[id] = Text::colorName (fg);
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);
mColor[id] = 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];
sprintf (idCell, "cell:%d,%d", row, col);
if (mFg.find (idCell) != mFg.end ())
return Text::colorCode (mFg[idCell]);
if (mColor.find (idCell) != mColor.end ())
return mColor[idCell];
char idRow[12];
sprintf (idRow, "row:%d", row);
if (mFg.find (idRow) != mFg.end ())
return Text::colorCode (mFg[idRow]);
if (mColor.find (idRow) != mColor.end ())
return mColor[idRow];
char idCol[12];
sprintf (idCol, "col:%d", col);
if (mFg.find (idCol) != mFg.end ())
return Text::colorCode (mFg[idCol]);
if (mColor.find (idCol) != mColor.end ())
return mColor[idCol];
if (mFg.find ("table") != mFg.end ())
return Text::colorCode (mFg["table"]);
if (mColor.find ("table") != mColor.end ())
return mColor["table"];
return Text::nocolor;
return Color ();
}
////////////////////////////////////////////////////////////////////////////////
Text::color Table::getHeaderFg (int col)
Color Table::getHeaderColor (int col)
{
char idCol[12];
sprintf (idCol, "col:%d", col);
return mFg.find (idCol) != mFg.end () ? Text::colorCode (mFg[idCol])
: mFg.find ("table") != mFg.end () ? Text::colorCode (mFg["table"])
: Text::nocolor;
return mColor.find (idCol) != mColor.end () ? mColor[idCol]
: mColor.find ("table") != mColor.end () ? mColor["table"]
: Color ();
}
////////////////////////////////////////////////////////////////////////////////
Text::color Table::getBg (const int row, const 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)
Color Table::getHeaderUnderline (int col)
{
char idCol[12];
sprintf (idCol, "col:%d", col);
return mBg.find (idCol) != mBg.end () ? Text::colorCode (mBg[idCol])
: mBg.find ("table") != mBg.end () ? Text::colorCode (mBg["table"])
: 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;
return mUnderline.find (idCol) != mUnderline.end () ? mUnderline[idCol]
: Color ();
}
////////////////////////////////////////////////////////////////////////////////
@ -584,10 +485,9 @@ const std::string Table::formatHeader (
{
assert (width > 0);
Text::color fg = getHeaderFg (col);
Text::color bg = getHeaderBg (col);
std::string data = mColumns[col];
Text::color decoration = getHeaderUnderline (col);
Color c = getHeaderColor (col);
std::string data = mColumns[col];
c.blend (getHeaderUnderline (col));
std::string pad = "";
std::string intraPad = "";
@ -609,11 +509,7 @@ const std::string Table::formatHeader (
for (int i = 0; i < getIntraPadding (); ++i)
intraPad += " ";
return Text::colorize (
fg, bg,
Text::colorize (
decoration, Text::nocolor,
pad + preJust + data + postJust + pad) + intraPad);
return c.colorize (pad + preJust + data + postJust + pad) + intraPad;
}
////////////////////////////////////////////////////////////////////////////////
@ -638,9 +534,8 @@ const std::string Table::formatHeaderDashedUnderline (
{
assert (width > 0);
Text::color fg = getHeaderFg (col);
Text::color bg = getHeaderBg (col);
Text::color decoration = getHeaderUnderline (col);
Color c = getHeaderColor (col);
c.blend (getHeaderUnderline (col));
std::string data = "";
for (int i = 0; i < width; ++i)
@ -659,11 +554,7 @@ const std::string Table::formatHeaderDashedUnderline (
for (int i = 0; i < getIntraPadding (); ++i)
intraPad += " ";
return Text::colorize (
fg, bg,
Text::colorize (
decoration, Text::nocolor,
pad + data + pad) + intraPad);
return c.colorize (pad + data + pad) + intraPad;
}
////////////////////////////////////////////////////////////////////////////////
@ -677,8 +568,7 @@ void Table::formatCell (
{
assert (width > 0);
Text::color fg = getFg (row, col);
Text::color bg = getBg (row, col);
Color c = getColor (row, col);
just justification = getJustification (row, col);
std::string data = getCell (row, col);
@ -722,8 +612,7 @@ void Table::formatCell (
postJust += " ";
}
lines.push_back (
Text::colorize (fg, bg, pad + preJust + chunks[chunk] + postJust + pad + intraPad));
lines.push_back (c.colorize (pad + preJust + chunks[chunk] + postJust + pad + intraPad));
}
// 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)
pad += " ";
blank = Text::colorize (fg, bg, pad + intraPad);
blank = c.colorize (pad + intraPad);
}
////////////////////////////////////////////////////////////////////////////////

View file

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

View file

@ -476,14 +476,16 @@ int handleVersion (std::string &outs)
}
}
Color bold ("bold");
out << "Copyright (C) 2006 - 2009, P. Beckingham."
<< std::endl
<< ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
? Text::colorize (Text::bold, Text::nocolor, PACKAGE)
? bold.colorize (PACKAGE)
: PACKAGE)
<< " "
<< ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
? Text::colorize (Text::bold, Text::nocolor, VERSION)
? bold.colorize (VERSION)
: VERSION)
<< std::endl
<< disclaimer.render ()
@ -1139,8 +1141,9 @@ int handleDuplicate (std::string &outs)
void handleShell ()
{
// 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))
? Text::colorize (Text::bold, Text::nocolor, PACKAGE_STRING)
? bold.colorize (PACKAGE_STRING)
: PACKAGE_STRING)
<< " shell"
<< std::endl
@ -1216,77 +1219,8 @@ int handleColor (std::string &outs)
std::stringstream out;
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
{
out << optionalBlankLine () << "Foreground" << std::endl
<< " "
<< 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
out
// TODO Add new "color" command here.
<< optionalBlankLine ();
}
else

View file

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

View file

@ -112,7 +112,7 @@ void validSortColumns (const std::vector <std::string>&, const std::vector <std:
// rules.cpp
void initializeColorRules ();
void autoColorize (Task&, Text::color&, Text::color&);
void autoColorize (Task&, Color&);
std::string colorizeHeader (const std::string&);
std::string colorizeMessage (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 (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)
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);
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 ())
@ -895,7 +896,8 @@ int handleReportHistory (std::string &outs)
row = table.addRow ();
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, 3, totalCompleted / (table.rowCount () - 2));
table.addCell (row, 4, totalDeleted / (table.rowCount () - 2));
@ -987,6 +989,10 @@ int handleReportGHistory (std::string &outs)
else
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.
int maxAddedLine = 0;
int maxRemovedLine = 0;
@ -1000,7 +1006,6 @@ int handleReportGHistory (std::string &outs)
}
int maxLine = maxAddedLine + maxRemovedLine;
if (maxLine > 0)
{
unsigned int leftOffset = (widthOfBar * maxAddedLine) / maxLine;
@ -1068,9 +1073,9 @@ int handleReportGHistory (std::string &outs)
while (bar.length () < leftOffset - aBar.length ())
bar += " ";
bar += Text::colorize (Text::black, Text::on_red, aBar);
bar += Text::colorize (Text::black, Text::on_green, cBar);
bar += Text::colorize (Text::black, Text::on_yellow, dBar);
bar += color_added.colorize (aBar);
bar += color_completed.colorize (cBar);
bar += color_deleted.colorize (dBar);
}
else
{
@ -1097,11 +1102,11 @@ int handleReportGHistory (std::string &outs)
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
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 ()
<< std::endl;
else
@ -1157,13 +1162,15 @@ int handleReportTimesheet (std::string &outs)
{
Date endString (end);
endString -= 86400;
out << std::endl
<< (color ? Text::colorize (Text::bold, Text::nocolor) : "")
<< start.toString (context.config.get ("dateformat", "m/d/Y"))
<< " - "
<< endString.toString (context.config.get ("dateformat", "m/d/Y"))
<< (color ? Text::colorize () : "")
<< std::endl;
std::string title = start.toString (context.config.get ("dateformat", "m/d/Y"))
+ " - "
+ endString.toString (context.config.get ("dateformat", "m/d/Y"));
Color bold (Color::nocolor, Color::nocolor, false, true, false);
std::cout << std::endl
<< (color ? bold.colorize (title) : title)
<< std::endl;
// Render the completed table.
Table completed;
@ -1207,11 +1214,9 @@ int handleReportTimesheet (std::string &outs)
if (color)
{
Text::color fg = Text::colorCode (task->get ("fg"));
Text::color bg = Text::colorCode (task->get ("bg"));
autoColorize (*task, fg, bg);
completed.setRowFg (row, fg);
completed.setRowBg (row, bg);
Color c (task->get ("fg") + " " + task->get ("bg"));
autoColorize (*task, c);
completed.setRowColor (row, c);
}
}
}
@ -1265,11 +1270,9 @@ int handleReportTimesheet (std::string &outs)
if (color)
{
Text::color fg = Text::colorCode (task->get ("fg"));
Text::color bg = Text::colorCode (task->get ("bg"));
autoColorize (*task, fg, bg);
started.setRowFg (row, fg);
started.setRowBg (row, bg);
Color c (task->get ("fg") + " " + task->get ("bg"));
autoColorize (*task, c);
started.setRowColor (row, c);
}
}
}
@ -1423,7 +1426,7 @@ std::string renderMonths (
today.day () == d &&
today.month () == months.at (mpl) &&
today.year () == years.at (mpl))
table.setCellFg (row, thisCol, Text::cyan);
table.setCellColor (row, thisCol, Color (Color::cyan));
foreach (task, all)
{
@ -1437,8 +1440,8 @@ std::string renderMonths (
due.month () == months.at (mpl) &&
due.year () == years.at (mpl))
{
table.setCellFg (row, thisCol, Text::black);
table.setCellBg (row, thisCol, due < today ? Text::on_red : Text::on_yellow);
Color c (Color::black, (due < today ? Color::red : Color::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))
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 ()
<< std::endl;

View file

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