rev 5524 - in kde-extras/taskjuggler: tags tags/2.3.1-2/debian tags/2.3.1-2/debian/patches trunk/debian trunk/debian/patches

Fathi Boudra fboudra-guest at alioth.debian.org
Sat Feb 3 16:32:54 CET 2007


Author: fboudra-guest
Date: 2007-02-03 16:32:53 +0100 (Sat, 03 Feb 2007)
New Revision: 5524

Added:
   kde-extras/taskjuggler/tags/2.3.1-2/
   kde-extras/taskjuggler/tags/2.3.1-2/debian/patches/01_taskjuggler_branch_r1380.diff
   kde-extras/taskjuggler/trunk/debian/patches/01_taskjuggler_branch_r1380.diff
Modified:
   kde-extras/taskjuggler/tags/2.3.1-2/debian/changelog
   kde-extras/taskjuggler/trunk/debian/changelog
Log:
add upstream svn patch. fixes durations in printed reports

Copied: kde-extras/taskjuggler/tags/2.3.1-2 (from rev 5523, kde-extras/taskjuggler/trunk)

Modified: kde-extras/taskjuggler/tags/2.3.1-2/debian/changelog
===================================================================
--- kde-extras/taskjuggler/trunk/debian/changelog	2007-02-03 13:59:58 UTC (rev 5523)
+++ kde-extras/taskjuggler/tags/2.3.1-2/debian/changelog	2007-02-03 15:32:53 UTC (rev 5524)
@@ -1,3 +1,10 @@
+taskjuggler (2.3.1-2) experimental; urgency=low
+
+  * Add taskjuggler branch r1380 patch. It fixes durations in printed reports.
+    (Closes: #409112)
+
+ -- Fathi Boudra <fboudra at free.fr>  Sat,  3 Feb 2007 15:54:24 +0100
+
 taskjuggler (2.3.1-1) experimental; urgency=low
 
   * New upstream release

Added: kde-extras/taskjuggler/tags/2.3.1-2/debian/patches/01_taskjuggler_branch_r1380.diff
===================================================================
--- kde-extras/taskjuggler/trunk/debian/patches/01_taskjuggler_branch_r1380.diff	2007-02-03 13:59:58 UTC (rev 5523)
+++ kde-extras/taskjuggler/tags/2.3.1-2/debian/patches/01_taskjuggler_branch_r1380.diff	2007-02-03 15:32:53 UTC (rev 5524)
@@ -0,0 +1,434 @@
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/docs/en/PropertyReference.xml taskjuggler-svn1380/docs/en/PropertyReference.xml
+--- taskjuggler-2.3.1/docs/en/PropertyReference.xml	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/docs/en/PropertyReference.xml	2007-01-31 09:58:15.000000000 +0100
+@@ -1665,7 +1665,16 @@
+   explicitely or implicitely connected tasks measured from first task
+   to last task. The slack is the time between start of the first task
+   and end of the last task that is not covered by any task of the
+-  path. The default value is 10%.</para></descr>
++  path. The default value is 5%.</para>
++  <para>Larger values in combination with a project that uses lots of
++  inherited dependencies and long dependency pathes can result in very
++  long scheduling times. The more slack you allow, the more pathes
++  have to be searched till the end. An increase of 5% can turn a 10
++  second scheduling run into a 1 hour scheduling run. If you need
++  larger slack rate values, avoid the use of inherited
++  dependencies.</para>
++  <para>A value of 0 turns off the critical path detector.</para>
++  </descr>
+   <attributes>
+    <attr name="rate" type="REAL"/>
+   </attributes>
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/HTMLWeeklyCalendarElement.cpp taskjuggler-svn1380/taskjuggler/HTMLWeeklyCalendarElement.cpp
+--- taskjuggler-2.3.1/taskjuggler/HTMLWeeklyCalendarElement.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/HTMLWeeklyCalendarElement.cpp	2007-02-02 17:08:21.000000000 +0100
+@@ -7,7 +7,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: HTMLWeeklyCalendarElement.cpp 1373 2007-01-25 15:13:13Z cs $
++ * $Id: HTMLWeeklyCalendarElement.cpp 1380 2007-02-02 16:08:21Z cs $
+  */
+ 
+ #include "HTMLWeeklyCalendarElement.h"
+@@ -141,13 +141,13 @@
+         if (mAY != lastMAY)
+         {
+             s() << "     <td style=\"font-size:90%\">"
+-                << monthAndYear(wd) << "</td>" << endl;
++                << htmlFilter(mAY) << "</td>" << endl;
+             lastMAY = mAY;
+         }
+         s() << "    </tr>" << endl;
+         if (report->getProject()->isVacation(wd))
+             s() << "    <tr><td colspan=\"2\" style=\"font-size:80%\">"
+-                << report->getProject()->vacationName(wd)
++                << htmlFilter(report->getProject()->vacationName(wd))
+                 << "</td></tr>" << endl;
+         s() << "   </table></td>" << endl;
+     }
+@@ -186,20 +186,20 @@
+         {
+             if ((*tli)->getLoad(scenarios[0], Interval(start, end)) == 0.0)
+                 continue;
+-            if ((*tli)->isActive(scenarios[0],
+-                                 Interval(wd, sameTimeNextDay(wd))))
++            if (!(*tli)->isActive(scenarios[0],
++                                  Interval(wd, sameTimeNextDay(wd))))
++                continue;
++
++            if (first)
+             {
+-                if (first)
+-                {
+-                    s() << "     <table width=\"100%\">" << endl;
+-                    first = FALSE;
+-                }
+-                TableLineInfo tli1;
+-                tli1.ca1 = tli1.task = *tli;
+-                tli1.idxNo = no;
+-                tli1.fontFactor = 40;
+-                generateLine(&tli1, 2);
++                s() << "     <table width=\"100%\">" << endl;
++                first = FALSE;
+             }
++            TableLineInfo tli1;
++            tli1.ca1 = tli1.task = *tli;
++            tli1.idxNo = no;
++            tli1.fontFactor = 40;
++            generateLine(&tli1, 2);
+ 
+             if (!filterResourceList(filteredResourceList, *tli,
+                                     getHideResource(), getRollUpResource()))
+@@ -265,19 +265,19 @@
+         {
+             if ((*rli)->getLoad(scenarios[0],
+                                 Interval(wd,
+-                                         sameTimeNextDay(wd))) > 0.0)
++                                         sameTimeNextDay(wd))) <= 0.0)
++                continue;
++
++            if (first)
+             {
+-                if (first)
+-                {
+-                    s() << "     <table width=\"100%\">" << endl;
+-                    first = FALSE;
+-                }
+-                TableLineInfo tli2;
+-                tli2.ca1 = tli2.resource = *rli;
+-                tli2.idxNo = no;
+-                tli2.fontFactor = 40;
+-                generateLine(&tli2, 4);
++                s() << "     <table width=\"100%\">" << endl;
++                first = FALSE;
+             }
++            TableLineInfo tli2;
++            tli2.ca1 = tli2.resource = *rli;
++            tli2.idxNo = no;
++            tli2.fontFactor = 40;
++            generateLine(&tli2, 4);
+ 
+             /* We only want to show the nested task list for leaf resources.
+              * Leaf in this case means "task has no visible childs". */
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/ICalReport.cpp taskjuggler-svn1380/taskjuggler/ICalReport.cpp
+--- taskjuggler-2.3.1/taskjuggler/ICalReport.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/ICalReport.cpp	2007-02-02 17:08:21.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: ICalReport.cpp 1316 2006-08-12 09:40:53Z cs $
++ * $Id: ICalReport.cpp 1380 2007-02-02 16:08:21Z cs $
+  */
+ 
+ #include <config.h>
+@@ -211,7 +211,7 @@
+ 
+     // Dump the calendar in ICal format into a text file.
+     KCal::ICalFormat *format = new KCal::ICalFormat();
+-    s << format->toString(&cal) << endl;
++    s << format->toString(&cal).utf8() << endl;
+     f.close();
+ 
+     return TRUE;
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/Project.cpp taskjuggler-svn1380/taskjuggler/Project.cpp
+--- taskjuggler-2.3.1/taskjuggler/Project.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/Project.cpp	2007-01-31 09:46:47.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: Project.cpp 1352 2006-11-07 08:18:12Z cs $
++ * $Id: Project.cpp 1376 2007-01-31 08:46:47Z cs $
+  */
+ 
+ #include <config.h>
+@@ -719,13 +719,27 @@
+         (*rli)->finishScenario(sc);
+     for (TaskListIterator tli(taskList); *tli != 0; ++tli)
+         (*tli)->finishScenario(sc);
++
+     /* We need to have finished the scenario for all tasks before we can
+      * calculate the completion degree. */
+     for (TaskListIterator tli(taskList); *tli != 0; ++tli)
+-    {
+         (*tli)->calcCompletionDegree(sc);
+-        (*tli)->checkAndMarkCriticalPath(sc,
+-                                         getScenario(sc)->getMinSlackRate());
++
++    /* If the user has not set the minSlackRate to 0 we look for critical
++     * pathes. */
++    if (getScenario(sc)->getMinSlackRate() > 0.0)
++    {
++        setProgressInfo(i18n("Computing critical pathes..."));
++        /* The critical path detector needs to know the end of the last task.
++         * So we have to find this out first. */
++        time_t maxEnd = 0;
++        for (TaskListIterator tli(taskList); *tli != 0; ++tli)
++        if (maxEnd < (*tli)->getEnd(sc))
++            maxEnd = (*tli)->getEnd(sc);
++
++        for (TaskListIterator tli(taskList); *tli != 0; ++tli)
++            (*tli)->checkAndMarkCriticalPath
++                (sc, getScenario(sc)->getMinSlackRate(), maxEnd);
+     }
+ }
+ 
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/Scenario.cpp taskjuggler-svn1380/taskjuggler/Scenario.cpp
+--- taskjuggler-2.3.1/taskjuggler/Scenario.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/Scenario.cpp	2007-01-31 09:46:47.000000000 +0100
+@@ -7,7 +7,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: Scenario.cpp 1341 2006-09-30 15:10:11Z cs $
++ * $Id: Scenario.cpp 1376 2007-01-31 08:46:47Z cs $
+  */
+ 
+ #include "Scenario.h"
+@@ -34,7 +34,7 @@
+         projectionMode = false;
+         optimize = false;
+         strictBookings = false;
+-        minSlackRate = 10.0;
++        minSlackRate = 0.05;
+     }
+ }
+ 
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/Task.cpp taskjuggler-svn1380/taskjuggler/Task.cpp
+--- taskjuggler-2.3.1/taskjuggler/Task.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/Task.cpp	2007-01-31 09:46:47.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: Task.cpp 1374 2007-01-28 16:49:27Z cs $
++ * $Id: Task.cpp 1376 2007-01-31 08:46:47Z cs $
+  */
+ 
+ #include <stdlib.h>
+@@ -2944,7 +2944,7 @@
+ }
+ 
+ void
+-Task::checkAndMarkCriticalPath(int sc, double minSlack)
++Task::checkAndMarkCriticalPath(int sc, double minSlack, time_t maxEnd)
+ {
+     // The algorithm has to start at a leaf task that has no predecessors.
+     if (hasSubs() || !previous.isEmpty())
+@@ -2953,12 +2953,13 @@
+     if (DEBUGPA(3))
+         qDebug("Starting critical path search at %s", id.latin1());
+ 
+-    LDIList list;
+-    analyzePath(sc, minSlack, getStart(sc), 0);
++    long worstMinSlackTime = (long) ((maxEnd - getStart(sc)) * minSlack);
++    analyzePath(sc, minSlack, getStart(sc), 0, worstMinSlackTime);
+ }
+ 
+ bool
+-Task::analyzePath(int sc, double minSlack, time_t pathStart, long busyTime)
++Task::analyzePath(int sc, double minSlack, time_t pathStart, long busyTime,
++                  long worstMinSlackTime)
+ {
+     if (DEBUGPA(14))
+         qDebug("  * Checking task %s", id.latin1());
+@@ -2971,7 +2972,8 @@
+             qDebug("  > Sub check started for %s", id.latin1());
+ 
+         for (TaskListIterator tli(*sub); *tli; ++tli)
+-            if ((*tli)->analyzePath(sc, minSlack, pathStart, busyTime))
++            if ((*tli)->analyzePath(sc, minSlack, pathStart, busyTime,
++                                    worstMinSlackTime))
+                 critical = true;
+ 
+         if (DEBUGPA(15))
+@@ -2979,73 +2981,86 @@
+     }
+     else
+     {
+-        bool hasFollowers = false;
+-
+         if (!milestone)
+-            busyTime += (getEnd(sc) - getStart(sc));
++            busyTime += (getEnd(sc) + 1 - getStart(sc));
++
++        /* If we have enough slack already that the path cannot be critical,
++         * we stop looking at the rest of the path. */
++        long currentSlack = (getEnd(sc) + 1 - pathStart) - busyTime;
++        if (currentSlack > worstMinSlackTime)
++        {
++            if (DEBUGPA(11))
++                qDebug("Path cannot be critical. Stopping at task %s",
++                       id.latin1());
++            return false;
++        }
+ 
+-        /* A task and its parent tasks can have the same followers. We keep a
+-         * list of already checked followers, so that we check each follower
+-         * only once, no matter whether it is a follower of the current task
+-         * or any of its parents. */
+-        TaskList checkedTasks;
++        /* We first have to gather a list of all followers of this task. This
++         * list must also include the followers registered for all parent
++         * tasks of this task as they are followers as well. */
++        TaskList allFollowers;
+         for (Task* task = this; task; task = task->getParent())
+         {
+-            if (task->followers.isEmpty())
+-                continue;
++            for (TaskListIterator tli(task->followers); *tli; ++tli)
++                if (allFollowers.findRef(*tli) < 0)
++                    allFollowers.append(*tli);
++        }
+ 
+-            hasFollowers = true;
++        /* We don't want to follow dependencies that were only specified to
++         * pass them on to the sub tasks. Such parent tasks are put in the
++         * ignore list. */
++        TaskList ignoreList;
++        for (TaskListIterator tli(allFollowers); *tli; ++tli)
++        {
++            /* If allFollowers contains any parent of *tli we can ignore
++             * the parent. */
++            for (Task* t = (*tli)->getParent(); t; t = t->getParent())
++                if (allFollowers.findRef(t) >= 0)
++                    ignoreList.append(t);
++        }
++
++        /* Compose a new list that contains the allFollowers minus the ignore
++         * list. */
++        TaskList followers;
++        for (TaskListIterator tli(allFollowers); *tli; ++tli)
++            if (ignoreList.findRef(*tli) < 0)
++                followers.append(*tli);
++
++        if (DEBUGPA(10))
++            if (followers.count() < allFollowers.count())
++                qDebug("Ignoring %d followers of task %s",
++                       allFollowers.count() - followers.count(), id.latin1());
+ 
++        /* Now we can check the pathes through the remaining followers. */
++        for (TaskListIterator tli(followers); *tli; ++tli)
++        {
+             if (DEBUGPA(16))
+-                qDebug("  > Follower check started for %s", task->id.latin1());
+-
+-            /* Due to inherited dependencies we can get a complexity explosion
+-             * in the number of possible pathes. All these pathes are
+-             * essentially identical to the path through the task that is
+-             * the furthest from the top-level task. So we only check this
+-             * path. */
+-            for (TaskListIterator tli(task->followers); *tli; ++tli)
+-            {
+-                Task* parent = (*tli)->getParent();
+-                if (parent && task->followers.findRef(parent) >= 0 &&
+-                    checkedTasks.find(parent) < 0)
+-                {
+-                    if (DEBUGPA(17))
+-                        qDebug("  - Ignoring path through parent task %s",
+-                               parent->getId().latin1());
+-                    checkedTasks.append(parent);
+-                }
+-            }
++                qDebug("  > Follower check started for %s",
++                       (*tli)->id.latin1());
+ 
+-            for (TaskListIterator tli(task->followers); *tli; ++tli)
++            if ((*tli)->analyzePath(sc, minSlack, pathStart, busyTime,
++                                    worstMinSlackTime))
+             {
+-                // Don't check each follower more than once.
+-                if (checkedTasks.findRef(*tli) >= 0)
+-                    continue;
+-
+-                if ((*tli)->analyzePath(sc, minSlack, pathStart, busyTime))
++                if (scenarios[sc].criticalLinks.findRef(*tli) < 0)
+                 {
+-                    if (task->scenarios[sc].criticalLinks.findRef(*tli) < 0)
+-                    {
+-                        if (DEBUGPA(5))
+-                            qDebug("  +++ Critical link %s -> %s",
+-                                   id.latin1(), (*tli)->id.latin1());
+-                        task->scenarios[sc].criticalLinks.append(*tli);
+-                    }
+-
+-                    critical = true;
++                    if (DEBUGPA(5))
++                        qDebug("  +++ Critical link %s -> %s",
++                               id.latin1(), (*tli)->id.latin1());
++                    scenarios[sc].criticalLinks.append(*tli);
+                 }
+-                checkedTasks.append(*tli);
++
++                critical = true;
+             }
+ 
+             if (DEBUGPA(16))
+-                qDebug("  < Follower check finished for %s", task->id.latin1());
++                qDebug("  < Follower check finished for %s",
++                       (*tli)->id.latin1());
+         }
+ 
+-        if (!hasFollowers)
++        if (followers.isEmpty())
+         {
+             // We've reached the end of a path. Now let's see if it's critical.
+-            long overallDuration = getEnd(sc) - pathStart;
++            long overallDuration = getEnd(sc) + 1 - pathStart;
+             /* A path is considered critical if the ratio of busy time and
+              * overall path time is above the minSlack threshold and the path
+              * contains more than one task. */
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/Task.h taskjuggler-svn1380/taskjuggler/Task.h
+--- taskjuggler-2.3.1/taskjuggler/Task.h	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/Task.h	2007-01-31 09:46:47.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: Task.h 1370 2007-01-14 15:54:54Z cs $
++ * $Id: Task.h 1376 2007-01-31 08:46:47Z cs $
+  */
+ 
+ #ifndef _Task_h_
+@@ -297,7 +297,7 @@
+     void finishScenario(int sc);
+     void computeCriticalness(int sc);
+     double getCriticalness(int sc) const { return scenarios[sc].criticalness; }
+-    void checkAndMarkCriticalPath(int sc, double minSlack);
++    void checkAndMarkCriticalPath(int sc, double minSlack, time_t maxEnd);
+ 
+     void computePathCriticalness(int sc);
+     double getPathCriticalness(int sc) const
+@@ -400,7 +400,8 @@
+     double computeBackwardCriticalness(int sc);
+     double computeForwardCriticalness(int sc);
+ 
+-    bool analyzePath(int sc, double minSlack, time_t pathStart, long busyTime);
++    bool analyzePath(int sc, double minSlack, time_t pathStart, long busyTime,
++                     long worstMinSlackTime);
+ 
+     bool countMilestones(int sc, time_t now, int& totalMilestones,
+                          int& completedMilestones,
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/TaskJugglerUI/TjPrintReport.cpp taskjuggler-svn1380/TaskJugglerUI/TjPrintReport.cpp
+--- taskjuggler-2.3.1/TaskJugglerUI/TjPrintReport.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/TaskJugglerUI/TjPrintReport.cpp	2007-02-02 09:37:48.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: TjPrintReport.cpp 1374 2007-01-28 16:49:27Z cs $
++ * $Id: TjPrintReport.cpp 1379 2007-02-02 08:37:48Z cs $
+  */
+ 
+ #include "TjPrintReport.h"
+@@ -271,7 +271,7 @@
+             }
+         }
+         else if ((*ci)->getName() == "duration")
+-            cellText = reportElement->scaledLoad
++            cellText = reportElement->scaledDuration
+                 (task->getCalcDuration(scenario), tcf->realFormat);
+         else if ((*ci)->getName() == "effort")
+         {

Modified: kde-extras/taskjuggler/trunk/debian/changelog
===================================================================
--- kde-extras/taskjuggler/trunk/debian/changelog	2007-02-03 13:59:58 UTC (rev 5523)
+++ kde-extras/taskjuggler/trunk/debian/changelog	2007-02-03 15:32:53 UTC (rev 5524)
@@ -1,3 +1,10 @@
+taskjuggler (2.3.1-2) experimental; urgency=low
+
+  * Add taskjuggler branch r1380 patch. It fixes durations in printed reports.
+    (Closes: #409112)
+
+ -- Fathi Boudra <fboudra at free.fr>  Sat,  3 Feb 2007 15:54:24 +0100
+
 taskjuggler (2.3.1-1) experimental; urgency=low
 
   * New upstream release

Added: kde-extras/taskjuggler/trunk/debian/patches/01_taskjuggler_branch_r1380.diff
===================================================================
--- kde-extras/taskjuggler/trunk/debian/patches/01_taskjuggler_branch_r1380.diff	2007-02-03 13:59:58 UTC (rev 5523)
+++ kde-extras/taskjuggler/trunk/debian/patches/01_taskjuggler_branch_r1380.diff	2007-02-03 15:32:53 UTC (rev 5524)
@@ -0,0 +1,434 @@
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/docs/en/PropertyReference.xml taskjuggler-svn1380/docs/en/PropertyReference.xml
+--- taskjuggler-2.3.1/docs/en/PropertyReference.xml	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/docs/en/PropertyReference.xml	2007-01-31 09:58:15.000000000 +0100
+@@ -1665,7 +1665,16 @@
+   explicitely or implicitely connected tasks measured from first task
+   to last task. The slack is the time between start of the first task
+   and end of the last task that is not covered by any task of the
+-  path. The default value is 10%.</para></descr>
++  path. The default value is 5%.</para>
++  <para>Larger values in combination with a project that uses lots of
++  inherited dependencies and long dependency pathes can result in very
++  long scheduling times. The more slack you allow, the more pathes
++  have to be searched till the end. An increase of 5% can turn a 10
++  second scheduling run into a 1 hour scheduling run. If you need
++  larger slack rate values, avoid the use of inherited
++  dependencies.</para>
++  <para>A value of 0 turns off the critical path detector.</para>
++  </descr>
+   <attributes>
+    <attr name="rate" type="REAL"/>
+   </attributes>
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/HTMLWeeklyCalendarElement.cpp taskjuggler-svn1380/taskjuggler/HTMLWeeklyCalendarElement.cpp
+--- taskjuggler-2.3.1/taskjuggler/HTMLWeeklyCalendarElement.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/HTMLWeeklyCalendarElement.cpp	2007-02-02 17:08:21.000000000 +0100
+@@ -7,7 +7,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: HTMLWeeklyCalendarElement.cpp 1373 2007-01-25 15:13:13Z cs $
++ * $Id: HTMLWeeklyCalendarElement.cpp 1380 2007-02-02 16:08:21Z cs $
+  */
+ 
+ #include "HTMLWeeklyCalendarElement.h"
+@@ -141,13 +141,13 @@
+         if (mAY != lastMAY)
+         {
+             s() << "     <td style=\"font-size:90%\">"
+-                << monthAndYear(wd) << "</td>" << endl;
++                << htmlFilter(mAY) << "</td>" << endl;
+             lastMAY = mAY;
+         }
+         s() << "    </tr>" << endl;
+         if (report->getProject()->isVacation(wd))
+             s() << "    <tr><td colspan=\"2\" style=\"font-size:80%\">"
+-                << report->getProject()->vacationName(wd)
++                << htmlFilter(report->getProject()->vacationName(wd))
+                 << "</td></tr>" << endl;
+         s() << "   </table></td>" << endl;
+     }
+@@ -186,20 +186,20 @@
+         {
+             if ((*tli)->getLoad(scenarios[0], Interval(start, end)) == 0.0)
+                 continue;
+-            if ((*tli)->isActive(scenarios[0],
+-                                 Interval(wd, sameTimeNextDay(wd))))
++            if (!(*tli)->isActive(scenarios[0],
++                                  Interval(wd, sameTimeNextDay(wd))))
++                continue;
++
++            if (first)
+             {
+-                if (first)
+-                {
+-                    s() << "     <table width=\"100%\">" << endl;
+-                    first = FALSE;
+-                }
+-                TableLineInfo tli1;
+-                tli1.ca1 = tli1.task = *tli;
+-                tli1.idxNo = no;
+-                tli1.fontFactor = 40;
+-                generateLine(&tli1, 2);
++                s() << "     <table width=\"100%\">" << endl;
++                first = FALSE;
+             }
++            TableLineInfo tli1;
++            tli1.ca1 = tli1.task = *tli;
++            tli1.idxNo = no;
++            tli1.fontFactor = 40;
++            generateLine(&tli1, 2);
+ 
+             if (!filterResourceList(filteredResourceList, *tli,
+                                     getHideResource(), getRollUpResource()))
+@@ -265,19 +265,19 @@
+         {
+             if ((*rli)->getLoad(scenarios[0],
+                                 Interval(wd,
+-                                         sameTimeNextDay(wd))) > 0.0)
++                                         sameTimeNextDay(wd))) <= 0.0)
++                continue;
++
++            if (first)
+             {
+-                if (first)
+-                {
+-                    s() << "     <table width=\"100%\">" << endl;
+-                    first = FALSE;
+-                }
+-                TableLineInfo tli2;
+-                tli2.ca1 = tli2.resource = *rli;
+-                tli2.idxNo = no;
+-                tli2.fontFactor = 40;
+-                generateLine(&tli2, 4);
++                s() << "     <table width=\"100%\">" << endl;
++                first = FALSE;
+             }
++            TableLineInfo tli2;
++            tli2.ca1 = tli2.resource = *rli;
++            tli2.idxNo = no;
++            tli2.fontFactor = 40;
++            generateLine(&tli2, 4);
+ 
+             /* We only want to show the nested task list for leaf resources.
+              * Leaf in this case means "task has no visible childs". */
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/ICalReport.cpp taskjuggler-svn1380/taskjuggler/ICalReport.cpp
+--- taskjuggler-2.3.1/taskjuggler/ICalReport.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/ICalReport.cpp	2007-02-02 17:08:21.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: ICalReport.cpp 1316 2006-08-12 09:40:53Z cs $
++ * $Id: ICalReport.cpp 1380 2007-02-02 16:08:21Z cs $
+  */
+ 
+ #include <config.h>
+@@ -211,7 +211,7 @@
+ 
+     // Dump the calendar in ICal format into a text file.
+     KCal::ICalFormat *format = new KCal::ICalFormat();
+-    s << format->toString(&cal) << endl;
++    s << format->toString(&cal).utf8() << endl;
+     f.close();
+ 
+     return TRUE;
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/Project.cpp taskjuggler-svn1380/taskjuggler/Project.cpp
+--- taskjuggler-2.3.1/taskjuggler/Project.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/Project.cpp	2007-01-31 09:46:47.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: Project.cpp 1352 2006-11-07 08:18:12Z cs $
++ * $Id: Project.cpp 1376 2007-01-31 08:46:47Z cs $
+  */
+ 
+ #include <config.h>
+@@ -719,13 +719,27 @@
+         (*rli)->finishScenario(sc);
+     for (TaskListIterator tli(taskList); *tli != 0; ++tli)
+         (*tli)->finishScenario(sc);
++
+     /* We need to have finished the scenario for all tasks before we can
+      * calculate the completion degree. */
+     for (TaskListIterator tli(taskList); *tli != 0; ++tli)
+-    {
+         (*tli)->calcCompletionDegree(sc);
+-        (*tli)->checkAndMarkCriticalPath(sc,
+-                                         getScenario(sc)->getMinSlackRate());
++
++    /* If the user has not set the minSlackRate to 0 we look for critical
++     * pathes. */
++    if (getScenario(sc)->getMinSlackRate() > 0.0)
++    {
++        setProgressInfo(i18n("Computing critical pathes..."));
++        /* The critical path detector needs to know the end of the last task.
++         * So we have to find this out first. */
++        time_t maxEnd = 0;
++        for (TaskListIterator tli(taskList); *tli != 0; ++tli)
++        if (maxEnd < (*tli)->getEnd(sc))
++            maxEnd = (*tli)->getEnd(sc);
++
++        for (TaskListIterator tli(taskList); *tli != 0; ++tli)
++            (*tli)->checkAndMarkCriticalPath
++                (sc, getScenario(sc)->getMinSlackRate(), maxEnd);
+     }
+ }
+ 
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/Scenario.cpp taskjuggler-svn1380/taskjuggler/Scenario.cpp
+--- taskjuggler-2.3.1/taskjuggler/Scenario.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/Scenario.cpp	2007-01-31 09:46:47.000000000 +0100
+@@ -7,7 +7,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: Scenario.cpp 1341 2006-09-30 15:10:11Z cs $
++ * $Id: Scenario.cpp 1376 2007-01-31 08:46:47Z cs $
+  */
+ 
+ #include "Scenario.h"
+@@ -34,7 +34,7 @@
+         projectionMode = false;
+         optimize = false;
+         strictBookings = false;
+-        minSlackRate = 10.0;
++        minSlackRate = 0.05;
+     }
+ }
+ 
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/Task.cpp taskjuggler-svn1380/taskjuggler/Task.cpp
+--- taskjuggler-2.3.1/taskjuggler/Task.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/Task.cpp	2007-01-31 09:46:47.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: Task.cpp 1374 2007-01-28 16:49:27Z cs $
++ * $Id: Task.cpp 1376 2007-01-31 08:46:47Z cs $
+  */
+ 
+ #include <stdlib.h>
+@@ -2944,7 +2944,7 @@
+ }
+ 
+ void
+-Task::checkAndMarkCriticalPath(int sc, double minSlack)
++Task::checkAndMarkCriticalPath(int sc, double minSlack, time_t maxEnd)
+ {
+     // The algorithm has to start at a leaf task that has no predecessors.
+     if (hasSubs() || !previous.isEmpty())
+@@ -2953,12 +2953,13 @@
+     if (DEBUGPA(3))
+         qDebug("Starting critical path search at %s", id.latin1());
+ 
+-    LDIList list;
+-    analyzePath(sc, minSlack, getStart(sc), 0);
++    long worstMinSlackTime = (long) ((maxEnd - getStart(sc)) * minSlack);
++    analyzePath(sc, minSlack, getStart(sc), 0, worstMinSlackTime);
+ }
+ 
+ bool
+-Task::analyzePath(int sc, double minSlack, time_t pathStart, long busyTime)
++Task::analyzePath(int sc, double minSlack, time_t pathStart, long busyTime,
++                  long worstMinSlackTime)
+ {
+     if (DEBUGPA(14))
+         qDebug("  * Checking task %s", id.latin1());
+@@ -2971,7 +2972,8 @@
+             qDebug("  > Sub check started for %s", id.latin1());
+ 
+         for (TaskListIterator tli(*sub); *tli; ++tli)
+-            if ((*tli)->analyzePath(sc, minSlack, pathStart, busyTime))
++            if ((*tli)->analyzePath(sc, minSlack, pathStart, busyTime,
++                                    worstMinSlackTime))
+                 critical = true;
+ 
+         if (DEBUGPA(15))
+@@ -2979,73 +2981,86 @@
+     }
+     else
+     {
+-        bool hasFollowers = false;
+-
+         if (!milestone)
+-            busyTime += (getEnd(sc) - getStart(sc));
++            busyTime += (getEnd(sc) + 1 - getStart(sc));
++
++        /* If we have enough slack already that the path cannot be critical,
++         * we stop looking at the rest of the path. */
++        long currentSlack = (getEnd(sc) + 1 - pathStart) - busyTime;
++        if (currentSlack > worstMinSlackTime)
++        {
++            if (DEBUGPA(11))
++                qDebug("Path cannot be critical. Stopping at task %s",
++                       id.latin1());
++            return false;
++        }
+ 
+-        /* A task and its parent tasks can have the same followers. We keep a
+-         * list of already checked followers, so that we check each follower
+-         * only once, no matter whether it is a follower of the current task
+-         * or any of its parents. */
+-        TaskList checkedTasks;
++        /* We first have to gather a list of all followers of this task. This
++         * list must also include the followers registered for all parent
++         * tasks of this task as they are followers as well. */
++        TaskList allFollowers;
+         for (Task* task = this; task; task = task->getParent())
+         {
+-            if (task->followers.isEmpty())
+-                continue;
++            for (TaskListIterator tli(task->followers); *tli; ++tli)
++                if (allFollowers.findRef(*tli) < 0)
++                    allFollowers.append(*tli);
++        }
+ 
+-            hasFollowers = true;
++        /* We don't want to follow dependencies that were only specified to
++         * pass them on to the sub tasks. Such parent tasks are put in the
++         * ignore list. */
++        TaskList ignoreList;
++        for (TaskListIterator tli(allFollowers); *tli; ++tli)
++        {
++            /* If allFollowers contains any parent of *tli we can ignore
++             * the parent. */
++            for (Task* t = (*tli)->getParent(); t; t = t->getParent())
++                if (allFollowers.findRef(t) >= 0)
++                    ignoreList.append(t);
++        }
++
++        /* Compose a new list that contains the allFollowers minus the ignore
++         * list. */
++        TaskList followers;
++        for (TaskListIterator tli(allFollowers); *tli; ++tli)
++            if (ignoreList.findRef(*tli) < 0)
++                followers.append(*tli);
++
++        if (DEBUGPA(10))
++            if (followers.count() < allFollowers.count())
++                qDebug("Ignoring %d followers of task %s",
++                       allFollowers.count() - followers.count(), id.latin1());
+ 
++        /* Now we can check the pathes through the remaining followers. */
++        for (TaskListIterator tli(followers); *tli; ++tli)
++        {
+             if (DEBUGPA(16))
+-                qDebug("  > Follower check started for %s", task->id.latin1());
+-
+-            /* Due to inherited dependencies we can get a complexity explosion
+-             * in the number of possible pathes. All these pathes are
+-             * essentially identical to the path through the task that is
+-             * the furthest from the top-level task. So we only check this
+-             * path. */
+-            for (TaskListIterator tli(task->followers); *tli; ++tli)
+-            {
+-                Task* parent = (*tli)->getParent();
+-                if (parent && task->followers.findRef(parent) >= 0 &&
+-                    checkedTasks.find(parent) < 0)
+-                {
+-                    if (DEBUGPA(17))
+-                        qDebug("  - Ignoring path through parent task %s",
+-                               parent->getId().latin1());
+-                    checkedTasks.append(parent);
+-                }
+-            }
++                qDebug("  > Follower check started for %s",
++                       (*tli)->id.latin1());
+ 
+-            for (TaskListIterator tli(task->followers); *tli; ++tli)
++            if ((*tli)->analyzePath(sc, minSlack, pathStart, busyTime,
++                                    worstMinSlackTime))
+             {
+-                // Don't check each follower more than once.
+-                if (checkedTasks.findRef(*tli) >= 0)
+-                    continue;
+-
+-                if ((*tli)->analyzePath(sc, minSlack, pathStart, busyTime))
++                if (scenarios[sc].criticalLinks.findRef(*tli) < 0)
+                 {
+-                    if (task->scenarios[sc].criticalLinks.findRef(*tli) < 0)
+-                    {
+-                        if (DEBUGPA(5))
+-                            qDebug("  +++ Critical link %s -> %s",
+-                                   id.latin1(), (*tli)->id.latin1());
+-                        task->scenarios[sc].criticalLinks.append(*tli);
+-                    }
+-
+-                    critical = true;
++                    if (DEBUGPA(5))
++                        qDebug("  +++ Critical link %s -> %s",
++                               id.latin1(), (*tli)->id.latin1());
++                    scenarios[sc].criticalLinks.append(*tli);
+                 }
+-                checkedTasks.append(*tli);
++
++                critical = true;
+             }
+ 
+             if (DEBUGPA(16))
+-                qDebug("  < Follower check finished for %s", task->id.latin1());
++                qDebug("  < Follower check finished for %s",
++                       (*tli)->id.latin1());
+         }
+ 
+-        if (!hasFollowers)
++        if (followers.isEmpty())
+         {
+             // We've reached the end of a path. Now let's see if it's critical.
+-            long overallDuration = getEnd(sc) - pathStart;
++            long overallDuration = getEnd(sc) + 1 - pathStart;
+             /* A path is considered critical if the ratio of busy time and
+              * overall path time is above the minSlack threshold and the path
+              * contains more than one task. */
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/taskjuggler/Task.h taskjuggler-svn1380/taskjuggler/Task.h
+--- taskjuggler-2.3.1/taskjuggler/Task.h	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/taskjuggler/Task.h	2007-01-31 09:46:47.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: Task.h 1370 2007-01-14 15:54:54Z cs $
++ * $Id: Task.h 1376 2007-01-31 08:46:47Z cs $
+  */
+ 
+ #ifndef _Task_h_
+@@ -297,7 +297,7 @@
+     void finishScenario(int sc);
+     void computeCriticalness(int sc);
+     double getCriticalness(int sc) const { return scenarios[sc].criticalness; }
+-    void checkAndMarkCriticalPath(int sc, double minSlack);
++    void checkAndMarkCriticalPath(int sc, double minSlack, time_t maxEnd);
+ 
+     void computePathCriticalness(int sc);
+     double getPathCriticalness(int sc) const
+@@ -400,7 +400,8 @@
+     double computeBackwardCriticalness(int sc);
+     double computeForwardCriticalness(int sc);
+ 
+-    bool analyzePath(int sc, double minSlack, time_t pathStart, long busyTime);
++    bool analyzePath(int sc, double minSlack, time_t pathStart, long busyTime,
++                     long worstMinSlackTime);
+ 
+     bool countMilestones(int sc, time_t now, int& totalMilestones,
+                          int& completedMilestones,
+diff -Nur -x debian -x Makefile.in taskjuggler-2.3.1/TaskJugglerUI/TjPrintReport.cpp taskjuggler-svn1380/TaskJugglerUI/TjPrintReport.cpp
+--- taskjuggler-2.3.1/TaskJugglerUI/TjPrintReport.cpp	2007-01-31 20:21:32.000000000 +0100
++++ taskjuggler-svn1380/TaskJugglerUI/TjPrintReport.cpp	2007-02-02 09:37:48.000000000 +0100
+@@ -8,7 +8,7 @@
+  * it under the terms of version 2 of the GNU General Public License as
+  * published by the Free Software Foundation.
+  *
+- * $Id: TjPrintReport.cpp 1374 2007-01-28 16:49:27Z cs $
++ * $Id: TjPrintReport.cpp 1379 2007-02-02 08:37:48Z cs $
+  */
+ 
+ #include "TjPrintReport.h"
+@@ -271,7 +271,7 @@
+             }
+         }
+         else if ((*ci)->getName() == "duration")
+-            cellText = reportElement->scaledLoad
++            cellText = reportElement->scaledDuration
+                 (task->getCalcDuration(scenario), tcf->realFormat);
+         else if ((*ci)->getName() == "effort")
+         {




More information about the pkg-kde-commits mailing list