mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Enhancements - custom reports
- Converted active, overdue and completed reports to custom reports. - Added new recurring report. - Added support for new 'end' column, which is the completion date.
This commit is contained in:
parent
c9807f4636
commit
788e264378
6 changed files with 69 additions and 375 deletions
|
@ -45,32 +45,59 @@
|
||||||
// upgrade program to make the change, or c) this.
|
// upgrade program to make the change, or c) this.
|
||||||
Config::Config ()
|
Config::Config ()
|
||||||
{
|
{
|
||||||
(*this)["report.long.description"] = "Lists all task, all data, matching the specified criteria"; // TODO i18n
|
set ("report.long.description", "Lists all task, all data, matching the specified criteria"); // TODO i18n
|
||||||
(*this)["report.long.columns"] = "id,project,priority,entry,start,due,recur,age,tags,description"; // TODO i18n
|
set ("report.long.columns", "id,project,priority,entry,start,due,recur,age,tags,description"); // TODO i18n
|
||||||
(*this)["report.long.labels"] = "ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description"; // TODO i18n
|
set ("report.long.labels", "ID,Project,Pri,Added,Started,Due,Recur,Age,Tags,Description"); // TODO i18n
|
||||||
(*this)["report.long.sort"] = "due+,priority-,project+"; // TODO i18n
|
set ("report.long.sort", "due+,priority-,project+"); // TODO i18n
|
||||||
|
set ("report.long.filter", "status:pending"); // TODO i18n
|
||||||
|
|
||||||
(*this)["report.list.description"] = "Lists all tasks matching the specified criteria"; // TODO i18n
|
set ("report.list.description", "Lists all tasks matching the specified criteria"); // TODO i18n
|
||||||
(*this)["report.list.columns"] = "id,project,priority,due,active,age,description"; // TODO i18n
|
set ("report.list.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||||
(*this)["report.list.labels"] = "ID,Project,Pri,Due,Active,Age,Description"; // TODO i18n
|
set ("report.list.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||||
(*this)["report.list.sort"] = "due+,priority-,project+"; // TODO i18n
|
set ("report.list.sort", "due+,priority-,project+"); // TODO i18n
|
||||||
|
set ("report.list.filter", "status:pending"); // TODO i18n
|
||||||
|
|
||||||
(*this)["report.ls.description"] = "Minimal listing of all tasks matching the specified criteria"; // TODO i18n
|
set ("report.ls.description", "Minimal listing of all tasks matching the specified criteria"); // TODO i18n
|
||||||
(*this)["report.ls.columns"] = "id,project,priority,description"; // TODO i18n
|
set ("report.ls.columns", "id,project,priority,description"); // TODO i18n
|
||||||
(*this)["report.ls.labels"] = "ID,Project,Pri,Description"; // TODO i18n
|
set ("report.ls.labels", "ID,Project,Pri,Description"); // TODO i18n
|
||||||
(*this)["report.ls.sort"] = "priority-,project+"; // TODO i18n
|
set ("report.ls.sort", "priority-,project+"); // TODO i18n
|
||||||
|
set ("report.ls.filter", "status:pending"); // TODO i18n
|
||||||
|
|
||||||
(*this)["report.newest.description"] = "Shows the newest tasks"; // TODO i18n
|
set ("report.newest.description", "Shows the newest tasks"); // TODO i18n
|
||||||
(*this)["report.newest.columns"] = "id,project,priority,due,active,age,description"; // TODO i18n
|
set ("report.newest.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||||
(*this)["report.newest.labels"] = "ID,Project,Pri,Due,Active,Age,Description"; // TODO i18n
|
set ("report.newest.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||||
(*this)["report.newest.sort"] = "id-"; // TODO i18n
|
set ("report.newest.sort", "id-"); // TODO i18n
|
||||||
(*this)["report.newest.limit"] = "10"; // no i18n
|
set ("report.newest.filter", "status:pending limit:10"); // TODO i18n
|
||||||
|
|
||||||
(*this)["report.oldest.description"] = "Shows the oldest tasks"; // TODO i18n
|
set ("report.oldest.description", "Shows the oldest tasks"); // TODO i18n
|
||||||
(*this)["report.oldest.columns"] = "id,project,priority,due,active,age,description"; // TODO i18n
|
set ("report.oldest.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||||
(*this)["report.oldest.labels"] = "ID,Project,Pri,Due,Active,Age,Description"; // TODO i18n
|
set ("report.oldest.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||||
(*this)["report.oldest.sort"] = "id+"; // TODO i18n
|
set ("report.oldest.sort", "id+"); // TODO i18n
|
||||||
(*this)["report.oldest.limit"] = "10"; // no i18n
|
set ("report.oldest.filter", "status:pending limit:10"); // TODO i18n
|
||||||
|
|
||||||
|
set ("report.overdue.description", "Lists overdue tasks matching the specified criteria"); // TODO i18n
|
||||||
|
set ("report.overdue.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||||
|
set ("report.overdue.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||||
|
set ("report.overdue.sort", "due+,priority-,project+"); // TODO i18n
|
||||||
|
set ("report.overdue.filter", "status:pending due.before:today"); // TODO i18n
|
||||||
|
|
||||||
|
set ("report.active.description", "Lists active tasks matching the specified criteria"); // TODO i18n
|
||||||
|
set ("report.active.columns", "id,project,priority,due,active,age,description"); // TODO i18n
|
||||||
|
set ("report.active.labels", "ID,Project,Pri,Due,Active,Age,Description"); // TODO i18n
|
||||||
|
set ("report.active.sort", "due+,priority-,project+"); // TODO i18n
|
||||||
|
set ("report.active.filter", "status:pending start.any:"); // TODO i18n
|
||||||
|
|
||||||
|
set ("report.completed.description", "Lists completed tasks matching the specified criteria"); // TODO i18n
|
||||||
|
set ("report.completed.columns", "end,project,priority,age,description"); // TODO i18n
|
||||||
|
set ("report.completed.labels", "Complete,Project,Pri,Age,Description"); // TODO i18n
|
||||||
|
set ("report.completed.sort", "end+,priority-,project+"); // TODO i18n
|
||||||
|
set ("report.completed.filter", "status:completed"); // TODO i18n
|
||||||
|
|
||||||
|
set ("report.recurring.description", "Lists recurring tasks matching the specified criteria"); // TODO i18n
|
||||||
|
set ("report.recurring.columns", "id,project,priority,due,recur,active,age,description"); // TODO i18n
|
||||||
|
set ("report.recurring.labels", "ID,Project,Pri,Due,Recur,Active,Age,Description"); // TODO i18n
|
||||||
|
set ("report.recurring.sort", "due+,priority-,project+"); // TODO i18n
|
||||||
|
set ("report.recurring.filter", "status:pending parent.any:"); // TODO i18n
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -202,10 +202,7 @@ std::string Context::dispatch ()
|
||||||
|
|
||||||
// Command that display IDs and therefore need TDB::gc first.
|
// Command that display IDs and therefore need TDB::gc first.
|
||||||
/*
|
/*
|
||||||
else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (); } // TODO OBSOLETE
|
|
||||||
else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (); }
|
else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (); }
|
||||||
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (); } // TODO OBSOLETE
|
|
||||||
else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (); } // TODO OBSOLETE
|
|
||||||
*/
|
*/
|
||||||
else if (cmd.validCustom (cmd.command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (cmd.command); }
|
else if (cmd.validCustom (cmd.command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (cmd.command); }
|
||||||
|
|
||||||
|
|
|
@ -199,6 +199,25 @@ std::string handleCustomReport (const std::string& report)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (*col == "end")
|
||||||
|
{
|
||||||
|
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Completed");
|
||||||
|
table.setColumnWidth (columnCount, Table::minimum);
|
||||||
|
table.setColumnJustification (columnCount, Table::right);
|
||||||
|
|
||||||
|
std::string started;
|
||||||
|
for (unsigned int row = 0; row < tasks.size(); ++row)
|
||||||
|
{
|
||||||
|
started = tasks[row].get ("end");
|
||||||
|
if (started.length ())
|
||||||
|
{
|
||||||
|
Date dt (::atoi (started.c_str ()));
|
||||||
|
started = dt.toString (context.config.get ("dateformat", "m/d/Y"));
|
||||||
|
table.addCell (row, columnCount, started);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if (*col == "due")
|
else if (*col == "due")
|
||||||
{
|
{
|
||||||
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Due");
|
table.addColumn (columnLabels[*col] != "" ? columnLabels[*col] : "Due");
|
||||||
|
|
|
@ -93,14 +93,11 @@ std::string longUsage ();
|
||||||
void filterSequence (std::vector<T>&, T&);
|
void filterSequence (std::vector<T>&, T&);
|
||||||
void filter (std::vector<T>&, T&);
|
void filter (std::vector<T>&, T&);
|
||||||
std::string handleInfo ();
|
std::string handleInfo ();
|
||||||
std::string handleCompleted ();
|
|
||||||
std::string handleReportSummary ();
|
std::string handleReportSummary ();
|
||||||
std::string handleReportNext ();
|
std::string handleReportNext ();
|
||||||
std::string handleReportHistory ();
|
std::string handleReportHistory ();
|
||||||
std::string handleReportGHistory ();
|
std::string handleReportGHistory ();
|
||||||
std::string handleReportCalendar ();
|
std::string handleReportCalendar ();
|
||||||
std::string handleReportActive ();
|
|
||||||
std::string handleReportOverdue ();
|
|
||||||
std::string handleReportStats ();
|
std::string handleReportStats ();
|
||||||
std::string handleReportTimesheet ();
|
std::string handleReportTimesheet ();
|
||||||
|
|
||||||
|
|
347
src/report.cpp
347
src/report.cpp
|
@ -85,10 +85,6 @@ std::string shortUsage ()
|
||||||
table.addCell (row, 1, "task annotate ID desc...");
|
table.addCell (row, 1, "task annotate ID desc...");
|
||||||
table.addCell (row, 2, "Adds an annotation to an existing task");
|
table.addCell (row, 2, "Adds an annotation to an existing task");
|
||||||
|
|
||||||
row = table.addRow ();
|
|
||||||
table.addCell (row, 1, "task completed [tags] [attrs] desc...");
|
|
||||||
table.addCell (row, 2, "Chronological listing of all completed tasks matching the specified criteria");
|
|
||||||
|
|
||||||
row = table.addRow ();
|
row = table.addRow ();
|
||||||
table.addCell (row, 1, "task ID [tags] [attrs] [desc...]");
|
table.addCell (row, 1, "task ID [tags] [attrs] [desc...]");
|
||||||
table.addCell (row, 2, "Modifies the existing task with provided arguments");
|
table.addCell (row, 2, "Modifies the existing task with provided arguments");
|
||||||
|
@ -169,14 +165,6 @@ std::string shortUsage ()
|
||||||
table.addCell (row, 1, "task calendar");
|
table.addCell (row, 1, "task calendar");
|
||||||
table.addCell (row, 2, "Shows a monthly calendar, with due tasks marked");
|
table.addCell (row, 2, "Shows a monthly calendar, with due tasks marked");
|
||||||
|
|
||||||
row = table.addRow ();
|
|
||||||
table.addCell (row, 1, "task active");
|
|
||||||
table.addCell (row, 2, "Shows all task that are started, but not completed");
|
|
||||||
|
|
||||||
row = table.addRow ();
|
|
||||||
table.addCell (row, 1, "task overdue");
|
|
||||||
table.addCell (row, 2, "Shows all incomplete tasks that are beyond their due date");
|
|
||||||
|
|
||||||
row = table.addRow ();
|
row = table.addRow ();
|
||||||
table.addCell (row, 1, "task stats");
|
table.addCell (row, 1, "task stats");
|
||||||
table.addCell (row, 2, "Shows task database statistics");
|
table.addCell (row, 2, "Shows task database statistics");
|
||||||
|
@ -429,103 +417,6 @@ void filter (std::vector<T>& all, T& task)
|
||||||
all = filtered;
|
all = filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Successively apply filters based on the task object built from the command
|
|
||||||
// line. Tasks that match all the specified criteria are listed.
|
|
||||||
std::string handleCompleted ()
|
|
||||||
{
|
|
||||||
std::stringstream out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Get the pending tasks.
|
|
||||||
std::vector <T> tasks;
|
|
||||||
tdb.completedT (tasks);
|
|
||||||
filter (tasks, task);
|
|
||||||
|
|
||||||
initializeColorRules ();
|
|
||||||
|
|
||||||
// Create a table for output.
|
|
||||||
Table table;
|
|
||||||
table.setTableWidth (context.getWidth ());
|
|
||||||
table.setDateFormat (context.config.get ("dateformat", "m/d/Y"));
|
|
||||||
table.addColumn ("Done");
|
|
||||||
table.addColumn ("Project");
|
|
||||||
table.addColumn ("Description");
|
|
||||||
|
|
||||||
if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) &&
|
|
||||||
context.config.get (std::string ("fontunderline"), "true"))
|
|
||||||
{
|
|
||||||
table.setColumnUnderline (0);
|
|
||||||
table.setColumnUnderline (1);
|
|
||||||
table.setColumnUnderline (2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
table.setTableDashedUnderline ();
|
|
||||||
|
|
||||||
table.setColumnWidth (0, Table::minimum);
|
|
||||||
table.setColumnWidth (1, Table::minimum);
|
|
||||||
table.setColumnWidth (2, Table::flexible);
|
|
||||||
|
|
||||||
table.setColumnJustification (0, Table::right);
|
|
||||||
table.setColumnJustification (1, Table::left);
|
|
||||||
table.setColumnJustification (2, Table::left);
|
|
||||||
|
|
||||||
// Note: There is deliberately no sorting. The original sorting was on the
|
|
||||||
// end date. Tasks are appended to completed.data naturally sorted by
|
|
||||||
// the end date, so that sequence is assumed to remain unchanged, and
|
|
||||||
// relied upon here.
|
|
||||||
|
|
||||||
// Iterate over each task, and apply selection criteria.
|
|
||||||
for (unsigned int i = 0; i < tasks.size (); ++i)
|
|
||||||
{
|
|
||||||
T refTask (tasks[i]);
|
|
||||||
|
|
||||||
// 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 (context.config.get ("dateformat", "m/d/Y")));
|
|
||||||
table.addCell (row, 1, refTask.getAttribute ("project"));
|
|
||||||
|
|
||||||
std::string description = refTask.getDescription ();
|
|
||||||
std::string when;
|
|
||||||
std::map <time_t, std::string> annotations;
|
|
||||||
refTask.getAnnotations (annotations);
|
|
||||||
foreach (anno, annotations)
|
|
||||||
{
|
|
||||||
Date dt (anno->first);
|
|
||||||
when = dt.toString (context.config.get ("dateformat", "m/d/Y"));
|
|
||||||
description += "\n" + when + " " + anno->second;
|
|
||||||
}
|
|
||||||
table.addCell (row, 2, description);
|
|
||||||
|
|
||||||
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
|
||||||
{
|
|
||||||
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 (table.rowCount ())
|
|
||||||
out << optionalBlankLine ()
|
|
||||||
<< table.render ()
|
|
||||||
<< optionalBlankLine ()
|
|
||||||
<< table.rowCount ()
|
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
|
||||||
<< std::endl;
|
|
||||||
else
|
|
||||||
out << "No matches."
|
|
||||||
<< std::endl;
|
|
||||||
*/
|
|
||||||
|
|
||||||
return out.str ();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Display all information for the given task.
|
// Display all information for the given task.
|
||||||
std::string handleInfo ()
|
std::string handleInfo ()
|
||||||
|
@ -1998,244 +1889,6 @@ std::string handleReportCalendar ()
|
||||||
return out.str ();
|
return out.str ();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
std::string handleReportActive ()
|
|
||||||
{
|
|
||||||
std::stringstream out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Get all the tasks.
|
|
||||||
std::vector <T> tasks;
|
|
||||||
tdb.pendingT (tasks);
|
|
||||||
filter (tasks, task);
|
|
||||||
|
|
||||||
initializeColorRules ();
|
|
||||||
|
|
||||||
// Create a table for output.
|
|
||||||
Table table;
|
|
||||||
table.setTableWidth (context.getWidth ());
|
|
||||||
table.setDateFormat (context.config.get ("dateformat", "m/d/Y"));
|
|
||||||
table.addColumn ("ID");
|
|
||||||
table.addColumn ("Project");
|
|
||||||
table.addColumn ("Pri");
|
|
||||||
table.addColumn ("Due");
|
|
||||||
table.addColumn ("Description");
|
|
||||||
|
|
||||||
if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) &&
|
|
||||||
context.config.get (std::string ("fontunderline"), "true"))
|
|
||||||
{
|
|
||||||
table.setColumnUnderline (0);
|
|
||||||
table.setColumnUnderline (1);
|
|
||||||
table.setColumnUnderline (2);
|
|
||||||
table.setColumnUnderline (3);
|
|
||||||
table.setColumnUnderline (4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
table.setTableDashedUnderline ();
|
|
||||||
|
|
||||||
table.setColumnWidth (0, Table::minimum);
|
|
||||||
table.setColumnWidth (1, Table::minimum);
|
|
||||||
table.setColumnWidth (2, Table::minimum);
|
|
||||||
table.setColumnWidth (3, Table::minimum);
|
|
||||||
table.setColumnWidth (4, Table::flexible);
|
|
||||||
|
|
||||||
table.setColumnJustification (0, Table::right);
|
|
||||||
table.setColumnJustification (3, Table::right);
|
|
||||||
|
|
||||||
table.sortOn (3, Table::ascendingDate);
|
|
||||||
table.sortOn (2, Table::descendingPriority);
|
|
||||||
table.sortOn (1, Table::ascendingCharacter);
|
|
||||||
|
|
||||||
// Iterate over each task, and apply selection criteria.
|
|
||||||
for (unsigned int i = 0; i < tasks.size (); ++i)
|
|
||||||
{
|
|
||||||
T refTask (tasks[i]);
|
|
||||||
if (refTask.has ("start"))
|
|
||||||
{
|
|
||||||
Date now;
|
|
||||||
bool imminent = false;
|
|
||||||
bool overdue = false;
|
|
||||||
std::string due = refTask.getAttribute ("due");
|
|
||||||
if (due.length ())
|
|
||||||
{
|
|
||||||
switch (getDueState (due))
|
|
||||||
{
|
|
||||||
case 2: overdue = true; break;
|
|
||||||
case 1: imminent = true; break;
|
|
||||||
case 0:
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Date dt (::atoi (due.c_str ()));
|
|
||||||
due = dt.toString (context.config.get ("dateformat", "m/d/Y"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
std::string description = refTask.getDescription ();
|
|
||||||
std::string when;
|
|
||||||
std::map <time_t, std::string> annotations;
|
|
||||||
refTask.getAnnotations (annotations);
|
|
||||||
foreach (anno, annotations)
|
|
||||||
{
|
|
||||||
Date dt (anno->first);
|
|
||||||
when = dt.toString (context.config.get ("dateformat", "m/d/Y"));
|
|
||||||
description += "\n" + when + " " + anno->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.addCell (row, 4, description);
|
|
||||||
|
|
||||||
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
|
||||||
{
|
|
||||||
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::colorCode (context.config.get ("color.overdue", "red")));
|
|
||||||
else if (imminent)
|
|
||||||
table.setCellFg (row, 3, Text::colorCode (context.config.get ("color.due", "yellow")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.rowCount ())
|
|
||||||
out << optionalBlankLine ()
|
|
||||||
<< table.render ()
|
|
||||||
<< optionalBlankLine ()
|
|
||||||
<< table.rowCount ()
|
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
|
||||||
<< std::endl;
|
|
||||||
else
|
|
||||||
out << "No active tasks." << std::endl;
|
|
||||||
*/
|
|
||||||
return out.str ();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
std::string handleReportOverdue ()
|
|
||||||
{
|
|
||||||
std::stringstream out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Get all the tasks.
|
|
||||||
std::vector <T> tasks;
|
|
||||||
tdb.pendingT (tasks);
|
|
||||||
filter (tasks, task);
|
|
||||||
|
|
||||||
initializeColorRules ();
|
|
||||||
|
|
||||||
// Create a table for output.
|
|
||||||
Table table;
|
|
||||||
table.setTableWidth (context.getWidth ());
|
|
||||||
table.setDateFormat (context.config.get ("dateformat", "m/d/Y"));
|
|
||||||
table.addColumn ("ID");
|
|
||||||
table.addColumn ("Project");
|
|
||||||
table.addColumn ("Pri");
|
|
||||||
table.addColumn ("Due");
|
|
||||||
table.addColumn ("Description");
|
|
||||||
|
|
||||||
if ((context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false)) &&
|
|
||||||
context.config.get (std::string ("fontunderline"), "true"))
|
|
||||||
{
|
|
||||||
table.setColumnUnderline (0);
|
|
||||||
table.setColumnUnderline (1);
|
|
||||||
table.setColumnUnderline (2);
|
|
||||||
table.setColumnUnderline (3);
|
|
||||||
table.setColumnUnderline (4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
table.setTableDashedUnderline ();
|
|
||||||
|
|
||||||
table.setColumnWidth (0, Table::minimum);
|
|
||||||
table.setColumnWidth (1, Table::minimum);
|
|
||||||
table.setColumnWidth (2, Table::minimum);
|
|
||||||
table.setColumnWidth (3, Table::minimum);
|
|
||||||
table.setColumnWidth (4, Table::flexible);
|
|
||||||
|
|
||||||
table.setColumnJustification (0, Table::right);
|
|
||||||
table.setColumnJustification (3, Table::right);
|
|
||||||
|
|
||||||
table.sortOn (3, Table::ascendingDate);
|
|
||||||
table.sortOn (2, Table::descendingPriority);
|
|
||||||
table.sortOn (1, Table::ascendingCharacter);
|
|
||||||
|
|
||||||
Date now;
|
|
||||||
|
|
||||||
// Iterate over each task, and apply selection criteria.
|
|
||||||
for (unsigned int i = 0; i < tasks.size (); ++i)
|
|
||||||
{
|
|
||||||
T refTask (tasks[i]);
|
|
||||||
std::string due;
|
|
||||||
if ((due = refTask.has ("due")))
|
|
||||||
{
|
|
||||||
if (due.length ())
|
|
||||||
{
|
|
||||||
Date dt (::atoi (due.c_str ()));
|
|
||||||
due = dt.toString (context.config.get ("dateformat", "m/d/Y"));
|
|
||||||
|
|
||||||
// If overdue.
|
|
||||||
if (dt < now)
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
std::string description = refTask.getDescription ();
|
|
||||||
std::string when;
|
|
||||||
std::map <time_t, std::string> annotations;
|
|
||||||
refTask.getAnnotations (annotations);
|
|
||||||
foreach (anno, annotations)
|
|
||||||
{
|
|
||||||
Date dt (anno->first);
|
|
||||||
when = dt.toString (context.config.get ("dateformat", "m/d/Y"));
|
|
||||||
description += "\n" + when + " " + anno->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.addCell (row, 4, description);
|
|
||||||
|
|
||||||
if (context.config.get ("color", true) || context.config.get (std::string ("_forcecolor"), false))
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
table.setCellFg (row, 3, Text::red);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table.rowCount ())
|
|
||||||
out << optionalBlankLine ()
|
|
||||||
<< table.render ()
|
|
||||||
<< optionalBlankLine ()
|
|
||||||
<< table.rowCount ()
|
|
||||||
<< (table.rowCount () == 1 ? " task" : " tasks")
|
|
||||||
<< std::endl;
|
|
||||||
else
|
|
||||||
out << "No overdue tasks." << std::endl;
|
|
||||||
*/
|
|
||||||
return out.str ();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
std::string handleReportStats ()
|
std::string handleReportStats ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -290,6 +290,7 @@ void validReportColumns (const std::vector <std::string>& columns)
|
||||||
*it != "priority" &&
|
*it != "priority" &&
|
||||||
*it != "entry" &&
|
*it != "entry" &&
|
||||||
*it != "start" &&
|
*it != "start" &&
|
||||||
|
*it != "end" &&
|
||||||
*it != "due" &&
|
*it != "due" &&
|
||||||
*it != "age" &&
|
*it != "age" &&
|
||||||
*it != "age_compact" &&
|
*it != "age_compact" &&
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue