diff --git a/src/command.cpp b/src/command.cpp index d8aad339d..837b3e9ee 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -1266,7 +1266,7 @@ int handleDelete (std::string &outs) << "'." << std::endl; - out << dependencyNag (*task); + dependencyChainOnComplete (*task); out << onProjectChange (*task); } } @@ -1289,7 +1289,7 @@ int handleDelete (std::string &outs) << "'." << std::endl; - out << dependencyNag (*task); + dependencyChainOnComplete (*task); out << onProjectChange (*task); } } @@ -1356,7 +1356,7 @@ int handleStart (std::string &outs) if (!nagged) nagged = nag (*task); - out << dependencyNag (*task); + dependencyChainOnStart (*task); } else { @@ -1503,7 +1503,7 @@ int handleDone (std::string &outs) << "'." << std::endl; - out << dependencyNag (*task); + dependencyChainOnComplete (*task); out << onProjectChange (*task, false); ++count; @@ -1648,6 +1648,13 @@ int handleModify (std::string &outs) { if (changes && permission.confirmed (before, taskDifferences (before, *other) + "Proceed with change?")) { + // TODO Are dependencies being explicitly removed? + // Either we scan context.task for negative IDs "depends:-n" + // or we ask deltaAttributes (above) to record dependency + // removal. + if (1) + dependencyChainOnModify (before, *other); + context.tdb.update (*other); if (before.get ("project") != other->get ("project")) diff --git a/src/dependency.cpp b/src/dependency.cpp index d22711f09..6bded8248 100644 --- a/src/dependency.cpp +++ b/src/dependency.cpp @@ -30,6 +30,7 @@ #include #include #include +#include extern Context context; @@ -183,59 +184,95 @@ static bool followUpstream ( //////////////////////////////////////////////////////////////////////////////// // Determine whether a dependency chain is being broken, assuming that 'task' is // either completed or deleted. +// +// blocked task blocking action +// ------- ---- -------- ----------------------------- +// [1] 2 Chain broken +// Nag message generated +// Repair offered: 1 dep:-2 // -// [1] --> 2 Chain broken -// Nag message generated -// Repair offered: 1 dep:-2 +// [1] 2 Chain broken +// 3 Nag message generated +// Repair offered: 1 dep:-2,-3 // -// [1] --> 2 Chain broken -// --> 3 Nag message generated -// Repair offered: 1 dep:-2,-3 +// 1 [2] - // -// 1 --> [2] - +// 1,3 [2] - // -// 1 --> [2] - -// 3 --> +// 1 [2] 3 Chain broken +// Nag message generated +// Repair offered: 2 dep:-3 +// 1 dep:-2,3 // -// 1 --> [2] --> 3 Chain broken -// Nag message generated -// Repair offered: 2 dep:-3 -// 1 dep:-2,3 +// 1,4 [2] 3,5 Chain broken +// Nag message generated +// Repair offered: 2 dep:-3,-5 +// 1 dep:3,5 +// 4 dep:3,5 // -// 1 --> [2] --> 3 Chain broken -// 4 --> --> 5 Nag message generated -// Repair offered: 2 dep:-3,-5 -// 1 dep:3,5 -// 4 dep:3,5 -// -bool dependencyChainBroken (Task& task) +void dependencyChainOnComplete (Task& task) { - if (task.has ("depends")) - { - std::cout << "# chain broken?\n"; - return true; - } + std::vector blocking; + dependencyGetBlocking (task, blocking); - return false; + std::cout << "# Task " << task.id << "\n"; + foreach (t, blocking) + std::cout << "# blocking " << t->id << " " << t->get ("uuid") << "\n"; + + // If the task is anything but the tail end of a dependency chain. + if (blocking.size ()) + { + std::vector blocked; + dependencyGetBlocked (task, blocked); + + foreach (t, blocked) + std::cout << "# blocked by " << t->id << " " << t->get ("uuid") << "\n"; + + // If there are both blocking and blocked tasks, the chain is broken. + if (blocked.size ()) + { + // TODO Nag about broken chain. + std::cout << "# Chain broken - offer to repair\n"; + + // TODO Confirm that the chain should be repaired. + + // Repair the chain - everything in blocked should now depend on + // everything in blocking, instead of task.id. + foreach (left, blocked) + { + left->removeDependency (task.id); + + foreach (right, blocking) + left->addDependency (right->id); + } + } + } } //////////////////////////////////////////////////////////////////////////////// -// Generate a nag message if a dependency chain is being violated. -std::string dependencyNag (Task& task) +void dependencyChainOnStart (Task& task) { std::stringstream out; - if (context.config.getBoolean ("dependency.reminder") && - task.has ("depends")) + if (context.config.getBoolean ("dependency.reminder") /* && + TODO check that task is actually blocked */) { - out << "# dependencyNag " + out << "# dependencyChainScan nag! " << task.id << " " << task.get ("uuid") << "\n"; - } - return out.str (); + context.footnote (out.str ()); + } +} + +//////////////////////////////////////////////////////////////////////////////// +void dependencyChainOnModify (Task& before, Task& after) +{ + // TODO Iff a dependency is being removed, is there anything to do. + + } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/edit.cpp b/src/edit.cpp index 056566599..cf6a8ee06 100644 --- a/src/edit.cpp +++ b/src/edit.cpp @@ -172,6 +172,8 @@ static std::string formatTask (Task task) before << " Annotation: " << now.toString (context.config.get ("dateformat.annotation")) << " -- " << std::endl << "# End" << std::endl; + // TODO Add dependencies here. + return before.str (); } @@ -518,6 +520,8 @@ static void parseTask (Task& task, const std::string& after) } task.setAnnotations (annotations); + + // TODO Dependencies } //////////////////////////////////////////////////////////////////////////////// @@ -628,6 +632,9 @@ int handleEdit (std::string &outs) editFile (*task); context.tdb.update (*task); /* + TODO Figure out what this is. I can't remember, but don't want to remove + it until I do. + foreach (other, all) { if (other->id != task.id) // Don't edit the same task again. diff --git a/src/main.h b/src/main.h index b325df6b4..3862a43f6 100644 --- a/src/main.h +++ b/src/main.h @@ -137,8 +137,9 @@ void dependencyGetBlocked (Task&, std::vector &); bool dependencyIsBlocking (Task&); void dependencyGetBlocking (Task&, std::vector &); bool dependencyIsCircular (Task&); -bool dependencyChainBroken (Task&); -std::string dependencyNag (Task&); +void dependencyChainOnComplete (Task&); +void dependencyChainOnStart (Task&); +void dependencyChainOnModify (Task&, Task&); // list template ///////////////////////////////////////////////////////////////////////////////