From c9f856a556acc0cfe596d65e793e5b940536bc3b Mon Sep 17 00:00:00 2001 From: Chris Schlaeger Date: Fri, 2 Oct 2009 13:09:44 +0200 Subject: [PATCH] Revert "Automatically align underspecified tasks boundaries on project boundaries when possible." This reverts commit bfd16d389138c5a64db6939a43bb0180ed069675. This patch breaks backward compatibility. --- TestSuite/HTML-Reports/Complete.tjp | 4 -- TestSuite/Syntax/Correct/BoundaryGuesser.tjp | 75 --------------------- taskjuggler/Project.cpp | 18 ++--- taskjuggler/Task.cpp | 98 ++++------------------------ 4 files changed, 20 insertions(+), 175 deletions(-) delete mode 100644 TestSuite/Syntax/Correct/BoundaryGuesser.tjp diff --git a/TestSuite/HTML-Reports/Complete.tjp b/TestSuite/HTML-Reports/Complete.tjp index 045ce1a5..0018efab 100644 --- a/TestSuite/HTML-Reports/Complete.tjp +++ b/TestSuite/HTML-Reports/Complete.tjp @@ -8,22 +8,18 @@ resource tux2 "Tux2" task m1 "Milestone Task" { task m2 "M2" { start 2005-10-19 - milestone } task m3 "M3" { task m4 "M4" { start 2005-10-22 - milestone } } task m5 "M5" { start 2005-12-01 - milestone } task m6 "M6" { task m7 "M7" { start 2005-12-24 - milestone } } } diff --git a/TestSuite/Syntax/Correct/BoundaryGuesser.tjp b/TestSuite/Syntax/Correct/BoundaryGuesser.tjp deleted file mode 100644 index e15828c2..00000000 --- a/TestSuite/Syntax/Correct/BoundaryGuesser.tjp +++ /dev/null @@ -1,75 +0,0 @@ -project prj "Project" "1.0" 2009-1-1 - 2009-6-30 { - timeformat "%Y-%m-%d" - now 2009-1-1 - scenario plan "Plan" { - projection { strict } - scenario forcheck "Just for checking multi-scenario mode" - } -} - -resource people "People" { - resource john "John" - resource team "Team of workers" { - resource joe "Joe" - resource jim "Jim" - } -} - -task prj "My Project" { - task planning "Planning Phase" { - # no start date since it can be guessed to be the aligned on project start - effort 6d - allocate john - } - task mnm "Management & Meetings" { - # no start date since it can be guessed as aligned on project start - # no end date since it can be guessed as aligned on project end - priority 1000 # no other task should steal time on this one - allocate john { - limits { weeklymax 0.5d dailymax 1h } # 4h/w but for short weeks - alternative joe select maxloaded # Joe when John is on vacation - } - } - task support "Support" { - # no end date since it can be guessed as aligned on project end - depends !deployment - priority 1000 # no other task should steal time on this one - allocate team { limits { weeklymax 0.5d dailymax 1h } } - } - task design "Design Phase" { - depends !planning - allocate john - effort 15d - } - task development "Development Phase" { - depends !design - allocate team - effort 30d - } - task integration "Integration Phase" { - depends !development - # not yet decided, let it be a milestone until further details - } - task deployment "Deployment Phase" { - depends !integration - # not yet decided, let it be a milestone until further details - } - task userdoc "User Documentation" { - depends !design - allocate people - effort 10d - } - task admindoc "Administrator Documentation" { - depends !development - allocate people - effort 6d - } -} - -taskreport "Gantt Chart" { - headline "Project Gantt Chart" - columns hierarchindex, name, start, end, effort, duration, chart - timeformat "%a %Y-%m-%d" - loadunit days - sorttasks tree,sequenceup -} diff --git a/taskjuggler/Project.cpp b/taskjuggler/Project.cpp index 00c0d037..2cb7dc35 100644 --- a/taskjuggler/Project.cpp +++ b/taskjuggler/Project.cpp @@ -508,15 +508,6 @@ Project::pass2(bool noDepCheck) for (TaskListIterator tli(taskList); *tli != 0; ++tli) (*tli)->xRef(idHash); - /* Now we can copy the missing values from the plan scenario to the other - * scenarios. */ - if (scenarioList.count() > 1) - { - for (ScenarioListIterator sli(scenarioList[0]->getSubListIterator()); - *sli; ++sli) - overlayScenario(0, (*sli)->getSequenceNo() - 1); - } - for (TaskListIterator tli(taskList); *tli != 0; ++tli) { // Set dates according to implicit dependencies @@ -533,6 +524,15 @@ Project::pass2(bool noDepCheck) for (ResourceListIterator rli(resourceList); *rli != 0; ++rli) (*rli)->saveSpecifiedBookings(); + /* Now we can copy the missing values from the plan scenario to the other + * scenarios. */ + if (scenarioList.count() > 1) + { + for (ScenarioListIterator sli(scenarioList[0]->getSubListIterator()); + *sli; ++sli) + overlayScenario(0, (*sli)->getSequenceNo() - 1); + } + // Now check that all tasks have sufficient data to be scheduled. setProgressInfo(i18n("Checking scheduling data...")); bool error = false; diff --git a/taskjuggler/Task.cpp b/taskjuggler/Task.cpp index bc494ace..22fc7e25 100644 --- a/taskjuggler/Task.cpp +++ b/taskjuggler/Task.cpp @@ -1523,102 +1523,26 @@ Task::implicitXRef() if (!isMilestone() && isLeaf()) { - /* Automatic boundary guesser for tasks that are underspecified in - * term of start/end/duration. As a convenience we add start and or - * end boundaries to task that are likely to be aligned on project - * start or end dates, and convert tasks to milestones in worst - * cases (i.e. when dependecies disables the tasks to be aligned - * on the project boundaries). - * This is handy when in the early stage of a project draft, when - * you just want to specify the project outline and fill in - * subtasks and details later. - * This is also handy even after the early stage for tasks that are - * actually aligned on one or both project boundary. */ - int milestoneBallots = 0; + /* Automatic milestone marker. As a convenience we convert tasks that + * only have a start or end criteria as a milestone. This is handy + * when in the early stage of a project draft, when you just want to + * specify the project outline and fill in subtasks and details + * later. */ + bool hasStartSpec = false; + bool hasEndSpec = false; + bool hasDurationSpec = false; for (int sc = 0; sc < project->getMaxScenarios(); ++sc) { - bool hasStartSpec = false; - bool hasEndSpec = false; - bool hasDurationSpec = false; - bool hasPreviousEvenInherited = false; - bool hasDependsEvenIhnerited = false; - bool hasFollowersEvenInherited = false; - bool hasPrecedesEvenInherited = false; - for (Task* task = this; task; task = task->getParent()) - { - hasPreviousEvenInherited |= task->hasPrevious(); - hasDependsEvenIhnerited |= !task->depends.isEmpty(); - hasFollowersEvenInherited |= task->hasFollowers(); - hasPrecedesEvenInherited |= !task ->precedes.isEmpty(); - } - if (scenarios[sc].specifiedStart != 0 || hasDependsEvenIhnerited) + if (scenarios[sc].specifiedStart != 0 || !depends.isEmpty()) hasStartSpec = true; - if (scenarios[sc].specifiedEnd != 0 || hasPrecedesEvenInherited) + if (scenarios[sc].specifiedEnd != 0 || !precedes.isEmpty()) hasEndSpec = true; if (scenarios[sc].duration != 0 || scenarios[sc].length != 0 || scenarios[sc].effort != 0) hasDurationSpec = true; - /*printf("O: %s/%d: (%g-%g %g) %d [%d %d] <-%d %d->\n", getId().ascii(), - sc, scenarios[sc].duration, scenarios[sc].length, - scenarios[sc].effort, (int)hasDurationSpec, (int)hasStartSpec, - (int)hasEndSpec, (int)hasPreviousEvenInherited, - (int)hasFollowersEvenInherited);*/ - // ASAP tasks lacking start specification - // - --> * (no previous) - // - x-> * (no previous) - if (!hasPreviousEvenInherited && !hasStartSpec - && scheduling == ASAP) - { - hasStartSpec = true; - setSpecifiedStart(sc, project->getStart()); - //printf("A: auto aligning %s on start date\n", getId().ascii()); - } - // ALAP tasks lacking end specification - // * <-- - (no followers) - // * <-x - (no followers) - if (!hasFollowersEvenInherited && !hasEndSpec - && scheduling == ALAP) - { - hasEndSpec = true; - setSpecifiedEnd(sc, project->getEnd()); - //printf("B: auto aligning %s on end date\n", getId().ascii()); - } - // tasks with no duration spec and at most one boundary spec - if (!hasDurationSpec && !(hasStartSpec && hasEndSpec)) - { - // ASAP tasks with neither end nor duration spec - // * --> - (no followers) - if (!hasFollowersEvenInherited && !hasEndSpec - && scheduling == ASAP) - { - setSpecifiedEnd(sc, project->getEnd()); - //printf("C: auto aligning %s on end date\n", getId().ascii()); - } - // ALAP tasks with neither start nor duration spec - // - <-- * (no previous) - else if (!hasPreviousEvenInherited && !hasStartSpec - && scheduling == ALAP) - { - setSpecifiedStart(sc, project->getStart()); - //printf("D: auto aligning %s on start date\n", getId().ascii()); - } - // other cases, e.g.: - // D --> D - // D <-- D - // | --> D (with previous) - // D <-- | (with followers) - else - { - ++milestoneBallots; - //printf("E: voting for %s conversion to milestone\n", getId().ascii()); - } - } } - if (milestoneBallots == project->getMaxScenarios()) - { + if (!hasDurationSpec && (hasStartSpec ^ hasEndSpec)) milestone = true; - //printf("F: auto converting %s to milestone\n", getId().ascii()); - } } } -- 2.11.0