mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
- Inserted recurring task checks at appropriate points.
This commit is contained in:
parent
b1aaab0a8e
commit
947e65c1e2
3 changed files with 64 additions and 47 deletions
|
@ -109,8 +109,6 @@ static const char* attributes[] =
|
||||||
"end",
|
"end",
|
||||||
"recur",
|
"recur",
|
||||||
"until",
|
"until",
|
||||||
"base",
|
|
||||||
"range",
|
|
||||||
"",
|
"",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -242,9 +240,7 @@ static bool validAttribute (
|
||||||
// Some attributes are intended to be private.
|
// Some attributes are intended to be private.
|
||||||
else if (name == "entry" ||
|
else if (name == "entry" ||
|
||||||
name == "start" ||
|
name == "start" ||
|
||||||
name == "end" ||
|
name == "end")
|
||||||
name == "base" ||
|
|
||||||
name == "range")
|
|
||||||
throw std::string ("\"") +
|
throw std::string ("\"") +
|
||||||
name +
|
name +
|
||||||
"\" is not an attribute you may modify directly.";
|
"\" is not an attribute you may modify directly.";
|
||||||
|
|
102
src/task.cpp
102
src/task.cpp
|
@ -419,8 +419,12 @@ void handleAdd (const TDB& tdb, T& task, Config& conf)
|
||||||
task.removeAttribute (i->first);
|
task.removeAttribute (i->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.getAttribute ("recur") != "")
|
// Recurring tasks get a special status.
|
||||||
decorateRecurringTask (task);
|
if (task.getAttribute ("due") != "" &&
|
||||||
|
task.getAttribute ("recur") != "")
|
||||||
|
{
|
||||||
|
task.setStatus (T::recurring);
|
||||||
|
}
|
||||||
|
|
||||||
if (task.getDescription () == "")
|
if (task.getDescription () == "")
|
||||||
throw std::string ("Cannot add a blank task.");
|
throw std::string ("Cannot add a blank task.");
|
||||||
|
@ -532,11 +536,12 @@ void handleList (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tdb.gc ();
|
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.allPendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
|
checkRecurring (tasks);
|
||||||
|
filter (tasks, task);
|
||||||
|
|
||||||
initializeColorRules (conf);
|
initializeColorRules (conf);
|
||||||
|
|
||||||
|
@ -582,8 +587,6 @@ 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"));
|
||||||
|
|
||||||
filter (tasks, task);
|
|
||||||
checkRecurring (tasks);
|
|
||||||
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]);
|
||||||
|
@ -678,11 +681,12 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tdb.gc ();
|
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
|
checkRecurring (tasks);
|
||||||
|
filter (tasks, task);
|
||||||
|
|
||||||
initializeColorRules (conf);
|
initializeColorRules (conf);
|
||||||
|
|
||||||
|
@ -715,7 +719,6 @@ void handleSmallList (const TDB& tdb, T& task, Config& conf)
|
||||||
table.sortOn (1, Table::ascendingCharacter);
|
table.sortOn (1, Table::ascendingCharacter);
|
||||||
|
|
||||||
// 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]);
|
||||||
|
@ -804,11 +807,11 @@ void handleCompleted (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tdb.gc ();
|
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.completedT (tasks);
|
tdb.completedT (tasks);
|
||||||
|
filter (tasks, task);
|
||||||
|
|
||||||
initializeColorRules (conf);
|
initializeColorRules (conf);
|
||||||
|
|
||||||
|
@ -838,7 +841,6 @@ void handleCompleted (const TDB& tdb, T& task, Config& conf)
|
||||||
table.sortOn (0, Table::ascendingDate);
|
table.sortOn (0, Table::ascendingDate);
|
||||||
|
|
||||||
// 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]);
|
||||||
|
@ -931,6 +933,7 @@ void handleInfo (const TDB& tdb, T& task, Config& conf)
|
||||||
table.addCell (row, 1, ( refTask.getStatus () == T::pending ? "Pending"
|
table.addCell (row, 1, ( refTask.getStatus () == T::pending ? "Pending"
|
||||||
: refTask.getStatus () == T::completed ? "Completed"
|
: refTask.getStatus () == T::completed ? "Completed"
|
||||||
: refTask.getStatus () == T::deleted ? "Deleted"
|
: refTask.getStatus () == T::deleted ? "Deleted"
|
||||||
|
: refTask.getStatus () == T::recurring ? "Recurring"
|
||||||
: ""));
|
: ""));
|
||||||
|
|
||||||
row = table.addRow ();
|
row = table.addRow ();
|
||||||
|
@ -951,6 +954,17 @@ void handleInfo (const TDB& tdb, T& task, Config& conf)
|
||||||
table.addCell (row, 1, refTask.getAttribute ("priority"));
|
table.addCell (row, 1, refTask.getAttribute ("priority"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (refTask.getStatus () == T::recurring)
|
||||||
|
{
|
||||||
|
row = table.addRow ();
|
||||||
|
table.addCell (row, 0, "Recurrence");
|
||||||
|
table.addCell (row, 1, refTask.getAttribute ("recur"));
|
||||||
|
|
||||||
|
row = table.addRow ();
|
||||||
|
table.addCell (row, 0, "Recur until");
|
||||||
|
table.addCell (row, 1, refTask.getAttribute ("until"));
|
||||||
|
}
|
||||||
|
|
||||||
// due (colored)
|
// due (colored)
|
||||||
bool imminent = false;
|
bool imminent = false;
|
||||||
bool overdue = false;
|
bool overdue = false;
|
||||||
|
@ -1096,11 +1110,12 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tdb.gc ();
|
|
||||||
|
|
||||||
// Get all the tasks.
|
// Get all the tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
|
checkRecurring (tasks);
|
||||||
|
filter (tasks, task);
|
||||||
|
|
||||||
initializeColorRules (conf);
|
initializeColorRules (conf);
|
||||||
|
|
||||||
|
@ -1154,7 +1169,6 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
|
||||||
table.sortOn (1, Table::ascendingCharacter);
|
table.sortOn (1, Table::ascendingCharacter);
|
||||||
|
|
||||||
// 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]);
|
||||||
|
@ -1255,9 +1269,11 @@ void handleLongList (const TDB& tdb, T& task, Config& conf)
|
||||||
void handleReportSummary (const TDB& tdb, T& task, Config& conf)
|
void handleReportSummary (const TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
// Generate unique list of project names.
|
// Generate unique list of project names.
|
||||||
|
tdb.gc ();
|
||||||
std::map <std::string, bool> allProjects;
|
std::map <std::string, bool> allProjects;
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.pendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
|
checkRecurring (pending);
|
||||||
filter (pending, task);
|
filter (pending, task);
|
||||||
for (unsigned int i = 0; i < pending.size (); ++i)
|
for (unsigned int i = 0; i < pending.size (); ++i)
|
||||||
{
|
{
|
||||||
|
@ -1266,7 +1282,7 @@ void handleReportSummary (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector <T> completed;
|
std::vector <T> completed;
|
||||||
tdb.completedT (completed);
|
tdb.allCompletedT (completed);
|
||||||
filter (completed, task);
|
filter (completed, task);
|
||||||
for (unsigned int i = 0; i < completed.size (); ++i)
|
for (unsigned int i = 0; i < completed.size (); ++i)
|
||||||
{
|
{
|
||||||
|
@ -1294,6 +1310,7 @@ void handleReportSummary (const TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
T task (pending[i]);
|
T task (pending[i]);
|
||||||
std::string project = task.getAttribute ("project");
|
std::string project = task.getAttribute ("project");
|
||||||
|
if (task.getStatus () == T::pending)
|
||||||
++countPending[project];
|
++countPending[project];
|
||||||
|
|
||||||
time_t entry = ::atoi (task.getAttribute ("entry").c_str ());
|
time_t entry = ::atoi (task.getAttribute ("entry").c_str ());
|
||||||
|
@ -1422,8 +1439,10 @@ void handleReportSummary (const TDB& tdb, T& task, Config& conf)
|
||||||
void handleReportNext (const TDB& tdb, T& task, Config& conf)
|
void handleReportNext (const TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
// Load all pending.
|
// Load all pending.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.allPendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
|
checkRecurring (pending);
|
||||||
filter (pending, task);
|
filter (pending, task);
|
||||||
|
|
||||||
// Restrict to matching subset.
|
// Restrict to matching subset.
|
||||||
|
@ -1597,8 +1616,10 @@ void handleReportHistory (const TDB& tdb, T& task, Config& conf)
|
||||||
std::map <time_t, int> deletedGroup;
|
std::map <time_t, int> deletedGroup;
|
||||||
|
|
||||||
// Scan the pending tasks.
|
// Scan the pending tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.allPendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
|
checkRecurring (pending);
|
||||||
filter (pending, task);
|
filter (pending, task);
|
||||||
for (unsigned int i = 0; i < pending.size (); ++i)
|
for (unsigned int i = 0; i < pending.size (); ++i)
|
||||||
{
|
{
|
||||||
|
@ -1789,8 +1810,10 @@ void handleReportGHistory (const TDB& tdb, T& task, Config& conf)
|
||||||
std::map <time_t, int> deletedGroup;
|
std::map <time_t, int> deletedGroup;
|
||||||
|
|
||||||
// Scan the pending tasks.
|
// Scan the pending tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.allPendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
|
checkRecurring (pending);
|
||||||
filter (pending, task);
|
filter (pending, task);
|
||||||
for (unsigned int i = 0; i < pending.size (); ++i)
|
for (unsigned int i = 0; i < pending.size (); ++i)
|
||||||
{
|
{
|
||||||
|
@ -2186,8 +2209,10 @@ std::string renderMonths (
|
||||||
void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
void handleReportCalendar (const TDB& tdb, T& task, Config& conf)
|
||||||
{
|
{
|
||||||
// Load all the pending tasks.
|
// Load all the pending tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> pending;
|
std::vector <T> pending;
|
||||||
tdb.pendingT (pending);
|
tdb.allPendingT (pending);
|
||||||
|
checkRecurring (pending);
|
||||||
filter (pending, task);
|
filter (pending, task);
|
||||||
|
|
||||||
// Find the oldest pending due date.
|
// Find the oldest pending due date.
|
||||||
|
@ -2281,8 +2306,10 @@ void handleReportActive (const TDB& tdb, T& task, Config& conf)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get all the tasks.
|
// Get all the tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.pendingT (tasks);
|
||||||
|
filter (tasks, task);
|
||||||
|
|
||||||
initializeColorRules (conf);
|
initializeColorRules (conf);
|
||||||
|
|
||||||
|
@ -2319,7 +2346,6 @@ void handleReportActive (const TDB& tdb, T& task, Config& conf)
|
||||||
table.sortOn (1, Table::ascendingCharacter);
|
table.sortOn (1, Table::ascendingCharacter);
|
||||||
|
|
||||||
// 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]);
|
||||||
|
@ -2398,6 +2424,7 @@ void handleReportOverdue (const TDB& tdb, T& task, Config& conf)
|
||||||
// Get all the tasks.
|
// Get all the tasks.
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.pendingT (tasks);
|
||||||
|
filter (tasks, task);
|
||||||
|
|
||||||
initializeColorRules (conf);
|
initializeColorRules (conf);
|
||||||
|
|
||||||
|
@ -2436,7 +2463,6 @@ void handleReportOverdue (const TDB& tdb, T& task, Config& conf)
|
||||||
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]);
|
||||||
|
@ -2502,11 +2528,12 @@ void handleReportOldest (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tdb.gc ();
|
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
|
checkRecurring (tasks);
|
||||||
|
filter (tasks, task);
|
||||||
|
|
||||||
initializeColorRules (conf);
|
initializeColorRules (conf);
|
||||||
|
|
||||||
|
@ -2553,7 +2580,6 @@ void handleReportOldest (const TDB& tdb, T& task, Config& conf)
|
||||||
|
|
||||||
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
||||||
|
|
||||||
filter (tasks, task);
|
|
||||||
for (unsigned int i = 0; i < min (quantity, tasks.size ()); ++i)
|
for (unsigned int i = 0; i < min (quantity, tasks.size ()); ++i)
|
||||||
{
|
{
|
||||||
T refTask (tasks[i]);
|
T refTask (tasks[i]);
|
||||||
|
@ -2645,11 +2671,12 @@ void handleReportNewest (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tdb.gc ();
|
|
||||||
|
|
||||||
// Get the pending tasks.
|
// Get the pending tasks.
|
||||||
|
tdb.gc ();
|
||||||
std::vector <T> tasks;
|
std::vector <T> tasks;
|
||||||
tdb.pendingT (tasks);
|
tdb.allPendingT (tasks);
|
||||||
|
checkRecurring (tasks);
|
||||||
|
filter (tasks, task);
|
||||||
|
|
||||||
initializeColorRules (conf);
|
initializeColorRules (conf);
|
||||||
|
|
||||||
|
@ -2696,7 +2723,6 @@ void handleReportNewest (const TDB& tdb, T& task, Config& conf)
|
||||||
|
|
||||||
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
table.setDateFormat (conf.get ("dateformat", "m/d/Y"));
|
||||||
|
|
||||||
filter (tasks, task);
|
|
||||||
int total = tasks.size ();
|
int total = tasks.size ();
|
||||||
for (int i = total - 1; i >= max (0, total - quantity); --i)
|
for (int i = total - 1; i >= max (0, total - quantity); --i)
|
||||||
{
|
{
|
||||||
|
@ -3440,16 +3466,6 @@ void nag (const TDB& tdb, T& task, Config& conf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
void decorateRecurringTask (T& task)
|
|
||||||
{
|
|
||||||
if (task.getAttribute ("due") != "" &&
|
|
||||||
task.getAttribute ("recur") != "")
|
|
||||||
{
|
|
||||||
task.setAttribute ("base", task.getAttribute ("due"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Determines whether a task is overdue. Returns
|
// Determines whether a task is overdue. Returns
|
||||||
// 0 = not due at all
|
// 0 = not due at all
|
||||||
|
@ -3478,6 +3494,8 @@ int getDueState (const std::string& due)
|
||||||
// tasks.
|
// tasks.
|
||||||
void checkRecurring (std::vector <T>& tasks)
|
void checkRecurring (std::vector <T>& tasks)
|
||||||
{
|
{
|
||||||
|
std::vector <T> modified;
|
||||||
|
|
||||||
std::vector <T>::iterator it;
|
std::vector <T>::iterator it;
|
||||||
for (it = tasks.begin (); it != tasks.end (); ++it)
|
for (it = tasks.begin (); it != tasks.end (); ++it)
|
||||||
{
|
{
|
||||||
|
@ -3497,7 +3515,11 @@ void checkRecurring (std::vector <T>& tasks)
|
||||||
// TODO Determine if any new child tasks need to be generated.
|
// TODO Determine if any new child tasks need to be generated.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
modified.push_back (*it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks = modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -87,7 +87,6 @@ void handleModify (const TDB&, T&, Config&);
|
||||||
void handleColor (Config&);
|
void handleColor (Config&);
|
||||||
void gatherNextTasks (const TDB&, T&, Config&, std::vector <T>&, std::vector <int>&);
|
void gatherNextTasks (const TDB&, T&, Config&, std::vector <T>&, std::vector <int>&);
|
||||||
void nag (const TDB&, T&, Config&);
|
void nag (const TDB&, T&, Config&);
|
||||||
void decorateRecurringTask (T&);
|
|
||||||
void checkRecurring (std::vector <T>&);
|
void checkRecurring (std::vector <T>&);
|
||||||
|
|
||||||
// util.cpp
|
// util.cpp
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue