Recurring Tasks

- Rewrote updateRecurrenceMask, which was hopelessly muddled after the
  TDB -> TDB2 change.
- Modified associated code.
- Improved signal to noise ratio in unit tests.
This commit is contained in:
Paul Beckingham 2011-09-11 01:56:56 -04:00
parent 6e8d2ca79c
commit 6e649f3f45
5 changed files with 36 additions and 50 deletions

View file

@ -125,7 +125,7 @@ int CmdDelete::execute (std::string& output)
{ {
// Update mask in parent. // Update mask in parent.
task->setStatus (Task::deleted); task->setStatus (Task::deleted);
updateRecurrenceMask (siblings, *task); updateRecurrenceMask (*task);
// Don't want a 'delete' to clobber the end date that may have // Don't want a 'delete' to clobber the end date that may have
// been written by a 'done' command. // been written by a 'done' command.
@ -183,7 +183,6 @@ int CmdDelete::execute (std::string& output)
} }
context.tdb2.commit (); context.tdb2.commit ();
output = out.str (); output = out.str ();
return rc; return rc;
} }

View file

@ -103,7 +103,7 @@ int CmdDone::execute (std::string& output)
} }
} }
updateRecurrenceMask (filtered, *task); updateRecurrenceMask (*task);
if (!nagged) if (!nagged)
nagged = nag (*task); nagged = nag (*task);
} }

View file

@ -41,7 +41,7 @@
void handleRecurrence (); void handleRecurrence ();
Date getNextRecurrence (Date&, std::string&); Date getNextRecurrence (Date&, std::string&);
bool generateDueDates (Task&, std::vector <Date>&); bool generateDueDates (Task&, std::vector <Date>&);
void updateRecurrenceMask (std::vector <Task>&, Task&); void updateRecurrenceMask (Task&);
int getDueState (const std::string&); int getDueState (const std::string&);
bool nag (Task&); bool nag (Task&);

View file

@ -56,7 +56,6 @@ extern Context context;
void handleRecurrence () void handleRecurrence ()
{ {
std::vector <Task> tasks = context.tdb2.pending.get_tasks (); std::vector <Task> tasks = context.tdb2.pending.get_tasks ();
std::vector <Task> modified;
// Look at all tasks and find any recurring ones. // Look at all tasks and find any recurring ones.
std::vector <Task>::iterator t; std::vector <Task>::iterator t;
@ -124,9 +123,6 @@ void handleRecurrence ()
rec.remove ("mask"); // Remove the mask of the parent. rec.remove ("mask"); // Remove the mask of the parent.
// Add the new task to the vector, for immediate use.
modified.push_back (rec);
// Add the new task to the DB. // Add the new task to the DB.
context.tdb2.add (rec); context.tdb2.add (rec);
} }
@ -141,11 +137,7 @@ void handleRecurrence ()
context.tdb2.modify (*t); context.tdb2.modify (*t);
} }
} }
else
modified.push_back (*t);
} }
tasks = modified;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -345,20 +337,16 @@ Date getNextRecurrence (Date& current, std::string& period)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// When the status of a recurring child task changes, the parent task must // When the status of a recurring child task changes, the parent task must
// update it's mask. // update it's mask.
void updateRecurrenceMask ( void updateRecurrenceMask (Task& task)
std::vector <Task>& all,
Task& task)
{ {
std::string parent = task.get ("parent"); std::string uuid = task.get ("parent");
if (parent != "") Task parent;
if (uuid != "" &&
context.tdb2.get (uuid, parent))
{ {
std::vector <Task>::iterator it; unsigned int index = strtol (task.get ("imask").c_str (), NULL, 10);
for (it = all.begin (); it != all.end (); ++it) std::string mask = parent.get ("mask");
{
if (it->get ("uuid") == parent)
{
unsigned int index = atoi (task.get ("imask").c_str ());
std::string mask = it->get ("mask");
if (mask.length () > index) if (mask.length () > index)
{ {
mask[index] = (task.getStatus () == Task::pending) ? '-' mask[index] = (task.getStatus () == Task::pending) ? '-'
@ -366,9 +354,6 @@ void updateRecurrenceMask (
: (task.getStatus () == Task::deleted) ? 'X' : (task.getStatus () == Task::deleted) ? 'X'
: (task.getStatus () == Task::waiting) ? 'W' : (task.getStatus () == Task::waiting) ? 'W'
: '?'; : '?';
it->set ("mask", mask);
context.tdb2.modify (*it);
} }
else else
{ {
@ -383,9 +368,8 @@ void updateRecurrenceMask (
: '?'; : '?';
} }
return; // No point continuing the loop. parent.set ("mask", mask);
} context.tdb2.modify (parent);
}
} }
} }

View file

@ -48,7 +48,10 @@ like ($output, qr/^\s+3/ms, 'Found 3');
like ($output, qr/^\s+4/ms, 'Found 4'); like ($output, qr/^\s+4/ms, 'Found 4');
like ($output, qr/^\s+5/ms, 'Found 5'); like ($output, qr/^\s+5/ms, 'Found 5');
qx{../src/task rc:recur.rc $_ do} for 1..5; qx{../src/task rc:recur.rc 2 do};
qx{../src/task rc:recur.rc 3 do};
qx{../src/task rc:recur.rc 4 do};
qx{../src/task rc:recur.rc 5 do};
$output = qx{../src/task rc:recur.rc list}; $output = qx{../src/task rc:recur.rc list};
like ($output, qr/and has been deleted/, 'Parent task deleted'); like ($output, qr/and has been deleted/, 'Parent task deleted');