- Factored out filtering code.

This commit is contained in:
Paul Beckingham 2008-06-17 23:40:37 -04:00
parent 7fb3ab0c3d
commit 9bca303113
2 changed files with 298 additions and 483 deletions

View file

@ -12,6 +12,7 @@ Configurable columns in reports
1.3.0 (?) 1.3.0 (?)
+ "task calendar" now displays multiple months per line, adjustable by the + "task calendar" now displays multiple months per line, adjustable by the
"monthsperline" configuration variable. Feature added by Damian Glenny "monthsperline" configuration variable. Feature added by Damian Glenny
+ "task export" can now filter tasks like the reports.
+ Bug: Segmentation fault when no "dateformat" configuration variable + Bug: Segmentation fault when no "dateformat" configuration variable
specified specified
+ Bug: Fixed bug whereby if you have more than one task with a due date, 7 + Bug: Fixed bug whereby if you have more than one task with a due date, 7

View file

@ -285,6 +285,66 @@ int main (int argc, char** argv)
return 0; return 0;
} }
////////////////////////////////////////////////////////////////////////////////
static void filter (std::vector<T>& all, T& task)
{
std::vector <T> filtered;
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
for (unsigned int i = 0; i < all.size (); ++i)
{
T refTask (all[i]);
// Apply description filter.
std::string desc = lowerCase (refTask.getDescription ());
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ())
{
// Apply attribute filter.
matches = 0;
foreach (a, attrList)
if (a->first == "project")
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ()))
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
filtered.push_back (refTask);
}
}
}
all = filtered;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void handleAdd (const TDB& tdb, T& task, Config& conf) void handleAdd (const TDB& tdb, T& task, Config& conf)
{ {
@ -446,110 +506,62 @@ void handleList (const TDB& tdb, T& task, Config& conf)
table.setDateFormat (conf.get ("dateformat", "m/d/Y")); table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
// Split any description specified into words. filter (tasks, task);
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria.
for (unsigned int i = 0; i < tasks.size (); ++i) for (unsigned int i = 0; i < tasks.size (); ++i)
{ {
T refTask (tasks[i]); T refTask (tasks[i]);
// Apply description filter. // Now format the matching task.
std::string desc = lowerCase (refTask.getDescription ()); bool imminent = false;
unsigned int matches = 0; bool overdue = false;
for (unsigned int w = 0; w < descWords.size (); ++w) Date now;
if (desc.find (descWords[w]) != std::string::npos) std::string due = refTask.getAttribute ("due");
++matches; if (due.length ())
if (matches == descWords.size ())
{ {
// Apply attribute filter. Date dt (::atoi (due.c_str ()));
matches = 0; due = dt.toString (conf.get ("dateformat", "m/d/Y"));
foreach (a, attrList)
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
}
std::string active;
if (refTask.getAttribute ("start") != "")
active = "*";
std::string age;
std::string created = refTask.getAttribute ("entry");
if (created.length ())
{
Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt));
}
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, due);
table.addCell (row, 4, active);
if (showAge) table.addCell (row, 5, age);
table.addCell (row, (showAge ? 6 : 5), refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{ {
if (a->first == "project") if (overdue)
{ table.setCellFg (row, 3, Text::red);
if (a->second.length () <= refTask.getAttribute (a->first).length ()) else if (imminent)
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ())) table.setCellFg (row, 3, Text::yellow);
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
// Now format the matching task.
bool imminent = false;
bool overdue = false;
Date now;
std::string due = refTask.getAttribute ("due");
if (due.length ())
{
Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
}
std::string active;
if (refTask.getAttribute ("start") != "")
active = "*";
std::string age;
std::string created = refTask.getAttribute ("entry");
if (created.length ())
{
Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt));
}
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, due);
table.addCell (row, 4, active);
if (showAge) table.addCell (row, 5, age);
table.addCell (row, (showAge ? 6 : 5), refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{
if (overdue)
table.setCellFg (row, 3, Text::red);
else if (imminent)
table.setCellFg (row, 3, Text::yellow);
}
}
}
} }
} }
} }
@ -616,107 +628,60 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority); table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter); table.sortOn (1, Table::ascendingCharacter);
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria. // Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i) for (unsigned int i = 0; i < tasks.size (); ++i)
{ {
T refTask (tasks[i]); T refTask (tasks[i]);
// Apply description filter. // Now format the matching task.
std::string desc = lowerCase (refTask.getDescription ()); bool imminent = false;
unsigned int matches = 0; bool overdue = false;
for (unsigned int w = 0; w < descWords.size (); ++w) Date now;
if (desc.find (descWords[w]) != std::string::npos) std::string due = refTask.getAttribute ("due");
++matches; if (due.length ())
if (matches == descWords.size ())
{ {
// Apply attribute filter. Date dt (::atoi (due.c_str ()));
matches = 0; due = dt.toString (conf.get ("dateformat", "m/d/Y"));
foreach (a, attrList)
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
}
std::string active;
if (refTask.getAttribute ("start") != "")
active = "*";
std::string age;
std::string created = refTask.getAttribute ("entry");
if (created.length ())
{
Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt));
}
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{ {
if (a->first == "project") if (overdue)
{ table.setCellFg (row, 3, Text::red);
if (a->second.length () <= refTask.getAttribute (a->first).length ()) else if (imminent)
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ())) table.setCellFg (row, 3, Text::yellow);
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
// Now format the matching task.
bool imminent = false;
bool overdue = false;
Date now;
std::string due = refTask.getAttribute ("due");
if (due.length ())
{
Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
}
std::string active;
if (refTask.getAttribute ("start") != "")
active = "*";
std::string age;
std::string created = refTask.getAttribute ("entry");
if (created.length ())
{
Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt));
}
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{
if (overdue)
table.setCellFg (row, 3, Text::red);
else if (imminent)
table.setCellFg (row, 3, Text::yellow);
}
}
}
} }
} }
} }
@ -779,76 +744,29 @@ void handleCompleted (const TDB& tdb, T& task, Config& conf)
table.sortOn (0, Table::ascendingDate); table.sortOn (0, Table::ascendingDate);
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria. // Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i) for (unsigned int i = 0; i < tasks.size (); ++i)
{ {
T refTask (tasks[i]); T refTask (tasks[i]);
// Apply description filter. // Now format the matching task.
std::string desc = lowerCase (refTask.getDescription ()); Date end (::atoi (refTask.getAttribute ("end").c_str ()));
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ()) // All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, end.toString (conf.get ("dateformat", "m/d/Y")));
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getDescription ());
if (conf.get ("color", true))
{ {
// Apply attribute filter. Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
matches = 0; Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
foreach (a, attrList) autoColorize (refTask, fg, bg);
{ table.setRowFg (row, fg);
if (a->first == "project") table.setRowBg (row, bg);
{
if (a->second.length () <= refTask.getAttribute (a->first).length ())
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ()))
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
// Now format the matching task.
Date end (::atoi (refTask.getAttribute ("end").c_str ()));
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, end.toString (conf.get ("dateformat", "m/d/Y")));
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
}
}
}
} }
} }
@ -1097,129 +1015,82 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority); table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter); table.sortOn (1, Table::ascendingCharacter);
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria. // Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i) for (unsigned int i = 0; i < tasks.size (); ++i)
{ {
T refTask (tasks[i]); T refTask (tasks[i]);
// Apply description filter. Date now;
std::string desc = lowerCase (refTask.getDescription ());
unsigned int matches = 0;
for (unsigned int w = 0; w < descWords.size (); ++w)
if (desc.find (descWords[w]) != std::string::npos)
++matches;
if (matches == descWords.size ()) std::string started = refTask.getAttribute ("start");
if (started.length ())
{ {
// Apply attribute filter. Date dt (::atoi (started.c_str ()));
matches = 0; started = dt.toString (conf.get ("dateformat", "m/d/Y"));
foreach (a, attrList) }
std::string entered = refTask.getAttribute ("entry");
if (entered.length ())
{
Date dt (::atoi (entered.c_str ()));
entered = dt.toString (conf.get ("dateformat", "m/d/Y"));
}
// Now format the matching task.
bool imminent = false;
bool overdue = false;
std::string due = refTask.getAttribute ("due");
if (due.length ())
{
Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
}
std::string age;
std::string created = refTask.getAttribute ("entry");
if (created.length ())
{
Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt));
}
// Make a list of tags.
std::string tags;
std::vector <std::string> all;
refTask.getTags (all);
join (tags, " ", all);
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, entered);
table.addCell (row, 4, started);
table.addCell (row, 5, due);
table.addCell (row, 6, age);
table.addCell (row, 7, tags);
table.addCell (row, 8, refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{ {
if (a->first == "project") if (overdue)
{ table.setCellFg (row, 3, Text::red);
if (a->second.length () <= refTask.getAttribute (a->first).length ()) else if (imminent)
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ())) table.setCellFg (row, 3, Text::yellow);
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
Date now;
std::string started = refTask.getAttribute ("start");
if (started.length ())
{
Date dt (::atoi (started.c_str ()));
started = dt.toString (conf.get ("dateformat", "m/d/Y"));
}
std::string entered = refTask.getAttribute ("entry");
if (entered.length ())
{
Date dt (::atoi (entered.c_str ()));
entered = dt.toString (conf.get ("dateformat", "m/d/Y"));
}
// Now format the matching task.
bool imminent = false;
bool overdue = false;
std::string due = refTask.getAttribute ("due");
if (due.length ())
{
Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
}
std::string age;
std::string created = refTask.getAttribute ("entry");
if (created.length ())
{
Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt));
}
// Make a list of tags.
std::string tags;
std::vector <std::string> all;
refTask.getTags (all);
join (tags, " ", all);
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, entered);
table.addCell (row, 4, started);
table.addCell (row, 5, due);
table.addCell (row, 6, age);
table.addCell (row, 7, tags);
table.addCell (row, 8, refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{
if (overdue)
table.setCellFg (row, 3, Text::red);
else if (imminent)
table.setCellFg (row, 3, Text::yellow);
}
}
}
} }
} }
} }
@ -1468,110 +1339,62 @@ void handleReportNext (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority); table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter); table.sortOn (1, Table::ascendingCharacter);
// Split any description specified into words.
std::vector <std::string> descWords;
split (descWords, lowerCase (task.getDescription ()), ' ');
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria. // Iterate over each task, and apply selection criteria.
foreach (i, matching) foreach (i, matching)
{ {
T refTask (pending[*i]); T refTask (pending[*i]);
// Apply description filter. // Now format the matching task.
std::string desc = lowerCase (refTask.getDescription ()); bool imminent = false;
unsigned int matches = 0; bool overdue = false;
for (unsigned int w = 0; w < descWords.size (); ++w) Date now;
if (desc.find (descWords[w]) != std::string::npos) std::string due = refTask.getAttribute ("due");
++matches; if (due.length ())
if (matches == descWords.size ())
{ {
// Apply attribute filter. Date dt (::atoi (due.c_str ()));
matches = 0; due = dt.toString (conf.get ("dateformat", "m/d/Y"));
foreach (a, attrList)
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
}
std::string active;
if (refTask.getAttribute ("start") != "")
active = "*";
std::string age;
std::string created = refTask.getAttribute ("entry");
if (created.length ())
{
Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt));
}
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, due);
table.addCell (row, 4, active);
if (showAge) table.addCell (row, 5, age);
table.addCell (row, (showAge ? 6 : 5), refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{ {
if (a->first == "project") if (overdue)
{ table.setCellFg (row, 3, Text::red);
if (a->second.length () <= refTask.getAttribute (a->first).length ()) else if (imminent)
if (a->second == refTask.getAttribute (a->first).substr (0, a->second.length ())) table.setCellFg (row, 3, Text::yellow);
++matches;
}
else if (a->second == refTask.getAttribute (a->first))
++matches;
}
if (matches == attrList.size ())
{
// Apply tag filter.
matches = 0;
for (unsigned int t = 0; t < tagList.size (); ++t)
if (refTask.hasTag (tagList[t]))
++matches;
if (matches == tagList.size ())
{
// Now format the matching task.
bool imminent = false;
bool overdue = false;
Date now;
std::string due = refTask.getAttribute ("due");
if (due.length ())
{
Date dt (::atoi (due.c_str ()));
due = dt.toString (conf.get ("dateformat", "m/d/Y"));
overdue = (dt < now) ? true : false;
Date nextweek = now + 7 * 86400;
imminent = dt < nextweek ? true : false;
}
std::string active;
if (refTask.getAttribute ("start") != "")
active = "*";
std::string age;
std::string created = refTask.getAttribute ("entry");
if (created.length ())
{
Date dt (::atoi (created.c_str ()));
formatTimeDeltaDays (age, (time_t) (now - dt));
}
// All criteria match, so add refTask to the output table.
int row = table.addRow ();
table.addCell (row, 0, refTask.getId ());
table.addCell (row, 1, refTask.getAttribute ("project"));
table.addCell (row, 2, refTask.getAttribute ("priority"));
table.addCell (row, 3, due);
table.addCell (row, 4, active);
if (showAge) table.addCell (row, 5, age);
table.addCell (row, (showAge ? 6 : 5), refTask.getDescription ());
if (conf.get ("color", true))
{
Text::color fg = Text::colorCode (refTask.getAttribute ("fg"));
Text::color bg = Text::colorCode (refTask.getAttribute ("bg"));
autoColorize (refTask, fg, bg);
table.setRowFg (row, fg);
table.setRowBg (row, bg);
if (fg == Text::nocolor)
{
if (overdue)
table.setCellFg (row, 3, Text::red);
else if (imminent)
table.setCellFg (row, 3, Text::yellow);
}
}
}
} }
} }
} }
@ -2087,15 +1910,8 @@ void handleReportActive (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority); table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter); table.sortOn (1, Table::ascendingCharacter);
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
// Iterate over each task, and apply selection criteria. // Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i) for (unsigned int i = 0; i < tasks.size (); ++i)
{ {
T refTask (tasks[i]); T refTask (tasks[i]);
@ -2202,17 +2018,10 @@ void handleReportOverdue (const TDB& tdb, T& task, Config& conf)
table.sortOn (2, Table::descendingPriority); table.sortOn (2, Table::descendingPriority);
table.sortOn (1, Table::ascendingCharacter); table.sortOn (1, Table::ascendingCharacter);
// Get all the tags to match against.
std::vector <std::string> tagList;
task.getTags (tagList);
// Get all the attributes to match against.
std::map <std::string, std::string> attrList;
task.getAttributes (attrList);
Date now; Date now;
// Iterate over each task, and apply selection criteria. // Iterate over each task, and apply selection criteria.
filter (tasks, task);
for (unsigned int i = 0; i < tasks.size (); ++i) for (unsigned int i = 0; i < tasks.size (); ++i)
{ {
T refTask (tasks[i]); T refTask (tasks[i]);
@ -2479,7 +2288,11 @@ void handleDone (const TDB& tdb, T& task, Config& conf)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void handleExport (const TDB& tdb, T& task, Config& conf) void handleExport (const TDB& tdb, T& task, Config& conf)
{ {
// Use the description as a file name, then clobber the description so the
// file name isn't used for filtering.
std::string file = trim (task.getDescription ()); std::string file = trim (task.getDescription ());
task.setDescription ("");
if (file.length () > 0) if (file.length () > 0)
{ {
std::ofstream out (file.c_str ()); std::ofstream out (file.c_str ());
@ -2501,6 +2314,7 @@ void handleExport (const TDB& tdb, T& task, Config& conf)
std::vector <T> all; std::vector <T> all;
tdb.allT (all); tdb.allT (all);
filter (all, task);
foreach (t, all) foreach (t, all)
{ {
out << t->composeCSV ().c_str (); out << t->composeCSV ().c_str ();