diff --git a/ChangeLog b/ChangeLog index fad00b7aa..2fb0b9564 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22,6 +22,7 @@ (thanks to Marton Suranyi). - TW-5 color.due.today does not work (thanks to Max Muller). - TW-28 Inserts spaces before punctuation characters (thanks to Matt Kraai). +- TW-72 extend info report with urgency column - TW-115 allow "0day" durations for UDAs. - TW-197 New virtual tag READY. - TW-253 Unrecognized taskwarrior file format. in diff --git a/NEWS b/NEWS index c5a487d8b..8ef0d5b08 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ New Features in taskwarrior 2.4.0 - Regular expressions are now enabled by default. - The 'filter' verbosity token shows the complete filter used for the last command. + - The 'info' report now breaks down urgency values. New commands in taskwarrior 2.4.0 diff --git a/src/Task.h b/src/Task.h index 855d9e818..044d86554 100644 --- a/src/Task.h +++ b/src/Task.h @@ -163,18 +163,19 @@ private: void parseLegacy (const std::string&); void validate_before (const std::string&, const std::string&); - inline float urgency_priority () const; - inline float urgency_project () const; - inline float urgency_active () const; - inline float urgency_scheduled () const; - inline float urgency_waiting () const; - inline float urgency_blocked () const; - inline float urgency_annotations () const; - inline float urgency_tags () const; - inline float urgency_next () const; - inline float urgency_due () const; - inline float urgency_blocking () const; - inline float urgency_age () const; +public: + float urgency_priority () const; + float urgency_project () const; + float urgency_active () const; + float urgency_scheduled () const; + float urgency_waiting () const; + float urgency_blocked () const; + float urgency_annotations () const; + float urgency_tags () const; + float urgency_next () const; + float urgency_due () const; + float urgency_blocking () const; + float urgency_age () const; }; #endif diff --git a/src/commands/CmdInfo.cpp b/src/commands/CmdInfo.cpp index 59ce53a3c..7167aca4a 100644 --- a/src/commands/CmdInfo.cpp +++ b/src/commands/CmdInfo.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,9 @@ #include extern Context context; + +static const float epsilon = 0.000001; + //////////////////////////////////////////////////////////////////////////////// CmdInfo::CmdInfo () { @@ -317,7 +321,62 @@ int CmdInfo::execute (std::string& output) // Task::urgency row = view.addRow (); view.set (row, 0, STRING_COLUMN_LABEL_URGENCY); - view.set (row, 1, trimLeft (format (task->urgency (), 4, 4))); + + std::string urgency = + trimLeft (format (task->urgency (), 4, 4)) + "\n" + + urgencyTerm ("project", task->urgency_project (), Task::urgencyProjectCoefficient) + + urgencyTerm ("priority", task->urgency_priority (), Task::urgencyPriorityCoefficient) + + urgencyTerm ("active", task->urgency_active (), Task::urgencyActiveCoefficient) + + urgencyTerm ("scheduled", task->urgency_scheduled (), Task::urgencyScheduledCoefficient) + + urgencyTerm ("waiting", task->urgency_waiting (), Task::urgencyWaitingCoefficient) + + urgencyTerm ("blocked", task->urgency_blocked (), Task::urgencyBlockedCoefficient) + + urgencyTerm ("blocking", task->urgency_blocking (), Task::urgencyBlockingCoefficient) + + urgencyTerm ("annotations", task->urgency_annotations (), Task::urgencyAnnotationsCoefficient) + + urgencyTerm ("tags", task->urgency_tags (), Task::urgencyTagsCoefficient) + + urgencyTerm ("next", task->urgency_next (), Task::urgencyNextCoefficient) + + urgencyTerm ("due", task->urgency_due (), Task::urgencyDueCoefficient) + + urgencyTerm ("age", task->urgency_age (), Task::urgencyAgeCoefficient); + + // Tag, Project- and UDA-specific coefficients. + std::map ::iterator var; + for (var = Task::coefficients.begin (); var != Task::coefficients.end (); ++var) + { + if (var->first.substr (0, 13) == "urgency.user.") + { + // urgency.user.project..coefficient + std::string::size_type end = std::string::npos; + if (var->first.substr (13, 8) == "project." && + (end = var->first.find (".coefficient")) != std::string::npos) + { + std::string project = var->first.substr (21, end - 21); + if (task->get ("project").find (project) == 0) + urgency += urgencyTerm ("PROJECT " + project, 1.0, var->second); + } + + // urgency.user.tag..coefficient + if (var->first.substr (13, 4) == "tag." && + (end = var->first.find (".coefficient")) != std::string::npos) + { + std::string name = var->first.substr (17, end - 17); + if (task->hasTag (name)) + urgency += urgencyTerm ("TAG " + name, 1.0, var->second); + } + } + + // urgency.uda..coefficient + else if (var->first.substr (0, 12) == "urgency.uda.") + { + std::string::size_type end = var->first.find (".coefficient"); + if (end != std::string::npos) + { + std::string name = var->first.substr (12, end - 12); + if (task->has (name)) + urgency += urgencyTerm ("UDA " + name, 1.0, var->second); + } + } + } + + view.set (row, 1, urgency); // Show any UDAs std::vector all = task->all (); @@ -455,3 +514,24 @@ int CmdInfo::execute (std::string& output) } //////////////////////////////////////////////////////////////////////////////// +std::string CmdInfo::urgencyTerm ( + const std::string& label, + float measure, + float coefficient) const +{ + float value = measure * coefficient; + if (fabsf (value) > epsilon) + return std::string ( + rightJustify (label, 20) + + " " + + leftJustify (format (measure, 5, 3), 6) + + " * " + + leftJustify (format (coefficient, 4, 2), 4) + + " = " + + leftJustify (format (value, 5, 3), 5) + + "\n"); + + return ""; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/commands/CmdInfo.h b/src/commands/CmdInfo.h index 197bae6a7..fdf9a23c5 100644 --- a/src/commands/CmdInfo.h +++ b/src/commands/CmdInfo.h @@ -35,6 +35,9 @@ class CmdInfo : public Command public: CmdInfo (); int execute (std::string&); + +private: + std::string urgencyTerm (const std::string&, float, float) const; }; #endif