Hi guys, I was looking at bug http://bugzilla.gnome.org/show_bug.cgi?id=382548, but it's a bit more tricky to solve than I anticipated. So I thought, why not explain what I've found out so far on the mailing list. It may be interesting to others and helps me organize my thoughts. First let me explain the problem. Scenario 1) Do this: - create two tasks - drag a dependency from t2 to t1 - indent t2 You now have a child task that must end before its parent can start. Naturally this should not be possible. If you now try to undo the indent, planner crashes. Scenario 2) Trying to accomplish the above the other way around: - create two tasks - indent t2 - drag a dependency from t2 to t1 This is correctly rejected by planner. In libplanner/mrp-task-manager.c Planner builds up a graph from tasks and relationships in order to check if certain actions would create cycles, allowing it to reject impossible indentation or constraints. In this graph subtasks are put before their summary or parent tasks because they must be calculated first. When it is asked to have t2 end before t1 while t1 is a summary task containing t2 (scenario 2), it calls mrp_task_manager_check_predecessor(). This function calls add_predecessor_to_dependency_graph() which will first add t2 as a predecessor of t1 and then go on to add t2 as a predecessor of all t1's children. As a result it will add t2 as a predecessor of itself. This loop is later detected and the dependency is rejected. In scenario 1 the indentation is checked by mrp_task_manager_check_move(), which calls add_task_to_dependency_graph(). The latter function does something for the predecessors of t2 (irrelevant, because in the simple case t2 has none) and then adds the new parent relationship to the graph. What it does not do is add the predecessorrelationships for the parent to its new child and it is this predecessorrelationship that caused the loop in scenario 2. My first thought was to add all predecessors of the parent task t1 to the t2 and its children when t2 was added (using imrp_task_peek_predecessors() to get them). Because predecessors are always added recursively to all children of a task it should be enough to look only at the parent's predecessors. I'll think it over some more, but if anyone already has comments on this let me know. Maurice. -- Maurice van der Pot Gentoo Linux Developer griffon26 gentoo org http://www.gentoo.org Gnome Planner Developer griffon26 kfk4ever com http://live.gnome.org/Planner
Attachment:
pgpHPZtTjKQTg.pgp
Description: PGP signature