colors: Add rule.colors.merge

This commit is contained in:
Tomas Babej 2015-09-01 07:36:41 +02:00 committed by Paul Beckingham
parent ef16020cbb
commit 7989177f7c
2 changed files with 74 additions and 59 deletions

View file

@ -165,6 +165,7 @@ std::string Config::_defaults =
"rule.precedence.color=deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.\n" "rule.precedence.color=deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.\n"
"\n" "\n"
"# General decoration\n" "# General decoration\n"
"rule.color.merge=yes\n"
"color.label=\n" "color.label=\n"
"color.label.sort=\n" "color.label.sort=\n"
"color.alternate=on gray2\n" "color.alternate=on gray2\n"
@ -239,6 +240,7 @@ std::string Config::_defaults =
"rule.precedence.color=deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.\n" "rule.precedence.color=deleted,completed,active,keyword.,tag.,project.,overdue,scheduled,due.today,due,blocked,blocking,recurring,tagged,uda.\n"
"\n" "\n"
"# General decoration\n" "# General decoration\n"
"rule.color.merge=yes\n"
"color.label=\n" "color.label=\n"
"color.label.sort=\n" "color.label.sort=\n"
"color.alternate=\n" "color.alternate=\n"

View file

@ -88,58 +88,68 @@ void initializeColorRules ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeBlocked (Task& task, const Color& base, Color& c) static void applyColor (const Color& base, Color& c, bool merge)
{
if (merge)
c.blend (base);
else
c = base;
}
////////////////////////////////////////////////////////////////////////////////
static void colorizeBlocked (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.is_blocked) if (task.is_blocked)
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeBlocking (Task& task, const Color& base, Color& c) static void colorizeBlocking (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.is_blocking) if (task.is_blocking)
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeTagged (Task& task, const Color& base, Color& c) static void colorizeTagged (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.getTagCount ()) if (task.getTagCount ())
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeActive (Task& task, const Color& base, Color& c) static void colorizeActive (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.has ("start") && if (task.has ("start") &&
!task.has ("end")) !task.has ("end"))
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeScheduled (Task& task, const Color& base, Color& c) static void colorizeScheduled (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.has ("scheduled") && if (task.has ("scheduled") &&
Date (task.get_date ("scheduled")) <= now) Date (task.get_date ("scheduled")) <= now)
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeUntil (Task& task, const Color& base, Color& c) static void colorizeUntil (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.has ("until")) if (task.has ("until"))
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeTag (Task& task, const std::string& rule, const Color& base, Color& c) static void colorizeTag (Task& task, const std::string& rule, const Color& base, Color& c, bool merge)
{ {
if (task.hasTag (rule.substr (10))) if (task.hasTag (rule.substr (10)))
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeProject (Task& task, const std::string& rule, const Color& base, Color& c) static void colorizeProject (Task& task, const std::string& rule, const Color& base, Color& c, bool merge)
{ {
// Observe the case sensitivity setting. // Observe the case sensitivity setting.
bool sensitive = context.config.getBoolean ("search.case.sensitive"); bool sensitive = context.config.getBoolean ("search.case.sensitive");
@ -150,25 +160,25 @@ static void colorizeProject (Task& task, const std::string& rule, const Color& b
// Match project names leftmost. // Match project names leftmost.
if (rule_trunc.length () <= project.length ()) if (rule_trunc.length () <= project.length ())
if (compare (rule_trunc, project.substr (0, rule_trunc.length ()), sensitive)) if (compare (rule_trunc, project.substr (0, rule_trunc.length ()), sensitive))
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeProjectNone (Task& task, const Color& base, Color& c) static void colorizeProjectNone (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.get ("project") == "") if (task.get ("project") == "")
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeTagNone (Task& task, const Color& base, Color& c) static void colorizeTagNone (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.getTagCount () == 0) if (task.getTagCount () == 0)
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeKeyword (Task& task, const std::string& rule, const Color& base, Color& c) static void colorizeKeyword (Task& task, const std::string& rule, const Color& base, Color& c, bool merge)
{ {
// Observe the case sensitivity setting. // Observe the case sensitivity setting.
bool sensitive = context.config.getBoolean ("search.case.sensitive"); bool sensitive = context.config.getBoolean ("search.case.sensitive");
@ -176,7 +186,7 @@ static void colorizeKeyword (Task& task, const std::string& rule, const Color& b
// The easiest thing to check is the description, because it is just one // The easiest thing to check is the description, because it is just one
// attribute. // attribute.
if (find (task.get ("description"), rule.substr (14), sensitive) != std::string::npos) if (find (task.get ("description"), rule.substr (14), sensitive) != std::string::npos)
c.blend (base); applyColor (base, c, merge);
// Failing the description check, look at all annotations, returning on the // Failing the description check, look at all annotations, returning on the
// first match. // first match.
@ -187,7 +197,7 @@ static void colorizeKeyword (Task& task, const std::string& rule, const Color& b
if (it.first.substr (0, 11) == "annotation_" && if (it.first.substr (0, 11) == "annotation_" &&
find (it.second, rule.substr (14), sensitive) != std::string::npos) find (it.second, rule.substr (14), sensitive) != std::string::npos)
{ {
c.blend (base); applyColor (base, c, merge);
return; return;
} }
} }
@ -195,28 +205,27 @@ static void colorizeKeyword (Task& task, const std::string& rule, const Color& b
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeUDA (Task& task, const std::string& rule, const Color& base, Color& c) static void colorizeUDA (Task& task, const std::string& rule, const Color& base, Color& c, bool merge)
{ {
// Is the rule color.uda.name.value or color.uda.name? // Is the rule color.uda.name.value or color.uda.name?
size_t pos = rule.find (".", 10); size_t pos = rule.find (".", 10);
if (pos == std::string::npos) if (pos == std::string::npos)
{ {
if (task.has (rule.substr (10))) if (task.has (rule.substr (10)))
c.blend (base); applyColor (base, c, merge);
} }
else else
{ {
const std::string uda = rule.substr (10, pos - 10); const std::string uda = rule.substr (10, pos - 10);
const std::string val = rule.substr (pos + 1); const std::string val = rule.substr (pos + 1);
if (val == "none" && ! task.has (uda)) if (val == "none" && ! task.has (uda) ||
c.blend (base); task.get (uda) == val)
else if (task.get (uda) == val) applyColor (base, c, merge);
c.blend (base);
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeDue (Task& task, const Color& base, Color& c) static void colorizeDue (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.has ("due")) if (task.has ("due"))
{ {
@ -224,12 +233,12 @@ static void colorizeDue (Task& task, const Color& base, Color& c)
if (status != Task::completed && if (status != Task::completed &&
status != Task::deleted && status != Task::deleted &&
task.getDateState ("due") == Task::dateAfterToday) task.getDateState ("due") == Task::dateAfterToday)
c.blend (base); applyColor (base, c, merge);
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeDueToday (Task& task, const Color& base, Color& c) static void colorizeDueToday (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.has ("due")) if (task.has ("due"))
{ {
@ -238,12 +247,12 @@ static void colorizeDueToday (Task& task, const Color& base, Color& c)
if (status != Task::completed && if (status != Task::completed &&
status != Task::deleted && status != Task::deleted &&
(dateState == Task::dateLaterToday || dateState == Task::dateEarlierToday)) (dateState == Task::dateLaterToday || dateState == Task::dateEarlierToday))
c.blend (base); applyColor (base, c, merge);
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeOverdue (Task& task, const Color& base, Color& c) static void colorizeOverdue (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.has ("due")) if (task.has ("due"))
{ {
@ -251,29 +260,29 @@ static void colorizeOverdue (Task& task, const Color& base, Color& c)
if (status != Task::completed && if (status != Task::completed &&
status != Task::deleted && status != Task::deleted &&
task.getDateState ("due") == Task::dateBeforeToday) task.getDateState ("due") == Task::dateBeforeToday)
c.blend (base); applyColor (base, c, merge);
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeRecurring (Task& task, const Color& base, Color& c) static void colorizeRecurring (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.has ("recur")) if (task.has ("recur"))
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeCompleted (Task& task, const Color& base, Color& c) static void colorizeCompleted (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.getStatus () == Task::completed) if (task.getStatus () == Task::completed)
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
static void colorizeDeleted (Task& task, const Color& base, Color& c) static void colorizeDeleted (Task& task, const Color& base, Color& c, bool merge)
{ {
if (task.getStatus () == Task::deleted) if (task.getStatus () == Task::deleted)
c.blend (base); applyColor (base, c, merge);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -287,36 +296,40 @@ void autoColorize (Task& task, Color& c)
return; return;
} }
bool merge = context.config.getBoolean ("rule.color.merge");
// Note: c already contains colors specifically assigned via command. // Note: c already contains colors specifically assigned via command.
// Note: These rules form a hierarchy - the last rule is King, hence the // Note: These rules form a hierarchy - the last rule is King, hence the
// reverse iterator. // reverse iterator.
for (auto r = gsPrecedence.rbegin (); r != gsPrecedence.rend (); ++r) for (auto r = gsPrecedence.rbegin (); r != gsPrecedence.rend (); ++r)
{ {
Color base = gsColor[*r]; Color base = gsColor[*r];
if (base.nontrivial ()) if (base.nontrivial ())
{ {
if (*r == "color.blocked") colorizeBlocked (task, base, c); if (*r == "color.blocked") colorizeBlocked (task, base, c, merge);
else if (*r == "color.blocking") colorizeBlocking (task, base, c); else if (*r == "color.blocking") colorizeBlocking (task, base, c, merge);
else if (*r == "color.tagged") colorizeTagged (task, base, c); else if (*r == "color.tagged") colorizeTagged (task, base, c, merge);
else if (*r == "color.active") colorizeActive (task, base, c); else if (*r == "color.active") colorizeActive (task, base, c, merge);
else if (*r == "color.scheduled") colorizeScheduled (task, base, c); else if (*r == "color.scheduled") colorizeScheduled (task, base, c, merge);
else if (*r == "color.until") colorizeUntil (task, base, c); else if (*r == "color.until") colorizeUntil (task, base, c, merge);
else if (*r == "color.project.none") colorizeProjectNone (task, base, c); else if (*r == "color.project.none") colorizeProjectNone (task, base, c, merge);
else if (*r == "color.tag.none") colorizeTagNone (task, base, c); else if (*r == "color.tag.none") colorizeTagNone (task, base, c, merge);
else if (*r == "color.due") colorizeDue (task, base, c); else if (*r == "color.due") colorizeDue (task, base, c, merge);
else if (*r == "color.due.today") colorizeDueToday (task, base, c); else if (*r == "color.due.today") colorizeDueToday (task, base, c, merge);
else if (*r == "color.overdue") colorizeOverdue (task, base, c); else if (*r == "color.overdue") colorizeOverdue (task, base, c, merge);
else if (*r == "color.recurring") colorizeRecurring (task, base, c); else if (*r == "color.recurring") colorizeRecurring (task, base, c, merge);
else if (*r == "color.completed") colorizeCompleted (task, base, c); else if (*r == "color.completed") colorizeCompleted (task, base, c, merge);
else if (*r == "color.deleted") colorizeDeleted (task, base, c); else if (*r == "color.deleted") colorizeDeleted (task, base, c, merge);
// Wildcards // Wildcards
else if (r->substr (0, 10) == "color.tag.") colorizeTag (task, *r, base, c); else if (r->substr (0, 10) == "color.tag.") colorizeTag (task, *r, base, c, merge);
else if (r->substr (0, 14) == "color.project.") colorizeProject (task, *r, base, c); else if (r->substr (0, 14) == "color.project.") colorizeProject (task, *r, base, c, merge);
else if (r->substr (0, 14) == "color.keyword.") colorizeKeyword (task, *r, base, c); else if (r->substr (0, 14) == "color.keyword.") colorizeKeyword (task, *r, base, c, merge);
else if (r->substr (0, 10) == "color.uda.") colorizeUDA (task, *r, base, c); else if (r->substr (0, 10) == "color.uda.") colorizeUDA (task, *r, base, c, merge);
} }
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////