Re: [Planner Dev] "Nonstandard Days" and "Dominant tasks" - 6th patch



Hi guys, 

The changelog from 5th to 6th patch is:
  1) Integrated the Kurt's code style patch
  2) Solved the bug of white stripes in wide range time Gantt view.
  3) Used the overflow proof graphical functions (I had defined these
     before but I have forgotten to use them).

Regards, Matteo.

On Sat, Mar 25, 2006 at 09:13:48AM -0500, Kurt Maute wrote:
> On Fri, 2006-03-24 at 18:32 +0100, Richard Hult wrote:
> > Hi,
> > 
> > Thanks guys, this looks really nice :) Let's get it committed, maybe
> > after fixing the bug Kurt found?
> 
> Agree.  Once that bug is fixed we're ready to commit.
> 
> -- 
> Kurt Maute <kurt maute us>
> 
> _______________________________________________
> Planner-dev mailing list
> Planner-dev lists imendio com
> http://lists.imendio.com/mailman/listinfo/planner-dev

-- 
 Matteo Nastasi  -  Milano - Italy  | HomePage: www.alternativeoutput.it
 Sostenere e supportare GNU/Linux ! | IRC:    #linux-mi irc freenode net   
 Milano Linux                       | E-Mail:   matteo nastasi milug org 
        Users Group  www.milug.org  |       nastasi alternativeoutput it
* looking for nastasi alternativeoutput it--projects/planner--mop2--0--base-0 to compare with
* comparing to nastasi alternativeoutput it--projects/planner--mop2--0--base-0
A  {arch}/planner/planner--mop2/planner--mop2--0/nastasi alternativeoutput it--projects/patch-log/patch-1
A  {arch}/planner/planner--mop2/planner--mop2--0/nastasi alternativeoutput it--projects/patch-log/patch-2
M  libplanner/mrp-task.h
M  libplanner/mrp-task.c
M  src/planner-task-tree.c
M  configure.in
M  src/planner-gantt-chart.c
M  autogen.sh
M  data/ui/gantt-view.ui
M  libplanner/mrp-task-manager.c
M  src/planner-task-tree.h
M  src/planner-gantt-chart.h
M  libplanner/mrp-calendar.c
M  libplanner/mrp-calendar.h
M  src/planner-gantt-view.c
M  src/planner-task-view.c
M  src/planner-gantt-row.c
M  data/planner.schemas.in

* modified files

--- orig/autogen.sh
+++ mod/autogen.sh
@@ -163,7 +163,7 @@
   fi
 done
 
-conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
+conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c #--enable-simple-priority-scheduling
 
 cd "$ORIGDIR"
 


--- orig/configure.in
+++ mod/configure.in
@@ -249,6 +249,18 @@
 AM_CONDITIONAL(HAVE_EDS_PLUGIN, test x$use_eds = xyes)
 dnl -----------------------------------------------------------
 
+dnl  -----------------------------------
+dnl | Simple Priority Scheduling check |-----------------------------------------
+dnl  -----------------------------------
+AC_ARG_ENABLE(simple_priority_scheduling, [  --enable-simple-priority-scheduling       enable a simple priority scheduling in tasks management[default=no]], enable_simple_priority_scheduling="$enableval", enable_simple_priority_scheduling=no)
+if test "x$enable_simple_priority_scheduling" = "xyes" ; then
+    use_simple_priority_scheduling=yes
+    AC_DEFINE(WITH_SIMPLE_PRIORITY_SCHEDULING, 1, [Define to 1 to enable enable a simple priority scheduling in tasks management feature])
+else
+    use_simple_priority_scheduling=no
+fi
+AM_CONDITIONAL(HAVE_SIMPLE_PRIORITY_SCHEDULING, test x$use_simple_priority_scheduling = xyes)
+dnl -----------------------------------------------------------
 
 dnl  -------------------------------------
 dnl | Evolution Data Server Backend check |--------------------------------------
@@ -326,11 +338,16 @@
 echo "Python bindings              : $have_python"
 echo "Python plugin                : $enable_python_plugin"
 #echo "Dotnet bindings              : $have_dotnet"
+echo "Simple priority scheduling   : $use_simple_priority_scheduling"
 echo "Database/GDA support         : $use_gda"
 echo "Evolution Data Server import : $use_eds"
 echo "Evolution Data Server backend: $use_eds_backend"
 echo
 
+if test "x$use_simple_priority_scheduling" = "xyes" ; then
+	echo "*** Note: The use simple priority tasks scheduling is experimental. Don't use it in production systems ***"
+fi
+
 if test "x$enable_eds_backend" = "xyes" ; then
 	echo "*** Note: The Evolution backend is experimental. Don't use it in production systems ***"
 fi


--- orig/data/planner.schemas.in
+++ mod/data/planner.schemas.in
@@ -14,6 +14,18 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/planner/views/gantt_view/display_nonstandard_days</key>
+      <applyto>/apps/planner/views/gantt_view/display_nonstandard_days</applyto>
+      <owner>planner</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+        <short>Display nonstandard days in Gantt view</short>
+        <long>Whether to display nonstandard days in the Gantt view.</long>
+      </locale>
+    </schema>
+ 
+    <schema>
       <key>/schemas/apps/planner/views/task_view/highlight_critical_path</key>
       <applyto>/apps/planner/views/task_view/highlight_critical_path</applyto>
       <owner>planner</owner>


--- orig/data/ui/gantt-view.ui
+++ mod/data/ui/gantt-view.ui
@@ -14,6 +14,7 @@
       <placeholder name="View specific placeholder bottom">
         <menuitem    action="EditColumns"/>
         <menuitem    action="HighlightCriticalTasks"/>
+        <menuitem    action="NonstandardDays"/>
       </placeholder>
     </menu>
 


--- orig/libplanner/mrp-calendar.c
+++ mod/libplanner/mrp-calendar.c
@@ -1063,6 +1063,29 @@
 	}
 }
 
+/**
+ * mrp_interval_set_absolute:
+ * @interval: an #MrpInterval
+ * @offset: the offset to subtract to start and end
+ * @start: value of start time
+ * @end: value of end time
+ *
+ * Set the start and end time of #interval, with an optional @offset.
+ * 
+ **/
+void
+mrp_interval_set_absolute (MrpInterval *interval,
+			   mrptime     offset,
+			   mrptime     start,
+			   mrptime     end)
+{
+	g_return_if_fail (interval != NULL);
+	
+	interval->start = start - offset;
+
+	interval->end = end - offset;
+}
+
 static void
 foreach_day_interval_add_to_list (MrpDay  *day,
 				  GList  *intervals, 


--- orig/libplanner/mrp-calendar.h
+++ mod/libplanner/mrp-calendar.h
@@ -127,6 +127,10 @@
 						    mrptime      offset,
 						    mrptime     *start,
 						    mrptime     *end);
+void         mrp_interval_set_absolute             (MrpInterval *interval,
+						    mrptime      offset,
+						    mrptime      start,
+						    mrptime      end);
 
 
 #endif /* __MRP_CALENDAR_H__ */


--- orig/libplanner/mrp-task-manager.c
+++ mod/libplanner/mrp-task-manager.c
@@ -76,6 +76,12 @@
 task_manager_task_duration_notify_cb      (MrpTask             *task,
 					   GParamSpec          *spec,
 					   MrpTaskManager      *manager);
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+static void
+task_manager_task_priority_notify_cb      (MrpTask             *task,
+					   GParamSpec          *spec,
+					   MrpTaskManager      *manager);
+#endif
 static void
 task_manager_task_constraint_notify_cb    (MrpTask             *task,
 					   GParamSpec          *spec,
@@ -261,6 +267,13 @@
 			  "notify::duration",
 			  G_CALLBACK (task_manager_task_duration_notify_cb),
 			  manager);
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+	/* Added to manage the transaction from normal to dominant. */
+	g_signal_connect (task,
+			  "notify::priority",
+			  G_CALLBACK (task_manager_task_priority_notify_cb),
+			  manager);
+#endif
 	g_signal_connect (task,
 			  "notify::constraint",
 			  G_CALLBACK (task_manager_task_constraint_notify_cb),
@@ -1222,20 +1235,13 @@
 	return start;
 }
 
-typedef struct {
-	gboolean is_start;
-	mrptime  start;
-	mrptime  end;
-	gint     units;
-} UnitsInterval;
-
-#define UNIT_IVAL_GET_TIME(R) ((R->is_start?R->start:R->end))
-
+/* NOTE: MrpUnitsInterval moved in mrp-task.h to enable
+         other objects to use it. */
 static gint                                         
 units_interval_sort_func (gconstpointer a, gconstpointer b)
 {
-	UnitsInterval *ai = *(UnitsInterval **) a;
-	UnitsInterval *bi = *(UnitsInterval **) b;
+	MrpUnitsInterval *ai = *(MrpUnitsInterval **) a;
+	MrpUnitsInterval *bi = *(MrpUnitsInterval **) b;
 	mrptime       at, bt;
 
 	if (ai->is_start) {
@@ -1260,12 +1266,12 @@
 	}
 }
 
-static UnitsInterval *
+static MrpUnitsInterval *
 units_interval_new (MrpInterval *ival, gint units, gboolean is_start)
 {
-	UnitsInterval *unit_ival;
+	MrpUnitsInterval *unit_ival;
 
-	unit_ival = g_new (UnitsInterval, 1);
+	unit_ival = g_new (MrpUnitsInterval, 1);
 	unit_ival->is_start = is_start;
 	unit_ival->units = units;
 
@@ -1292,50 +1298,184 @@
 	MrpDay             *day;
 	GList              *ivals, *l;
 	MrpInterval        *ival;
-	UnitsInterval      *unit_ival, *new_unit_ival;
+
+	MrpUnitsInterval   *unit_ival, *new_unit_ival;
+	MrpUnitsInterval   *unit_ival_start, *unit_ival_end;
 	GList              *unit_ivals = NULL;
 	MrpAssignment      *assignment;
 	MrpResource        *resource;
 	GList              *assignments, *a;
-	gint                units;
+	gint                units, units_full, units_orig, priority;
+	mrptime             i_start, i_end;
+
 	mrptime             t;
 	mrptime             poc;
 	GPtrArray          *array;
 	guint               len;
 	gint                i;
 
+	mrptime             diffe;
+
+	gint     res_n;
+
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+	MrpInterval        *ival_split;
+	MrpUnitsInterval   *unit_ival_start_cmp;
+	MrpUnitsInterval   *split_unit_ival;
+	MrpAssignment      *v_assignment;
+	MrpResource        *v_resource;
+	GList              *v_assignments, *v_a;
+	gint                v_units;
+	GList              *v_tasks, *v_l;
+	GPtrArray          *array_split;
+	gint                e, lastct;
+	mrptime             v_start, v_end;
+	mrptime             i_start_post, i_end_post, i_start_cmp, i_end_cmp;
+#endif
+
 	priv = manager->priv;
 
 	assignments = mrp_task_get_assignments (task);
 
 	array = g_ptr_array_new ();
+	priority    = mrp_task_get_priority (task);
+	
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+	v_tasks = mrp_task_manager_get_all_tasks (manager);
+#endif
 	
 	for (a = assignments; a; a = a->next) {
 		assignment = a->data;
 		
 		resource = mrp_assignment_get_resource (assignment);
-		units = mrp_assignment_get_units (assignment);
+		units_orig = mrp_assignment_get_units (assignment);
 
 		calendar = mrp_resource_get_calendar (resource);
 		if (!calendar) {
 			calendar = mrp_project_get_calendar (priv->project);
 		}
-
 		day = mrp_calendar_get_day (calendar, date, TRUE);
 		ivals = mrp_calendar_day_get_intervals (calendar, day, TRUE);
 
 		for (l = ivals; l; l = l->next) {
 			ival = l->data;
+			mrp_interval_get_absolute (ival, date, &i_start, &i_end);
+			units = units_orig;
+			diffe = i_end - i_start;
+			
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+			for (v_l = v_tasks; v_l; v_l = v_l->next) {
+				MrpTask *v_task;
+				
+				v_task =  v_l->data;
+				
+				if (v_task == task) {
+					continue;
+				}
+
+				if (mrp_task_is_dominant (v_task) == FALSE) {
+					continue;
+				}
 
+				/* If intervals not overlapped -> contine. */
+				v_start = mrp_task_get_work_start (v_task);
+				v_end = mrp_task_get_finish (v_task);
+					
+				if (i_start > v_end || i_end < v_start) {
+					continue;
+				}
+
+				/* Compare resources task with resources of dominant task. */
+				v_assignments = mrp_task_get_assignments (v_task);
+
+				for (v_a = v_assignments; v_a; v_a = v_a->next) {
+					v_assignment = v_a->data;
+		
+					v_resource = mrp_assignment_get_resource (v_assignment);
+					if (v_resource == resource) {
+						v_units = mrp_assignment_get_units (v_assignment);
+						/* 
+						   If the dominant cost is compatible with the task
+						   request -> break. 
+
+						   FIXME - tasks that share the vampirised resource not work!
+						*/
+						if (100 - v_units > units) {
+							break;
+						}
+
+						/* Trim the interval of the dominant task. */
+						v_start = (v_start < i_start ? 
+								   i_start : v_start);
+						v_end = (v_end > i_end ?
+								 i_end : v_end);
+						
+						if (i_start < v_start) {
+							/*
+							     ----...
+							   ------...
+							   ival len from start to dominant
+							*/
+							ival = mrp_interval_new (i_start-date, v_start-date);
+
+							unit_ival_start = units_interval_new (ival, units, TRUE);
+							unit_ival_start->units_full = units;
+							unit_ival_end = units_interval_new (ival, units, FALSE);
+							unit_ival_end->units_full = units;
+							g_ptr_array_add (array, unit_ival_start);
+							g_ptr_array_add (array, unit_ival_end);
+						}
+						
+						ival = mrp_interval_new (v_start-date, v_end-date);
+
+						unit_ival_start = units_interval_new (ival, (100 - v_units), TRUE);
+						unit_ival_start->units_full = units;
+						unit_ival_end = units_interval_new (ival, (100 - v_units), FALSE);
+						unit_ival_end->units_full = units;						
+						g_ptr_array_add (array, unit_ival_start);
+						g_ptr_array_add (array, unit_ival_end);
+
+						if (v_end < i_end) {
+							/*
+							   ----  ...
+							   ------...
+							   ival len from end to dominant
+							*/
+							ival = mrp_interval_new (v_end-date, i_end-date);
+
+							unit_ival_start = units_interval_new (ival, units, TRUE);
+							unit_ival_start->units_full = units;
+							unit_ival_end = units_interval_new (ival, units, FALSE);
+							unit_ival_end->units_full = units;
+							g_ptr_array_add (array, unit_ival_start);
+							g_ptr_array_add (array, unit_ival_end);
+						}
+						break;
+					}
+				} /* for (v_a = v_assignments; v_a; ... */
+				if (v_a != NULL) {
+					break;
+				}
+			} /* for (v_l = v_tasks; v_l; ... */
+			
+	
+			if (v_l == NULL) {
+#endif /* ifdef WITH_SIMPLE_PRIORITY_SCHEDULING */
 			/* Start of the interval. */
-			unit_ival = units_interval_new (ival, units, TRUE);
-			g_ptr_array_add (array, unit_ival);
+				unit_ival_start = units_interval_new (ival, units, TRUE);
+				unit_ival_start->units_full = units;
 
 			/* End of the interval. */
-			unit_ival = units_interval_new (ival, units, FALSE);
-			g_ptr_array_add (array, unit_ival);
-		}
-	}
+				unit_ival_end = units_interval_new (ival, units, FALSE);
+				unit_ival_end->units_full = units;
+
+				g_ptr_array_add (array, unit_ival_start);
+				g_ptr_array_add (array, unit_ival_end);
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+			}
+#endif
+		} /* for (l = ivals; l; ... */
+	} /* for (a = assignments; a; ... */
 
 	/* If the task is not allocated, we handle it as if we have one resource
 	 * assigned to it, 100%, using the project calendar.
@@ -1351,20 +1491,82 @@
 			
 			/* Start of the interval. */
 			unit_ival = units_interval_new (ival, 100, TRUE);
+			unit_ival->units_full = 100;
 			g_ptr_array_add (array, unit_ival);
 
 			/* End of the interval. */
 			unit_ival = units_interval_new (ival, 100, FALSE);
+			unit_ival->units_full = 100;
 			g_ptr_array_add (array, unit_ival);
 		}
 	}
 	
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+	/* Requantize the time intervals. */
+	array_split = g_ptr_array_new ();
+	len = array->len;
+	poc = -1;
+	units = 0;
+	/* += 2 because start and end are strictly joined. */
+	for (i = 0; i < len; i+= 2) {
+		unit_ival_start = g_ptr_array_index (array, i);
+
+		i_start = unit_ival_start->start;
+		i_end = unit_ival_start->end;
+
+		lastct = 1;
+		i_end_post = i_end;
+		for (i_start_post = i_start; i_start_post < i_end && lastct > 0;) {
+			lastct = 0;
+			i_end_post = i_end;
+			for (e = 0 ; e < len ; e+= 2) {
+				unit_ival_start_cmp = g_ptr_array_index (array, e);
+				
+				i_start_cmp = unit_ival_start_cmp->start;
+				i_end_cmp = unit_ival_start_cmp->end;
+
+				/* If not overlapped intervals. */
+				if (i_start_post >= i_end_cmp || i_end_post <= i_start_cmp) {
+					continue;
+				}
+				if (i_start_post < i_start_cmp && i_start_cmp < i_end_post) {
+					i_end_post = i_start_cmp;
+					lastct++;
+					continue;
+				}
+				if (i_start_post < i_end_cmp && i_end_cmp < i_end_post) {
+					i_end_post = i_end_cmp;
+					lastct++;
+					continue;
+				}
+			}
+			ival_split = mrp_interval_new (i_start_post, i_end_post);
+			split_unit_ival = units_interval_new (ival_split, unit_ival_start->units, TRUE);
+			split_unit_ival->units_full = unit_ival_start->units_full;
+			g_ptr_array_add (array_split, split_unit_ival);
+			split_unit_ival = units_interval_new (ival_split, unit_ival_start->units, FALSE);
+			split_unit_ival->units_full = unit_ival_start->units_full;
+			g_ptr_array_add (array_split, split_unit_ival);
+			i_start_post = i_end_post;
+		}
+	}
+	for (i = 0; i < array->len; i++) {
+		g_free (array->pdata[i]);
+	}
+	
+	g_ptr_array_free (array, TRUE);
+	array = array_split;
+#endif /* ifdef WITH_SIMPLE_PRIORITY_SCHEDULING */
+	/* Clean and reassign the split_array ptr to the array */
 	g_ptr_array_sort (array, units_interval_sort_func);
 
 	len = array->len;
 
+
 	poc = -1;
 	units = 0;
+	units_full = 0;
+	res_n = 0;
 	for (i = 0; i < len; i++) {
 		unit_ival = g_ptr_array_index (array, i);		
 
@@ -1376,23 +1578,28 @@
 			 * determined by now.
 			 */
 			if (poc != -1) {
-				if (units > 0) {
-					new_unit_ival = g_new (UnitsInterval, 1);
-					new_unit_ival->units = units;
-					new_unit_ival->start = poc;
-					new_unit_ival->end = t;
-					
-					unit_ivals = g_list_prepend (unit_ivals, new_unit_ival);
-				}
+				new_unit_ival = g_new (MrpUnitsInterval, 1);
+				new_unit_ival->units = units;
+				new_unit_ival->units_full = units_full;
+				new_unit_ival->start = poc;
+				new_unit_ival->end = t;
+				new_unit_ival->res_n = res_n;
+				res_n = 0;
+				unit_ivals = g_list_prepend (unit_ivals, new_unit_ival);
 			}
-				
+			
 			poc = t;
 		}
-
+		
 		if (unit_ival->is_start) {
 			units += unit_ival->units;
+			units_full += unit_ival->units_full;
+			if (assignments) {
+				res_n++;
+			}
 		} else {
 			units -= unit_ival->units;
+			units_full -= unit_ival->units_full;
 		}
 	}
 
@@ -1416,7 +1623,7 @@
 	mrptime             t1, t2;
 	mrptime             work_start;
 	GList              *unit_ivals, *l;
-	UnitsInterval      *unit_ival;
+	MrpUnitsInterval   *unit_ival;
 	MrpTaskType         type;
 	
 	priv = manager->priv;
@@ -1499,11 +1706,12 @@
 	gint                work;
 	gint                effort;
 	gint                delta;
-	GList              *unit_ivals, *l;
-	UnitsInterval      *unit_ival;
+	GList              *unit_ivals, *unit_ivals_tot = NULL, *l = NULL;
+	MrpUnitsInterval   *unit_ival;
 	MrpTaskType         type;
 	MrpTaskSched        sched;
 	
+   
 	priv = manager->priv;
 
 	if (task == priv->root) {
@@ -1547,6 +1755,7 @@
 		}
 
 		if (!unit_ivals) {
+			/* Holidays for all. */
 			t += 60*60*24;
 			continue;
 		}
@@ -1556,7 +1765,6 @@
 
 			t1 = t + unit_ival->start;
 			t2 = t + unit_ival->end;
-			
 			/* Skip any intervals before the task starts. */
 			if (t2 < start) {
 				continue;
@@ -1577,15 +1785,23 @@
 			if (sched == MRP_TASK_SCHED_FIXED_WORK) {
 				delta = floor (0.5 + (double) unit_ival->units * (t2 - t1) / 100.0);
 
-				*duration += (t2 - t1);
-				
+				if (unit_ival->units_full > 0) {
+					*duration += (t2 - t1);
+				}
+
 				if (effort + delta >= work) {
 					finish = t1 + floor (0.5 + (work - effort) / unit_ival->units * 100.0);
 
 					/* Subtract the spill. */
 					*duration -= floor (0.5 + (effort + delta - work) / unit_ival->units * 100.0);
+					unit_ival->start = t1;
+					unit_ival->end = finish;
+					unit_ivals_tot = g_list_prepend (unit_ivals_tot, unit_ival);
 					goto done;
 				}
+				unit_ival->start = t1;
+				unit_ival->end = t2;
+				unit_ivals_tot = g_list_prepend (unit_ivals_tot, unit_ival);
 			}
 			else if (sched == MRP_TASK_SCHED_FIXED_DURATION) {
 				delta = t2 - t1;
@@ -1602,7 +1818,6 @@
 			
 			effort += delta;
 		}
-		
 		t += 60*60*24;
 	}
 
@@ -1613,9 +1828,18 @@
 	}
 	imrp_task_set_work_start (task, work_start);
 
-	g_list_foreach (unit_ivals, (GFunc) g_free, NULL);
+	/* clean the tail of the list before exit of function. */
+	if (l) {
+		for (l = l->next ; l; l = l->next) { 
+			unit_ival = l->data;
+		g_free (unit_ival);
+		}
+	}
 	g_list_free (unit_ivals);
 
+	unit_ivals_tot = g_list_reverse (unit_ivals_tot);
+	mrp_task_set_unit_ivals (task, unit_ivals_tot);
+
 	return finish;
 }
 
@@ -1976,6 +2200,15 @@
 	mrp_task_manager_recalc (manager, TRUE);
 }
 
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+static void
+task_manager_task_priority_notify_cb (MrpTask        *task,
+									  GParamSpec     *spec,
+									  MrpTaskManager *manager)
+{
+	mrp_task_manager_recalc (manager, TRUE);
+}
+#endif
 static void
 task_manager_task_constraint_notify_cb (MrpTask        *task,
 					GParamSpec     *spec,
@@ -2100,8 +2333,9 @@
 	
 	node = imrp_task_get_graph_node (task);
 	for (l = node->next; l; l = l->next) {
-		if (!check_predecessor_traverse (manager, l->data, end, length + 1))
+		if (!check_predecessor_traverse (manager, l->data, end, length + 1)) {
 			return FALSE;
+		}
 	}
 	
 	return TRUE;
@@ -2254,6 +2488,80 @@
 	return work;
 }
 
+static gint
+task_manager_get_work_for_task_with_assignments (MrpTaskManager *manager,
+									   MrpTask        *task,
+									   mrptime         start,
+									   mrptime         finish)
+{
+	MrpTaskManagerPriv *priv;
+	mrptime             t;
+	mrptime             t1, t2;
+	gint                work, delta;
+	GList              *ivals, *l;
+	MrpUnitsInterval   *ival;
+
+	priv = manager->priv;
+
+	work = 0;
+
+	/* Loop through the intervals of the calendar and add up the work, until
+	 * the finish time is hit.
+	 */
+	t = mrp_time_align_day (start);
+
+
+	while (t < finish) {
+		ivals = task_manager_get_task_units_intervals (manager, task, t);
+
+		/* If we don't get anywhere in 100 days, then the calendar must
+		 * be broken, so we abort the scheduling of this task. It's not
+		 * the best solution but fixes the issue for now.
+		 */
+		if (work == 0 && t - start > (60*60*24*100)) {
+			break;
+		}
+
+		if (!ivals) {
+			/* Holidays for all. */
+			t += 60*60*24;
+			continue;
+		}
+		
+		for (l = ivals; l; l = l->next) { 
+			ival = l->data;
+
+			t1 = t + ival->start;
+			t2 = t + ival->end;
+			/* Skip any intervals before the task starts. */
+			if (t2 < start) {
+				continue;
+			}
+
+			/* Don't add time before the start of the task. */
+			t1 = MAX (t1, start);
+			if (t1 == t2) {
+				continue;
+			}
+
+			/* Resize the too long interval */
+			t2 = MIN (t2, finish);
+			if (t1 >= t2) {
+				break;
+			}
+
+			delta = floor (0.5 + (double) ival->units * (t2 - t1) / 100.0);
+			
+			work += delta;
+		}
+	
+
+		t += 24*60*60;
+	}
+
+	return (work);
+}
+
 /* Calculate the work needed to achieve the specified start and finish, with the
  * allocated resources' calendars in consideration.
  */
@@ -2265,9 +2573,7 @@
 {
 	MrpTaskManagerPriv *priv;
 	gint                work = 0;
-	MrpAssignment      *assignment;
-	MrpResource        *resource;
-	GList              *assignments, *a;
+	GList              *assignments;
 	MrpCalendar        *calendar;
 
 	priv = manager->priv;
@@ -2293,24 +2599,13 @@
 	 */
 
 	assignments = mrp_task_get_assignments (task);
-	for (a = assignments; a; a = a->next) {
-		assignment = a->data;
-
-		resource = mrp_assignment_get_resource (assignment);
-
-		calendar = mrp_resource_get_calendar (resource);
-		if (!calendar) {
-			calendar = mrp_project_get_calendar (priv->project);
-		}
-
-		work += task_manager_get_work_for_calendar (manager,
-							    calendar,
-							    start,
-							    finish) *
-			mrp_assignment_get_units (assignment) / 100;
+	if (assignments) {
+		work = task_manager_get_work_for_task_with_assignments (manager,
+													  task,
+													  start,
+													  finish);
 	}
-	
-	if (!assignments) {
+	else {
 		calendar = mrp_project_get_calendar (priv->project);
 
 		work = task_manager_get_work_for_calendar (manager,


--- orig/libplanner/mrp-task.c
+++ mod/libplanner/mrp-task.c
@@ -125,6 +125,9 @@
 	/* List of assignments. */
 	GList            *assignments;
 
+	/* Intervals to build graphical view of the task */
+	GList            *unit_ivals;
+
 	gfloat            cost;
 	gboolean          cost_cached;
 };
@@ -195,6 +198,7 @@
 
 	priv->cost = 0.0;
  	priv->cost_cached = FALSE;
+	priv->unit_ivals = NULL;
 }
 
 static void
@@ -1499,6 +1503,89 @@
 }
 
 /**
+ * mrp_task_get_priority:
+ * @task: an #MrpTask
+ * 
+ * Retrieves the priority of @task.
+ * 
+ * Return value: The priority of @task.
+ **/
+gint
+mrp_task_get_priority (MrpTask *task)
+{
+	g_return_val_if_fail (MRP_IS_TASK (task), 0);
+	
+	return task->priv->priority;
+}
+
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+/**
+ * mrp_task_is_dominant:
+ * @task: an #MrpTask
+ * 
+ * Retrieves if @task is a dominant task.
+ * 
+ * Return value: if @task is a dominant task.
+ **/
+gboolean
+mrp_task_is_dominant (MrpTask *task)
+{
+	MrpConstraint constraint;
+
+	g_return_val_if_fail (MRP_IS_TASK (task), 0);
+	
+	constraint = impr_task_get_constraint (task);
+	if (constraint.type  != MRP_CONSTRAINT_MSO) {
+		return (FALSE);
+	}
+
+	if (task->priv->priority != MRP_DOMINANT_PRIORITY) {
+		return (FALSE);
+	}
+
+	return (TRUE);
+}
+#endif
+/**
+ * mrp_task_get_unit_ivals:
+ * @task: an #MrpTask
+ * 
+ * Retrieves the list of intervals of @task.
+ * 
+ * Return value: Intervals of @task.
+ **/
+GList *
+mrp_task_get_unit_ivals (MrpTask *task)
+{
+	g_return_val_if_fail (MRP_IS_TASK (task), 0);
+
+	return task->priv->unit_ivals;
+}
+
+/**
+ * mrp_task_set_unit_ivals:
+ * @task: an #MrpTask
+ * 
+ * Set the list of intervals of @task.
+ * 
+ * Return value: Intervals of @task.
+ **/
+GList *
+mrp_task_set_unit_ivals (MrpTask *task, GList *ivals)
+{
+	g_return_val_if_fail (MRP_IS_TASK (task), 0);
+
+	if (task->priv->unit_ivals) {
+		g_list_foreach (task->priv->unit_ivals, (GFunc) g_free, NULL);
+		g_list_free (task->priv->unit_ivals);
+		task->priv->unit_ivals = NULL;
+	}
+	task->priv->unit_ivals = ivals;
+
+	return task->priv->unit_ivals;
+}
+
+/**
  * mrp_task_get_assignments:
  * @task: an #MrpTask
  * 
@@ -1515,6 +1602,28 @@
 }
 
 /**
+ * mrp_task_get_nres:
+ * @task: an #MrpTask
+ * 
+ * Calculate the number of resources assigned to task.
+ * 
+ * Return value: the number of resources.
+ **/
+gint mrp_task_get_nres (MrpTask *task)
+{
+	GList *assignments, *a;
+	gint nres = 0;
+
+	assignments = mrp_task_get_assignments (task);
+
+	for (a = assignments; a; a = a->next) {
+		nres++;
+	}
+	
+	return (nres);
+}
+
+/**
  * mrp_task_get_assignment:
  * @task: an #MrpTask
  * @resource: an #MrpResource


--- orig/libplanner/mrp-task.h
+++ mod/libplanner/mrp-task.h
@@ -42,6 +42,33 @@
 typedef struct _MrpTaskClass MrpTaskClass;
 typedef struct _MrpTaskPriv  MrpTaskPriv;
 
+/*
+  NOTE: moved from libplanner/mrp-task-manager.c to use 
+         the structure in the src/planner-gantt-row.c
+         new fields are:
+           units      . worked units in the interval
+           units_full . expected worked units in the interval 
+                        all resources that are working in the
+                        interval in the right percentage
+           res_n      . number of expected resources working
+                        at the task in the interval
+*/
+typedef struct {
+	gboolean is_start;
+	mrptime  start;
+	mrptime  end;
+	gint     units;
+	gint     units_full;
+	gint     res_n;	
+} MrpUnitsInterval;
+
+#define UNIT_IVAL_GET_TIME(R) ((R->is_start?R->start:R->end))
+
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+/* Value of the magic priority of a dominant task. */
+#define MRP_DOMINANT_PRIORITY           9999
+#endif
+
 #include <libplanner/mrp-relation.h>
 
 struct _MrpTask
@@ -95,7 +122,17 @@
 mrptime          mrp_task_get_latest_finish         (MrpTask          *task);
 gint             mrp_task_get_duration              (MrpTask          *task);
 gint             mrp_task_get_work                  (MrpTask          *task);
+gint             mrp_task_get_priority              (MrpTask          *task);
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+gboolean         mrp_task_is_dominant               (MrpTask          *task);
+#endif
+GList *          mrp_task_get_unit_ivals            (MrpTask          *task);
+GList *          mrp_task_set_unit_ivals            (MrpTask          *task,
+						     GList *ivals);
 GList           *mrp_task_get_assignments           (MrpTask          *task);
+gint             mrp_task_get_nres                  (MrpTask          *task);
+
+gint             mrp_task_get_fullwork              (MrpTask          *task);
 MrpAssignment   *mrp_task_get_assignment            (MrpTask          *task,
 						     MrpResource      *resource);
 void             mrp_task_reset_constraint          (MrpTask          *task);


--- orig/src/planner-gantt-chart.c
+++ mod/src/planner-gantt-chart.c
@@ -53,7 +53,8 @@
 /* Font width factor. */
 static gdouble f = 1.0;
 
-#define CRITICAL_PATH_KEY "/views/gantt_view/highlight_critical_path"
+#define CRITICAL_PATH_KEY  "/views/gantt_view/highlight_critical_path"
+#define NOSTDDAYS_PATH_KEY "/views/gantt_view/display_nonstandard_days"
 
 
 typedef struct _TreeNode TreeNode; 
@@ -103,6 +104,9 @@
 
 	/* Critical path. */
 	gboolean         highlight_critical;
+	
+	/* Nonstandard days visualization */
+	gboolean         nonstandard_days;
 
 	/* Keep a list of signal connection ids, so we can remove them
 	 * easily.
@@ -384,6 +388,8 @@
 
 	priv->highlight_critical = planner_conf_get_bool (CRITICAL_PATH_KEY,
 							  NULL);
+	priv->nonstandard_days   = planner_conf_get_bool (NOSTDDAYS_PATH_KEY,
+							  NULL);
 }
 
 static void
@@ -1917,3 +1923,32 @@
 
 	return chart->priv->highlight_critical;
 }
+
+void
+planner_gantt_chart_set_nonstandard_days (PlannerGanttChart *chart,
+						  gboolean           state)
+{
+	PlannerGanttChartPriv *priv;
+	
+	g_return_if_fail (PLANNER_IS_GANTT_CHART (chart));
+
+	priv = chart->priv;
+
+	if (priv->nonstandard_days == state) {
+		return;
+	}
+	
+	priv->nonstandard_days = state;
+	
+	gtk_widget_queue_draw (GTK_WIDGET (priv->canvas));
+
+	planner_conf_set_bool (NOSTDDAYS_PATH_KEY, state, NULL);
+}
+
+gboolean
+planner_gantt_chart_get_nonstandard_days (PlannerGanttChart *chart)
+{
+	g_return_val_if_fail (PLANNER_IS_GANTT_CHART (chart), FALSE);
+
+	return chart->priv->nonstandard_days;
+}


--- orig/src/planner-gantt-chart.h
+++ mod/src/planner-gantt-chart.h
@@ -90,5 +90,11 @@
 gboolean
 planner_gantt_chart_get_highlight_critical_tasks      (PlannerGanttChart  *chart);
 
+void
+planner_gantt_chart_set_nonstandard_days             (PlannerGanttChart *chart,
+							   gboolean           state);
+gboolean
+planner_gantt_chart_get_nonstandard_days             (PlannerGanttChart *chart);
+
 
 #endif /* __PLANNER_GANTT_CHART_H__ */


--- orig/src/planner-gantt-row.c
+++ mod/src/planner-gantt-row.c
@@ -28,6 +28,7 @@
 #include <libplanner/mrp-project.h>
 #include <libplanner/mrp-resource.h>
 #include <libplanner/mrp-task.h>
+#include <libplanner/mrp-calendar.h>
 #include <glib/gi18n.h>
 #include <libgnomecanvas/gnome-canvas.h>
 #include "planner-marshal.h"
@@ -57,6 +58,21 @@
 /* Minimum width for a task to keep it visible. */
 #define MIN_WIDTH 2
 
+/* Trim the value to short int work space. */
+#define TRSH(a) ((int)((a) < SHRT_MIN ? (short int)SHRT_MIN : ((a) > SHRT_MAX ? (short int)SHRT_MAX : (a))))
+
+/* Same gdk_draw_rectangle but with trimmed x,y,w,h args. */
+#define draw_cut_rectangle(a,b,c,d,e,f,g)		\
+		gdk_draw_rectangle ((a), (b), (c), TRSH (d), TRSH (e), TRSH (f), TRSH (g))
+
+/* Same gdk_draw_line but with trimmed x1,y1,x2,y2 args. */
+#define draw_cut_line(a,b,c,d,e,f)		 \
+		gdk_draw_line ((a), (b), TRSH (c), TRSH (d), TRSH (e), TRSH (f))  
+
+/* Same gdk_draw_layout but with trimmed x,y args. */
+#define draw_cut_layout(a,b,c,d,e)		         \
+		gdk_draw_layout ((a), (b), TRSH (c), TRSH (d), (e))
+
 enum {
 	PROP_0,
 	PROP_X,
@@ -91,6 +107,8 @@
 	GdkGC       *break_gc;
 	GdkGC       *fill_gc;
 	GdkGC       *frame_gc;
+	GdkGC       *ttask_gc;
+
 
 	/* FIXME: Don't need those per gantt row. */
 	GdkColor     color_normal;
@@ -130,6 +148,8 @@
 	/* Cached values for the geometry of the bar. */
 	gdouble      width;
 	gdouble      height;
+	gdouble      bar_top; /* Top y position of the bar. */
+	gdouble      bar_bot; /* Bottom y position of the bar. */
 	gdouble      text_width;
 
 	/* Cached positions of each assigned resource. */
@@ -211,13 +231,35 @@
 						       gint                  *x1,
 						       gint                  *x2);
 
-static PlannerCmd *task_cmd_edit_property (PlannerWindow   *window,
-					   PlannerTaskTree *tree,
-					   MrpTask         *task,
-					   const gchar     *property,
-					   const GValue    *value);
-
-static GList *  gantt_row_get_selected_tasks (GtkTreeSelection *selection);
+static PlannerCmd *task_cmd_edit_property             (PlannerWindow   *window,
+					               PlannerTaskTree *tree,
+						       MrpTask         *task,
+						       const gchar     *property,
+						       const GValue    *value);
+
+static GList *  gantt_row_get_selected_tasks          (GtkTreeSelection      *selection);
+
+static MrpUnitsInterval * mop_get_next_ival           (GList                **cur, 
+						       gint                  *is_a_gap, 
+                                                       GList                 *start, 
+                                                       MrpUnitsInterval      *buf);
+static MrpInterval *      mop_get_next_mrp_ival       (GList                **cur, 
+                                                       gint                  *is_a_gap, 
+                                                       GList                 *start, 
+                                                       MrpInterval           *buf);
+static gboolean gantt_draw_tasktime                   (GdkDrawable           *drawable,
+						       GdkGC                 *gc,
+						       GnomeCanvas           *canvas,
+						       gdouble                start_wx, 
+						       gdouble                start_wy, 
+						       gdouble                end_wx, 
+						       gdouble                end_wy, 
+						       gint                   cy1, 
+						       gint                   cy2,
+						       gint                   x,
+                                                       gint                   y, 
+						       gboolean               is_up, 
+						       gchar                 *colorname);
 
 
 static GnomeCanvasItemClass *parent_class;
@@ -365,6 +407,8 @@
 	priv->y = 0.0;
 	priv->width = 0.0;
 	priv->height = 0.0;
+	priv->bar_top = 0.0;
+	priv->bar_bot = 0.0;
 	priv->scale = 1.0;
 	priv->visible = TRUE;
 	priv->highlight = FALSE;
@@ -529,7 +573,19 @@
 	case PROP_HEIGHT:
 		tmp_dbl = g_value_get_double (value);
 		if (tmp_dbl != priv->height) {
+			gboolean             nonstd_days;
+			PlannerGanttChart   *chart;
+			double               htask;
+
+			chart = g_object_get_data (G_OBJECT (item->canvas), "chart");
+			nonstd_days = planner_gantt_chart_get_nonstandard_days (chart);
+
 			priv->height = tmp_dbl;
+
+			htask = priv->height / 2.0;
+			priv->bar_top = ((priv->height - htask) / 2.0);
+			priv->bar_bot = ((priv->height + htask) / 2.0);
+
 			changed = TRUE;
 		}
 		break;
@@ -807,6 +863,8 @@
 
 	priv->frame_gc = gdk_gc_new (item->canvas->layout.bin_window);
 
+	priv->ttask_gc = gdk_gc_new (item->canvas->layout.bin_window);
+
 	gnome_canvas_get_color (item->canvas,
 				"LightSkyBlue3",
 				&priv->color_normal);
@@ -847,6 +905,9 @@
 	gdk_gc_unref (row->priv->frame_gc);
 	row->priv->frame_gc = NULL;
 
+	gdk_gc_unref (row->priv->ttask_gc);
+	row->priv->ttask_gc = NULL;
+
 	if (break_stipple) {
 		g_object_unref (break_stipple);
 	}
@@ -868,6 +929,221 @@
 				    GDK_JOIN_MITER);
 }
 
+
+static MrpUnitsInterval *mop_get_next_ival(GList **cur, gint *is_a_gap, GList *start, MrpUnitsInterval *buf)
+{
+	MrpUnitsInterval *cur_ival;
+	gint last_end, md;
+	
+	if (start) {
+		*cur = start;
+		cur_ival = start->data;
+		md = cur_ival->start % (24*60*60);
+		if (md > 0) {
+			buf->start = cur_ival->start - md;
+			buf->end = cur_ival->start;
+			buf->units = 0;
+			buf->units_full = 0;
+			buf->res_n = 0;
+	
+			*is_a_gap = 1;
+			
+			return (buf);
+		}
+		else {
+			*is_a_gap = 0;
+			return (cur_ival);
+		}
+	}
+	if ((*cur) == NULL) {
+		return (NULL);
+	}
+
+	cur_ival = (*cur)->data;
+
+	if (*is_a_gap == 1) { /* last was a gap */
+			*is_a_gap = 0;
+			return (cur_ival);		
+	}
+	else {
+		if ((*cur)->next != NULL) {
+			last_end = cur_ival->end;
+			*cur = (*cur)->next;
+			cur_ival = (*cur)->data;
+			
+			if (last_end < cur_ival->start) { /* another gap */
+				buf->start = last_end;
+				buf->end = cur_ival->start;
+				buf->units = 0;
+				buf->units_full = 0;
+				buf->res_n = 0;
+
+				*is_a_gap = 1;
+				return (buf);
+			}
+			else {
+				*is_a_gap = 0;
+				return (cur_ival);
+			}
+		}
+		else {
+			md = cur_ival->end % (24*60*60);
+			if (md > 0) {
+				buf->start      = cur_ival->end;
+				buf->end        = cur_ival->end - md + (24*60*60);
+				buf->units = 0;
+				buf->units_full = 0;
+				buf->res_n = 0;
+
+				*is_a_gap = 1;
+				*cur = NULL;
+				return (buf);
+			}
+			else {
+				return (NULL);
+			}
+		}
+	}
+
+	return (NULL);
+}
+
+
+
+static MrpInterval *mop_get_next_mrp_ival(GList **cur, gint *is_a_gap, GList *start, MrpInterval *buf)
+{
+	MrpInterval *cur_ival;
+	gint last_end, md;
+	mrptime cur_start, cur_end; 
+	
+	if (start) {
+		*cur = start;
+		cur_ival = start->data;
+
+		mrp_interval_get_absolute (cur_ival, 0, &cur_start, &cur_end);
+		md = cur_start % (24*60*60);
+		if (md > 0) {
+			mrp_interval_set_absolute (buf, 0, 0, cur_start);
+			*is_a_gap = 1;
+			
+			return (buf);
+		}
+		else {
+			*is_a_gap = 0;
+			return (cur_ival);
+		}
+	}
+	if ((*cur) == NULL) {
+		return (NULL);
+	}
+
+	cur_ival = (*cur)->data;
+	mrp_interval_get_absolute (cur_ival, 0, &cur_start, &cur_end);
+
+	if (*is_a_gap == 1) { /* last was a gap */
+			*is_a_gap = 0;
+			return (cur_ival);		
+	}
+	else {
+		if ((*cur)->next != NULL) {
+			last_end = cur_end;
+			*cur = (*cur)->next;
+			cur_ival = (*cur)->data;
+			mrp_interval_get_absolute (cur_ival, 0, &cur_start, &cur_end);
+			
+			if (last_end < cur_start) { /* another gap */
+				mrp_interval_set_absolute (buf, 0, last_end, cur_start);
+
+				*is_a_gap = 1;
+				return (buf);
+			}
+			else {
+				*is_a_gap = 0;
+				return (cur_ival);
+			}
+		}
+		else {
+			md = cur_end % (24*60*60);
+			if (md > 0) {
+				mrp_interval_set_absolute (buf, 0, cur_end, cur_end - md + (24*60*60));
+	
+				*is_a_gap = 1;
+				*cur = NULL;
+				return (buf);
+			}
+			else {
+				return (NULL);
+			}
+		}
+	}
+
+	return (NULL);
+}
+
+
+static gboolean gantt_draw_tasktime(GdkDrawable *drawable,
+							 GdkGC *gc,
+							 GnomeCanvas *canvas,
+							 gdouble start_wx, gdouble start_wy, 
+							 gdouble end_wx, gdouble end_wy, 
+							 gint cy1, gint cy2,
+							 gint x, gint y, 
+							 gboolean is_up, 
+							 gchar *colorname)
+{
+	GdkColor color;
+	gint ttime_x1, ttime_y1, ttime_x2, ttime_y2;
+
+	gnome_canvas_w2c (canvas, start_wx,  start_wy, &ttime_x1, &ttime_y1);
+	gnome_canvas_w2c (canvas,   end_wx,    end_wy, &ttime_x2, &ttime_y2);
+	ttime_x1 -= x;  ttime_y1 -= y;
+	ttime_x2 -= x;  ttime_y2 -= y;
+	
+	if (ttime_x2 > ttime_x1) {
+		gnome_canvas_get_color (canvas, colorname, &color);
+		gdk_gc_set_foreground (gc, &color);
+
+		if (is_up) {
+			draw_cut_rectangle (drawable,
+								gc,
+								TRUE,
+								ttime_x1,
+								ttime_y1,
+								ttime_x2 - ttime_x1,
+								cy1 - ttime_y1);
+			
+			gnome_canvas_get_color (canvas, "gray40", &color);
+			gdk_gc_set_foreground (gc, &color);
+		
+		draw_cut_line (drawable, gc, ttime_x1, ttime_y1,
+					   ttime_x2-1, ttime_y1);
+		draw_cut_line (drawable, gc, ttime_x1, ttime_y1,
+					   ttime_x1, cy1-1);
+		}
+		else {
+			draw_cut_rectangle (drawable,
+								gc,
+								TRUE,
+								ttime_x1, cy2+1,
+								ttime_x2 - ttime_x1,
+								ttime_y2 - cy2 - 1);
+			
+			gnome_canvas_get_color (canvas, "gray40", &color);
+			gdk_gc_set_foreground (gc, &color);
+			
+			draw_cut_line (drawable, gc, ttime_x1, ttime_y2,
+						   ttime_x2-1, ttime_y2);
+			draw_cut_line (drawable, gc, ttime_x1, cy2+1,
+						   ttime_x1, ttime_y2);
+		}
+		
+		return (TRUE);
+	}
+	else {
+		return (FALSE);
+	}
+}
+	
 static void
 gantt_row_draw (GnomeCanvasItem *item,
 		GdkDrawable     *drawable,
@@ -881,7 +1157,7 @@
 	PlannerGanttChart   *chart;
 	gdouble              i2w_dx; 
 	gdouble              i2w_dy;
-	gdouble              dx1, dy1, dx2, dy2;
+	gdouble              dx1, dy1, dx2, dy2, dshay1, dshay2;
 	gint                 level;
 	MrpTaskType          type;
 	gboolean             summary;
@@ -890,32 +1166,98 @@
 	gint                 percent_complete;
 	gint                 complete_x2, complete_width;
 	gboolean             highlight_critical;
+	gboolean             display_nonstandard_days;
 	gboolean             critical;
-
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+	gboolean             is_dominant;
+#endif
 	gint                 rx1, ry1;
 	gint                 rx2, ry2;
 	gint                 cx1, cy1, cx2, cy2; 
-	
+
+	GList               *unit_ivals, *cal_ivals, *cur_unit, *cur_cal;
+	GdkColor             color;
+	gint                 x_start, x_end, y_dumb, is_a_gap, is_a_subgap;
+	MrpUnitsInterval    *unit_ival, ival_buf;
+        MrpInterval         *ival_subbuf = NULL, *cal_ival;
+	gint                 i, day_cur, cur_start, cur_end;
+
+	MrpProject          *project;
+	MrpDay              *day;
+	MrpCalendar         *calendar;
+	mrptime              cal_start, cal_end; 
+	gboolean             is_before_work;
+	gboolean             shadup_is_cached, shadup_draw_it;
+	gboolean             shaddo_is_cached, shaddo_draw_it;
+	gint                 shadup_start, shadup_end;
+	gint                 shaddo_start, shaddo_end;
+
+	gboolean             workup_is_cached, workup_draw_it;
+	gboolean             workdo_is_cached, workdo_draw_it;
+	gint                 workup_start, workup_end;
+	gint                 workdo_start, workdo_end;
+
+	gboolean             wunits_is_first, wunits_is_cached, wunits_draw_it;
+	gint                 wunits_x_start;
+
+	gint                 last_end;
+
+	gint                 topy,  nres, finish;
+	gdouble              delta;
+	GList               *assignments;
+
+	shadup_start = -1;
+	shadup_end = -1;
+	shaddo_start = -1;
+	shaddo_end = -1;
+	workup_start = -1;
+	workup_end = -1;
+	workdo_start = -1;
+	workdo_end = -1;
+	wunits_is_first = FALSE;
+	wunits_is_cached = FALSE;
+	wunits_x_start = -1;
+	last_end = 0;
+	delta = -1.0;
+
 	row = PLANNER_GANTT_ROW (item);
 	priv = row->priv;
+	project = mrp_object_get_project (MRP_OBJECT (priv->task));
+	calendar = mrp_project_get_calendar (project);
+
 
 	chart = g_object_get_data (G_OBJECT (item->canvas), "chart");
 	highlight_critical = planner_gantt_chart_get_highlight_critical_tasks (chart);
-
+	display_nonstandard_days = planner_gantt_chart_get_nonstandard_days (chart);
 	level = planner_scale_clamp_zoom (priv->zoom);
 
+
+	/*
+	  NOTES
+	  
+	  w -> world
+	  i -> item
+	  c -> canvas 
+	  
+	  priv->x = t * scale
+	*/
+	
 	/* Get item area in canvas coordinates. */
 	i2w_dx = 0.0;
 	i2w_dy = 0.0;
+
 	gnome_canvas_item_i2w (item, &i2w_dx, &i2w_dy);
 
-	dx1 = priv->x;
-	dy1 = priv->y + 0.15 * priv->height;
+	dx1 = priv->x;	
+	
+	dy1 = priv->y + priv->bar_top;
 	dx2 = priv->x + priv->width;
-	dy2 = priv->y + 0.70 * priv->height;
+	dy2 = priv->y + priv->bar_bot;
 
 	dx2 = MAX (dx2, dx1 + MIN_WIDTH);
 	
+	dshay1 = priv->y + 0.08 * priv->height;
+	dshay2 = priv->y + 0.92 * priv->height;
 	gnome_canvas_w2c (item->canvas,
 			  dx1 + i2w_dx,
 			  dy1 + i2w_dy,
@@ -932,12 +1274,12 @@
 	cy1 -= y;
 	cx2 -= x;
 	cy2 -= y;
-
+	
 	if (cy1 >= cy2 || cx1 >= cx2) {
 		return;
 	}
 
-	summary_y = floor (priv->y + 2 * 0.15 * priv->height + 0.5) - y;
+	summary_y = floor (priv->y + 2 * priv->bar_top + 0.5) - y;
 
 	/* "Clip" the expose area. */
 	rx1 = MAX (cx1, 0);
@@ -953,7 +1295,12 @@
 	percent_complete = mrp_task_get_percent_complete (priv->task);
 	critical = mrp_task_get_critical (priv->task);
 	type = mrp_task_get_task_type (priv->task);
-	
+	finish = mrp_task_get_finish (priv->task);
+	nres = mrp_task_get_nres (priv->task);
+	assignments = mrp_task_get_assignments (priv->task);
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+	is_dominant = mrp_task_is_dominant (priv->task);
+#endif
 	if (!summary) {
 		complete_width = floor ((cx2 - cx1) * (percent_complete / 100.0) + 0.5);
 		complete_x2 = MIN (cx1 + complete_width, rx2);
@@ -967,22 +1314,442 @@
 							 priv->complete_gc);
 		}
 
+		if (assignments) {
+			/* #define DRAW_BACKGROUND_CHECK 1 */
+#ifdef DRAW_BACKGROUND_CHECK
+			gnome_canvas_get_color (item->canvas, "indian red", &color);
+			gdk_gc_set_foreground (priv->fill_gc, &color);
+			draw_cut_rectangle (drawable,
+								priv->fill_gc,
+								TRUE,
+								rx1,
+								cy1,
+								rx2 - rx1,
+								cy2 - cy1);
+#endif
+			
+			/* Start slices drawer */
+			unit_ivals = mrp_task_get_unit_ivals (priv->task);
+			ival_subbuf = mrp_interval_new (0,0);
+			
+			is_before_work = TRUE;
+			shadup_is_cached = FALSE;
+			shaddo_is_cached = FALSE;
+			workup_is_cached = FALSE;
+			workdo_is_cached = FALSE;
+			for (i = 0, unit_ival = mop_get_next_ival (&cur_unit, &is_a_gap, 
+								  unit_ivals, &ival_buf)
+					 ; unit_ival && (i == 0 || cur_start < finish) ; i++) {
+				if (i == 0) {
+					/* first iteration: read the day when start the task */
+					day_cur = mrp_time_align_day (unit_ival->start);
+					
+					/* extract the intervals of the day */
+					day = mrp_calendar_get_day (calendar, day_cur, TRUE);
+					cal_ivals = mrp_calendar_day_get_intervals (calendar, day, TRUE);
+					
+					if (cal_ivals == NULL) {
+						mrp_interval_set_absolute (ival_subbuf, 0, 0, (24*60*60));
+						is_a_subgap = 1;
+						cal_ival = ival_subbuf;
+					}
+					else {
+						for (cal_ival = mop_get_next_mrp_ival (&cur_cal, &is_a_subgap, 
+										       cal_ivals, ival_subbuf) ;
+						   cal_ival ;
+						   cal_ival = mop_get_next_mrp_ival (&cur_cal, &is_a_subgap, 
+											NULL, ival_subbuf)) {
+							mrp_interval_get_absolute (cal_ival, day_cur, &cal_start, &cal_end);
+						
+							if (cal_end > unit_ival->start) {
+								break;
+							}
+						}
+					}
+					cur_start = MAX (unit_ival->start, cal_start);
+					cur_end   = MIN (unit_ival->end  , cal_end  );
+					wunits_is_first = TRUE;
+				}
+				g_assert (cal_ival != NULL);
+			
+				gnome_canvas_w2c (item->canvas, (cur_start * priv->scale)
+								  + i2w_dx, i2w_dy, &x_start, &y_dumb);
+				gnome_canvas_w2c (item->canvas, (cur_end * priv->scale)
+								  + i2w_dx, i2w_dy, &x_end, &y_dumb);
+				x_start -= x;
+				x_end   -= x;
+			
+				if (is_before_work) {
+					if (unit_ival->units_full == 0) {
+						goto cont_shadowloop;
+					}
+					else {
+						is_before_work = FALSE;
+					}
+					
+				}
+				if (display_nonstandard_days) {
+					shadup_draw_it = FALSE;
+					shaddo_draw_it = FALSE;
+					workup_draw_it = FALSE;
+					workdo_draw_it = FALSE;
+					
+					if (unit_ival->res_n == 0 && (!is_a_subgap || 
+								  (is_a_subgap && planner_scale_conf[level].nonworking_limit 
+								   > cal_end - cal_start))) {
+						if (shadup_is_cached == FALSE) {
+							shadup_start = cur_start;
+							shadup_is_cached = TRUE;
+						}
+					}
+					else {
+						if (shadup_is_cached == TRUE) {
+							if (planner_scale_conf[level].nonworking_limit <= 
+								cur_start - shadup_start) {
+								shadup_end = cur_start;
+								shadup_draw_it = TRUE;
+							}
+							shadup_is_cached = FALSE;
+						}
+					}
+					
+					if (unit_ival->res_n < nres && (!is_a_subgap || 
+									(is_a_subgap && planner_scale_conf[level].nonworking_limit 
+									 > cal_end - cal_start))) {
+						
+						if (shaddo_is_cached == FALSE) {
+							shaddo_start = cur_start;
+							shaddo_is_cached = TRUE;
+						}
+					}
+					else {
+						if (shaddo_is_cached == TRUE) {
+							if (planner_scale_conf[level].nonworking_limit <= 
+								cur_start - shaddo_start) {
+								shaddo_end = cur_start;
+								shaddo_draw_it = TRUE;
+							}
+							shaddo_is_cached = FALSE;
+						}
+					}
+					
+					if ((unit_ival->res_n == nres && is_a_subgap) ||
+						(unit_ival->res_n == 0 && 
+						 (cal_start % (24*60*60) == 0) && (cal_end % (24*60*60) == 0) &&
+						 planner_scale_conf[level].nonworking_limit > cur_end - cur_start)) {
+						if (workup_is_cached == FALSE) {
+							workup_start = cur_start;
+							workup_is_cached = TRUE;
+						}
+					}
+					else {
+						if (workup_is_cached == TRUE) {
+							if (planner_scale_conf[level].nonworking_limit <= 
+								cur_start - workup_start) {
+								workup_end = cur_start;
+								workup_draw_it = TRUE;
+							}
+							workup_is_cached = FALSE;
+						}
+					}
+					
+					if ((unit_ival->res_n > 0 && is_a_subgap) ||
+						(unit_ival->res_n == 0 && 
+						 (cal_start % (24*60*60) == 0) && (cal_end % (24*60*60) == 0) &&
+						 planner_scale_conf[level].nonworking_limit > cur_end - cur_start)) {
+						
+						if (workdo_is_cached == FALSE) {
+							workdo_start = cur_start;
+							workdo_is_cached = TRUE;
+						}
+					}
+					else {
+						if (workdo_is_cached == TRUE) {
+							if (planner_scale_conf[level].nonworking_limit <= 
+								cur_start - workdo_start) {
+								workdo_end = cur_start;
+								workdo_draw_it = TRUE;
+							}
+							workdo_is_cached = FALSE;
+						}
+					}
+					
+					/* Show shadow up. */
+					if (shadup_draw_it ||
+						(shadup_is_cached && 
+						 ((cur_end % (24*60*60)) == 0))) {
+						if (!shadup_draw_it && ((cur_end % (24*60*60)) == 0)) {
+							shadup_end = cur_end;
+						}
+						if (planner_scale_conf[level].nonworking_limit <= 
+							shadup_end - shadup_start) {
+							
+							gantt_draw_tasktime (drawable, priv->ttask_gc, item->canvas,
+										(shadup_start * priv->scale) + i2w_dx,
+										dshay1 + i2w_dy,
+										(shadup_end * priv->scale) + i2w_dx,
+										dshay2 + i2w_dy,
+										cy1, cy2, x, y,  TRUE, "grey96");
+						}
+						shadup_draw_it = FALSE;
+						shadup_is_cached = FALSE;
+					}
+					
+					/* Show shadow down. */
+					if (shaddo_draw_it ||
+						(shaddo_is_cached && 
+						 ((cur_end % (24*60*60)) == 0))) {
+						if (!shaddo_draw_it && ((cur_end % (24*60*60)) == 0)) {
+							shaddo_end = cur_end;
+						}
+						if (planner_scale_conf[level].nonworking_limit <= 
+							shaddo_end - shaddo_start) {
+							
+							gantt_draw_tasktime (drawable, priv->ttask_gc, item->canvas,
+									     (shaddo_start * priv->scale) + i2w_dx,
+									     dshay1 + i2w_dy,
+									     (shaddo_end * priv->scale) + i2w_dx,
+									     dshay2 + i2w_dy,
+									     cy1, cy2, x, y,  FALSE, "grey96");
+						}
+						shaddo_draw_it = FALSE;
+						shaddo_is_cached = FALSE;
+					}
+					
+					/* Show work up. */
+					if (workup_draw_it ||
+						(workup_is_cached && 
+						 ((cur_end % (24*60*60)) == 0))) {
+						if (!workup_draw_it && ((cur_end % (24*60*60)) == 0)) {
+							workup_end = cur_end;
+						}
+						if (planner_scale_conf[level].nonworking_limit <= 
+							workup_end - workup_start) {
+							
+							gantt_draw_tasktime (drawable, priv->ttask_gc, item->canvas,
+									     (workup_start * priv->scale) + i2w_dx,
+									     dshay1 + i2w_dy,
+									     (workup_end * priv->scale) + i2w_dx,
+									     dshay2 + i2w_dy,
+									     cy1, cy2, x, y,  TRUE, "white");
+						}
+						workup_draw_it = FALSE;
+						workup_is_cached = FALSE;
+					}
+				
+					/* Show work down. */
+					if (workdo_draw_it ||
+						(workdo_is_cached && 
+						 ((cur_end % (24*60*60)) == 0))) {
+						if (!workdo_draw_it && ((cur_end % (24*60*60)) == 0)) {
+							workdo_end = cur_end;
+						}
+						if (planner_scale_conf[level].nonworking_limit <= 
+							workdo_end - workdo_start) {
+
+							gantt_draw_tasktime (drawable, priv->ttask_gc, item->canvas,
+									     (workdo_start * priv->scale) + i2w_dx,
+									     dshay1 + i2w_dy,
+									     (workdo_end * priv->scale) + i2w_dx,
+									     dshay2 + i2w_dy,
+									     cy1, cy2, x, y,  FALSE, "white");
+
+							workdo_draw_it = FALSE;
+							workdo_is_cached = FALSE;
+						}
+					}
+				}
+				/* Draw area. */
+				wunits_draw_it = TRUE;
+				if (unit_ival->res_n > 0 && unit_ival->units_full > 0) {
+					delta = (double)unit_ival->units / (double)unit_ival->units_full;
+				}
+				else {
+					if (unit_ival->res_n == 0) {  /* It is a nonworking interval. */
+						if (planner_scale_conf[level].nonworking_limit <= 
+						    cur_end - cur_start) {  
+							delta = 1.0;
+						}   /* else it use the last selected value */
+					}
+					/* It isn't a nonworking interval. */
+					else if (planner_scale_conf[level].nonworking_limit <= 
+						cur_end - cur_start) { /* Visible non working interval. */		
+						delta = 1.0;
+					}
+					else {  /* use the last selected value */
+						if (wunits_is_first == TRUE) {
+							wunits_is_cached = TRUE;
+							wunits_x_start = x_start;
+							wunits_draw_it = FALSE;
+						} 
+					}
+				}
+				
+				topy = floor ((cy1 + ((1.0 - (double)delta) * (double)(cy2 - cy1 - 3))) + 0.5);
+				if (!highlight_critical || !critical) {
+					gdk_gc_set_foreground (priv->fill_gc, &priv->color_normal);
+				} else {
+					gdk_gc_set_foreground (priv->fill_gc, &priv->color_critical);
+				}
+			
+				if (wunits_draw_it) {
+					if (wunits_is_cached) {
+						wunits_is_cached = FALSE;
+					}
+					else {
+						wunits_x_start = x_start;
+					}
+				
+					if ((cy2 - topy - 3) > 0) {
+						draw_cut_rectangle (drawable,
+							            	priv->fill_gc,
+									TRUE,
+									wunits_x_start,
+									topy + 2,
+									x_end - wunits_x_start,
+									cy2 - topy - 3);
+					}
+					if (topy  - cy1 > 0) {
+						gnome_canvas_get_color (item->canvas, "white", &color);
+						gdk_gc_set_foreground (priv->fill_gc, &color);
+						draw_cut_rectangle (drawable,
+									priv->fill_gc,
+									TRUE,
+									wunits_x_start,
+									cy1+2,
+									x_end - wunits_x_start,
+									topy - cy1);
+					}
+				}
+			
+			cont_shadowloop:
+				if (display_nonstandard_days) {
+					last_end = cur_end;
+				}
+				wunits_is_first = FALSE;
+			
+				if (cur_end == unit_ival->end) {
+					if ((unit_ival = mop_get_next_ival (&cur_unit, &is_a_gap, 
+									    NULL, &ival_buf)) == NULL) {
+						break;	
+					}
+				}
+				if (cur_end == cal_end) {
+					if ((cal_ival = mop_get_next_mrp_ival (&cur_cal, &is_a_subgap, 
+									       NULL, ival_subbuf)) == NULL) {
+						/* End of the day intervals, read next. */
+						day_cur += (24*60*60);
+						day = mrp_calendar_get_day (calendar, day_cur, TRUE);
+						cal_ivals = mrp_calendar_day_get_intervals (calendar, day, TRUE);
+						if (cal_ivals) {
+							/* Not empty day. */
+							cal_ival = mop_get_next_mrp_ival (&cur_cal, &is_a_subgap, 
+											  cal_ivals, ival_subbuf);
+						}
+						else {
+							/* Empty day. */
+							mrp_interval_set_absolute (ival_subbuf, 0, 0, (24*60*60));
+							is_a_subgap = 1;
+							cal_ival = ival_subbuf;
+						}
+						wunits_is_first = TRUE;
+					}
+					mrp_interval_get_absolute (cal_ival, day_cur, &cal_start, &cal_end);
+				}
+
+				cur_start = MAX (unit_ival->start, cal_start);
+				cur_end   = MIN (unit_ival->end  , cal_end  );
+			}
+
+			if (display_nonstandard_days) {
+				/*
+				  H O L Y D A Y S
+				*/ 
+
+				/* Show shad up. */
+				if (shadup_is_cached) {
+					shadup_end = last_end;
+			
+					gantt_draw_tasktime (drawable, priv->ttask_gc, item->canvas,
+								(shadup_start * priv->scale) + i2w_dx,
+								dshay1 + i2w_dy,
+								(shadup_end * priv->scale) + i2w_dx,
+								dshay2 + i2w_dy,
+								cy1, cy2, x, y,  TRUE, "grey96");
+				}
+
+				/* Show shad down. */
+				if (shaddo_is_cached) {
+					shaddo_end = last_end;
+
+					gantt_draw_tasktime (drawable, priv->ttask_gc, item->canvas,
+								(shaddo_start * priv->scale) + i2w_dx,
+								dshay1 + i2w_dy,
+								(shaddo_end * priv->scale) + i2w_dx,
+								dshay2 + i2w_dy,
+								cy1, cy2, x, y,  FALSE, "grey96");
+				}
+
+				/*
+				  W O R K 
+				*/  
+
+				/* Show work up. */
+				if (workup_is_cached) {
+					workup_end = last_end;
+			
+					gantt_draw_tasktime (drawable, priv->ttask_gc, item->canvas,
+								(workup_start * priv->scale) + i2w_dx,
+								dshay1 + i2w_dy,
+								(workup_end * priv->scale) + i2w_dx,
+								dshay2 + i2w_dy,
+								cy1, cy2, x, y,	 TRUE, "white");
+				}
+
+				/* Show work down. */
+				if (workdo_is_cached) {
+					workdo_end = last_end;
+
+					gantt_draw_tasktime (drawable, priv->ttask_gc, item->canvas,
+								(workdo_start * priv->scale) + i2w_dx,
+								dshay1 + i2w_dy,
+								(workdo_end * priv->scale) + i2w_dx,
+								dshay2 + i2w_dy,
+								cy1, cy2, x, y,  FALSE, "white");
+				}
+			}
+		}
+		else { /* if (assignments) ... */
+			if (!highlight_critical || !critical) {
+				gdk_gc_set_foreground (priv->fill_gc, &priv->color_normal);
+			} else {
+				gdk_gc_set_foreground (priv->fill_gc, &priv->color_critical);
+			}
+			draw_cut_rectangle (drawable,
+						priv->fill_gc,
+						TRUE,
+						rx1,
+						cy1,
+						rx2 - rx1,
+						cy2 - cy1);
+		}
+
+
+		gnome_canvas_get_color (item->canvas, "black", &color);
+		gdk_gc_set_foreground (priv->frame_gc, &color);
+		
+		if (ival_subbuf) {
+			mrp_interval_unref (ival_subbuf);
+		}
+
 		if (!highlight_critical || !critical) {
 			gdk_gc_set_foreground (priv->fill_gc, &priv->color_normal);
 		} else {
 			gdk_gc_set_foreground (priv->fill_gc, &priv->color_critical);
 		}
-		
-		gdk_draw_rectangle (drawable,
-				    priv->fill_gc,
-				    TRUE,
-				    rx1,
-				    cy1 + 1,
-				    rx2 - rx1,
-				    cy2 - cy1 - 1);
-		
+
 		if (rx1 <= complete_x2) {
-			gdk_draw_rectangle (drawable,
+			draw_cut_rectangle (drawable,
 					    priv->complete_gc,
 					    TRUE,
 					    rx1,
@@ -991,8 +1758,31 @@
 					    cy2 - cy1 - 7);
 		}
 
-		gdk_draw_line (drawable, priv->frame_gc, rx1, cy1, rx2, cy1);
-		gdk_draw_line (drawable, priv->frame_gc, rx1, cy2, rx2, cy2);
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+ 		for (i = 0 ; i < (is_dominant && !(!summary && priv->highlight) ? 2 : 1) ; ++i) {
+ 			if (i == 1) {
+ 				gnome_canvas_get_color (item->canvas, "indian red", &color);
+ 				gdk_gc_set_foreground (priv->frame_gc, &color);
+ 				
+ 				gdk_gc_set_line_attributes (priv->frame_gc,
+ 								0,
+ 								GDK_LINE_ON_OFF_DASH,
+ 								GDK_CAP_BUTT,
+ 								GDK_JOIN_MITER);
+ 				draw_cut_line (drawable, priv->frame_gc, cx1, cy1, cx2, cy1);
+ 				draw_cut_line (drawable, priv->frame_gc, cx1, cy2, cx2, cy2);
+ 				gantt_row_setup_frame_gc (row, !summary && priv->highlight);
+ 				gnome_canvas_get_color (item->canvas, "black", &color);
+ 				gdk_gc_set_foreground (priv->frame_gc, &color);
+ 			}
+ 			else {
+#endif
+ 				draw_cut_line (drawable, priv->frame_gc, rx1, cy1, rx2, cy1);
+ 				draw_cut_line (drawable, priv->frame_gc, rx1, cy2, rx2, cy2);
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+ 			}
+ 		}
+#endif
 
 		if (!highlight_critical || !critical) {
 			gdk_gc_set_foreground (priv->fill_gc, &priv->color_normal_light);
@@ -1000,7 +1790,7 @@
 			gdk_gc_set_foreground (priv->fill_gc, &priv->color_critical_light);
 		}
 
-		gdk_draw_line (drawable,
+		draw_cut_line (drawable,
 			       priv->fill_gc,
 			       rx1 + 0,
 			       cy1 + 1,
@@ -1008,7 +1798,7 @@
 			       cy1 + 1);
 
 		if (cx1 == rx1) {
-			gdk_draw_line (drawable,
+			draw_cut_line (drawable,
 				       priv->fill_gc,
 				       rx1 + 1,
 				       cy1 + 1,
@@ -1022,7 +1812,7 @@
 			gdk_gc_set_foreground (priv->fill_gc, &priv->color_critical_dark);
 		}
 
-		gdk_draw_line (drawable,
+		draw_cut_line (drawable,
 			       priv->fill_gc,
 			       rx1 + 0,
 			       cy2 - 1,
@@ -1030,33 +1820,43 @@
 			       cy2 - 1);
 		
 		if (cx2 == rx2) {
-			gdk_draw_line (drawable,
+			draw_cut_line (drawable,
 				       priv->fill_gc,
 				       rx2 - 1,
 				       cy1 + 1,
 				       rx2 - 1,
 				       cy2 - 1);
 		}
-
-		/* FIXME: Drawing of shadows on non-working time should go here. */
-		
-		if (cx1 == rx1) {
-			gdk_draw_line (drawable,
-				       priv->frame_gc,
-				       rx1,
-				       cy1,
-				       rx1,
-				       cy2);
-		}
-		
-		if (cx2 == rx2) {
-			gdk_draw_line (drawable,
-				       priv->frame_gc,
-				       rx2,
-				       cy1,
-				       rx2,
-				       cy2);
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+		for (i = 0 ; i < (is_dominant && !(!summary && priv->highlight) ? 2 : 1) ; ++i) {
+			if (i == 1) {
+				gnome_canvas_get_color (item->canvas, "red", &color);
+				gdk_gc_set_foreground (priv->frame_gc, &color);
+				
+				gdk_gc_set_line_attributes (priv->frame_gc,
+								0,
+								GDK_LINE_ON_OFF_DASH,
+								GDK_CAP_BUTT,
+								GDK_JOIN_MITER);
+			}
+#endif			
+			if (cx1 == rx1) {
+				draw_cut_line (drawable, priv->frame_gc,
+						cx1, cy1, cx1, cy2);
+			}
+			if (cx2 == rx2) {
+				draw_cut_line (drawable, priv->frame_gc,
+						cx2, cy1, cx2, cy2);
+			}
+			
+#ifdef WITH_SIMPLE_PRIORITY_SCHEDULING
+			if (i == 1) {
+				gantt_row_setup_frame_gc (row, !summary && priv->highlight);
+				gnome_canvas_get_color (item->canvas, "black", &color);
+				gdk_gc_set_foreground (priv->frame_gc, &color);
+			}
 		}
+#endif
 	}
 	else if (type == MRP_TASK_TYPE_MILESTONE && !summary && rx1 <= rx2) {
 		points[0].x = cx1;
@@ -1081,7 +1881,7 @@
 		/* FIXME: Maybe we should try and make the summary be thicker
 		 * for larger heights and always centered vertically?
 		 */
-		gdk_draw_rectangle (drawable,
+		draw_cut_rectangle (drawable,
 				    priv->frame_gc,
 				    TRUE,
 				    rx1,
@@ -1137,11 +1937,14 @@
 	rx2 = MIN (cx2 + TEXT_PADDING + priv->text_width, width);
 
 	if (priv->layout != NULL && rx1 < rx2) {
-		/* FIXME: Center the text vertically? */
-		gdk_draw_layout (drawable,
+		/* NOTE: cy1 - priv->bar_top: report to the top of the cell,
+		         + 3: is an empirical value to realign with task-tree result of the
+		         default gtkcellrenderertext ypad property (2) + 1 ??? ;). */
+		   
+		draw_cut_layout (drawable,
 				 GTK_WIDGET (item->canvas)->style->text_gc[GTK_STATE_NORMAL],
 				 cx2 + TEXT_PADDING,
-				 cy1,
+				 cy1 - priv->bar_top + 3, 
 				 priv->layout);
 
 		if (priv->mouse_over_index != -1) {
@@ -1157,7 +1960,7 @@
 			x1 += cx2 + TEXT_PADDING;
 			x2 += cx2 + TEXT_PADDING;
 				
-			gdk_draw_line (drawable,
+			draw_cut_line (drawable,
 				       GTK_WIDGET (item->canvas)->style->text_gc[GTK_STATE_NORMAL],
 				       x1,
 				       cy2 + 2,
@@ -1250,7 +2053,8 @@
 	 * it since it's a good optimization.
 	 */
 	else if (strcmp (pspec->name, "critical") != 0 &&
-		 strcmp (pspec->name, "percent-complete")) {
+			 strcmp (pspec->name, "priority") != 0 &&
+			 strcmp (pspec->name, "percent-complete")) {
 		return;
 	}
 	
@@ -1361,10 +2165,12 @@
 		*x2 = priv->x + priv->width;
 	}
 	if (y1) {
-		*y1 = priv->y + 0.15 * priv->height;
+		/* preMOP *y1 = priv->y + 0.15 * priv->height; */
+		*y1 = priv->y;
 	}
 	if (y2) {
-		*y2 = priv->y + 0.70 * priv->height;
+		/* preMOP *y2 = priv->y + 0.70 * priv->height; */
+		*y2 = priv->y + priv->height;
 	}
 }
 
@@ -1492,13 +2298,13 @@
 	return TRUE;
 }
 
-#define IN_DRAG_DURATION_SPOT(x,y,right,top,height) \
-	((abs(x - (right)) <= 3) && \
-	(y > top + 0.15 * height) && (y < top + 0.70 * height))
+#define IN_DRAG_DURATION_SPOT(x,y,right,top,ymin,ymax)	\
+	((abs (x - (right)) <= 3) && \
+	 (y > top + ymin) && (y < top + ymax))
 
-#define IN_DRAG_RELATION_SPOT(x,y,right,top,height) \
+#define IN_DRAG_RELATION_SPOT(x,y,right,top,ymin,ymax)	\
 	((x <= right) && \
-	(y > top + 0.15 * height) && (y < top + 0.70 * height))
+	 (y > top + ymin) && (y < top + ymax))
 
 static gboolean
 gantt_row_event (GnomeCanvasItem *item, GdkEvent *event)
@@ -1533,7 +2339,8 @@
 		switch (event->button.button) {
 		case 3:
 			if (IN_DRAG_RELATION_SPOT (event->button.x, event->button.y,
-						   priv->x + priv->width, priv->y, priv->height)) {
+						   priv->x + priv->width, priv->y, 
+						   priv->bar_top, priv->bar_bot)) {
 				PlannerGanttChart *chart;
 				PlannerTaskTree   *tree;
 				GtkTreePath       *path;
@@ -1586,15 +2393,16 @@
 							       event->button.y,
 							       priv->x + priv->width,
 							       priv->y,
-							       priv->height)) {
+							       priv->bar_top, 
+							       priv->bar_bot)) {
 				guint rgba;
 				
 				priv->state = STATE_DRAG_DURATION;
 
 				wx1 = priv->x;
-				wy1 = priv->y + 0.15 * priv->height;
+				wy1 = priv->y + priv->bar_top;
 				wx2 = event->button.x;
-				wy2 = priv->y + 0.70 * priv->height;
+				wy2 = priv->y + priv->bar_bot;
 
 				gnome_canvas_item_i2w (item, &wx1, &wy1);
 				gnome_canvas_item_i2w (item, &wx2, &wy2);
@@ -1619,9 +2427,9 @@
 							  event->button.y,
 							  priv->x + priv->width,
 							  priv->y,
-							  priv->height)) {
+							  priv->bar_top, 
+							  priv->bar_bot)) {
 				priv->state = STATE_DRAG_LINK;
-				
 				if (drag_points == NULL) {
 					drag_points = gnome_canvas_points_new (2);
 				}
@@ -1721,7 +2529,8 @@
 							       event->button.y,
 							       priv->x + priv->width,
 							       priv->y,
-							       priv->height)) {
+							       priv->bar_top, 
+							       priv->bar_bot)) {
 				cursor = gdk_cursor_new (GDK_RIGHT_SIDE);
 				gdk_window_set_cursor (canvas_widget->window, cursor);
 				if (cursor) {
@@ -1817,7 +2626,7 @@
 			project = mrp_object_get_project (MRP_OBJECT (priv->task));
 
 			wx2 = event->motion.x;
-			wy2 = priv->y + 0.70 * priv->height;
+			wy2 = priv->y + priv->bar_bot;
 			
 			gnome_canvas_item_i2w (item, &wx2, &wy2);
 
@@ -2020,7 +2829,8 @@
 	case GDK_2BUTTON_PRESS:
 		if (event->button.button == 1) {
 			if (IN_DRAG_RELATION_SPOT (event->button.x, event->button.y,
-						   priv->x + priv->width, priv->y, priv->height)) {
+						   priv->x + priv->width, priv->y, 
+						   priv->bar_top, priv->bar_bot)) {
 				PlannerTaskTree  *tree;
 				GtkTreePath      *path;
 				GtkTreeSelection *selection;
@@ -2255,7 +3065,7 @@
 					tx2 = MIN (tx2, rx2);
 
 					if (tx1 < tx2) {
-						gdk_draw_rectangle (drawable,
+						draw_cut_rectangle (drawable,
 								    priv->fill_gc,
 								    TRUE,
 								    tx1,
@@ -2265,14 +3075,14 @@
 					}
 					
 					/*gdk_gc_set_foreground (priv->fill_gc, &color_high);
-					gdk_draw_line (drawable,
+					draw_cut_line (drawable,
 						       priv->fill_gc,
 						       tx1,
 						       cy1 + 1,
 						       tx1,
 						       cy2 - 1);
 					
-					gdk_draw_line (drawable,
+					draw_cut_line (drawable,
 						       priv->fill_gc,
 						       tx2 - 1,
 						       cy1 + 1,
@@ -2312,7 +3122,7 @@
 				tx2 = MIN (tx2, rx2);
 
 				if (tx1 < tx2) {
-					gdk_draw_rectangle (drawable,
+					draw_cut_rectangle (drawable,
 							    priv->fill_gc,
 							    TRUE,
 							    tx1,


--- orig/src/planner-gantt-view.c
+++ mod/src/planner-gantt-view.c
@@ -84,6 +84,8 @@
 							   gpointer           data);
 static void          gantt_view_highlight_critical_cb     (GtkAction         *action,
 							   gpointer           data);
+static void          gantt_view_nonstandard_days_cb       (GtkAction         *action,
+							   gpointer           data);
 static void          gantt_view_edit_columns_cb           (GtkAction         *action,
 							   gpointer           data);
 static void          gantt_view_update_row_height         (PlannerGanttView  *view);
@@ -175,10 +177,14 @@
 static const GtkToggleActionEntry toggle_entries[] = {
 	{ "HighlightCriticalTasks", NULL, N_("_Highlight Critical Tasks"),
 	  NULL, NULL,
-	  G_CALLBACK (gantt_view_highlight_critical_cb), FALSE }
+	  G_CALLBACK (gantt_view_highlight_critical_cb), FALSE },
+	{ "NonstandardDays", NULL, N_("_Nonstandard Days"),
+	  NULL, NULL,
+	  G_CALLBACK (gantt_view_nonstandard_days_cb), FALSE }
 };
 
 
+
 G_DEFINE_TYPE (PlannerGanttView, planner_gantt_view, PLANNER_TYPE_VIEW);
 
 
@@ -213,7 +219,7 @@
 gantt_view_activate (PlannerView *view)
 {
 	PlannerGanttViewPriv *priv;
-	gboolean              show_critical;
+	gboolean              show_critical, show_nostd_days;
 	gchar                *filename;
 
 	priv = PLANNER_GANTT_VIEW (view)->priv;
@@ -242,13 +248,23 @@
 	show_critical = planner_gantt_chart_get_highlight_critical_tasks (
 		PLANNER_GANTT_CHART (priv->gantt));
 	
+	show_nostd_days = planner_gantt_chart_get_nonstandard_days (
+		PLANNER_GANTT_CHART (priv->gantt));
+
 	planner_task_tree_set_highlight_critical (PLANNER_TASK_TREE (priv->tree),
 						  show_critical);
 
+	planner_task_tree_set_nonstandard_days (PLANNER_TASK_TREE (priv->tree),
+						  show_nostd_days);
+
 	gtk_toggle_action_set_active (
 		GTK_TOGGLE_ACTION (gtk_action_group_get_action (priv->actions, "HighlightCriticalTasks")),
 		show_critical);
 
+	gtk_toggle_action_set_active (
+		GTK_TOGGLE_ACTION (gtk_action_group_get_action (priv->actions, "NonstandardDays")),
+		show_nostd_days);
+
 	gantt_view_selection_changed_cb (PLANNER_TASK_TREE (priv->tree),
 					 PLANNER_GANTT_VIEW (view));
 	gantt_view_update_zoom_sensitivity (PLANNER_GANTT_VIEW (view));
@@ -816,7 +832,7 @@
 	view = PLANNER_GANTT_VIEW (data);
 	priv = view->priv;
 
-	state = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(action));
+	state = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
 
 	planner_gantt_chart_set_highlight_critical_tasks (
 		PLANNER_GANTT_CHART (priv->gantt),
@@ -828,6 +844,29 @@
 }
 
 static void
+gantt_view_nonstandard_days_cb (GtkAction *action,
+				  gpointer   data)
+{
+	PlannerGanttView     *view;
+	PlannerGanttViewPriv *priv;
+	gboolean         state;
+	
+	view = PLANNER_GANTT_VIEW (data);
+	priv = view->priv;
+
+	state = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+
+	planner_gantt_chart_set_nonstandard_days (
+		PLANNER_GANTT_CHART (priv->gantt),
+		state);
+	planner_task_tree_set_nonstandard_days (
+		PLANNER_TASK_TREE (priv->tree),
+		state);
+	gantt_view_update_row_height (view);
+
+}
+
+static void
 gantt_view_edit_columns_cb (GtkAction *action,
 			    gpointer   data)
 {


--- orig/src/planner-task-tree.c
+++ mod/src/planner-task-tree.c
@@ -60,7 +60,10 @@
 	PlannerWindow  *main_window;
 
 	gboolean        highlight_critical;
-	
+
+	/* Nonstandard days visualization */
+	gboolean        nonstandard_days;
+
 	/* Keep the dialogs here so that we can just raise the dialog if it's
 	 * opened twice for the same task.
 	 */
@@ -95,7 +98,7 @@
 static void        task_tree_setup_tree_view           (GtkTreeView          *tree,
 							MrpProject           *project,
 							PlannerGanttModel    *model);
-static void        task_tree_add_column                (GtkTreeView          *tree,
+static void        task_tree_add_column                (PlannerTaskTree      *tree,
 							gint                  column,
 							const gchar          *title);
 static void        task_tree_name_data_func            (GtkTreeViewColumn    *tree_column,
@@ -515,7 +518,9 @@
 
 	child_parent = planner_gantt_model_get_indent_task_target (model, cmd->task);
 
-	if (cmd->children != NULL) task_cmd_restore_children (cmd);
+	if (cmd->children != NULL) {
+		task_cmd_restore_children (cmd);
+	}
 
 	task_cmd_restore_relations (cmd);
 	task_cmd_restore_assignments (cmd);
@@ -1356,7 +1361,6 @@
 			    iter,
 			    COL_WBS, &str,
 			    -1);
-
 	g_object_set (cell,
 		      "text", str,
 		      NULL);
@@ -2265,7 +2269,7 @@
 }
 
 static void
-task_tree_add_column (GtkTreeView *tree,
+task_tree_add_column (PlannerTaskTree *tree,
 		      gint         column,
 		      const gchar *title)
 {
@@ -2276,13 +2280,14 @@
 	switch (column) {
 	case COL_WBS:
 		cell = gtk_cell_renderer_text_new ();
+		
 		col = gtk_tree_view_column_new_with_attributes (title,
 								cell,
 								NULL);
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_wbs_data_func,
-							 tree, NULL);
+							 GTK_TREE_VIEW (tree), NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_wbs_data_func);
 		g_object_set_data (G_OBJECT (col), "id", "wbs");
@@ -2297,7 +2302,7 @@
 		g_signal_connect (cell,
 				  "edited",
 				  G_CALLBACK (task_tree_name_edited),
-				  tree);
+				  GTK_TREE_VIEW (tree));
 
 		col = gtk_tree_view_column_new_with_attributes (title,
 								cell,
@@ -2305,7 +2310,7 @@
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_name_data_func,
-							 tree, NULL);
+							 GTK_TREE_VIEW (tree), NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_name_data_func);
 		g_object_set_data (G_OBJECT (col), "id", "name");
@@ -2320,11 +2325,11 @@
 		g_signal_connect (cell,
 				  "edited",
 				  G_CALLBACK (task_tree_start_edited),
-				  tree);
+				  GTK_TREE_VIEW (tree));
 		g_signal_connect (cell,
 				  "show-popup",
 				  G_CALLBACK (task_tree_start_show_popup),
-				  tree);
+				  GTK_TREE_VIEW (tree));
 		
 		col = gtk_tree_view_column_new_with_attributes (title,
 								cell,
@@ -2334,7 +2339,7 @@
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_start_data_func,
-							 tree, NULL);
+							 GTK_TREE_VIEW (tree), NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_start_data_func);
 		g_object_set_data (G_OBJECT (col), "id", "start");
@@ -2350,7 +2355,7 @@
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_duration_data_func,
-							 tree,
+							 GTK_TREE_VIEW (tree),
 							 NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_duration_data_func);
@@ -2359,7 +2364,7 @@
 		g_signal_connect (cell,
 				  "edited",
 				  G_CALLBACK (task_tree_duration_edited),
-				  tree);
+				  GTK_TREE_VIEW (tree));
 		break;
 
 	case COL_WORK:
@@ -2372,7 +2377,7 @@
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_work_data_func,
-							 tree,
+							 GTK_TREE_VIEW (tree),
 							 NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_work_data_func);
@@ -2381,7 +2386,7 @@
 		g_signal_connect (cell,
 				  "edited",
 				  G_CALLBACK (task_tree_work_edited),
-				  tree);
+				  GTK_TREE_VIEW (tree));
 		break;
 		
 	case COL_SLACK:
@@ -2394,7 +2399,7 @@
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_slack_data_func,
-							 tree,
+							 GTK_TREE_VIEW (tree),
 							 NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_slack_data_func);
@@ -2406,7 +2411,7 @@
 		g_signal_connect (cell,
 				  "show-popup",
 				  G_CALLBACK (task_tree_start_show_popup),
-				  tree);
+				  GTK_TREE_VIEW (tree));
 		
 		col = gtk_tree_view_column_new_with_attributes (title,
 								cell,
@@ -2416,7 +2421,7 @@
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_finish_data_func,
-							 tree, NULL);
+							 GTK_TREE_VIEW (tree), NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_finish_data_func);
 		g_object_set_data (G_OBJECT (col), "id", "finish");
@@ -2432,7 +2437,7 @@
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_cost_data_func,
-							 tree,
+							 GTK_TREE_VIEW (tree),
 							 NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_cost_data_func);
@@ -2449,7 +2454,7 @@
 		gtk_tree_view_column_set_cell_data_func (col,
 							 cell,
 							 task_tree_assigned_to_data_func,
-							 tree,
+							 GTK_TREE_VIEW (tree),
 							 NULL);
 		g_object_set_data (G_OBJECT (col),
 				   "data-func", task_tree_assigned_to_data_func);
@@ -2462,17 +2467,17 @@
 
 	gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
 	
-	g_object_set_data (G_OBJECT (col), "user-data", tree);
-	gtk_tree_view_append_column (tree, col);
+	g_object_set_data (G_OBJECT (col), "user-data", GTK_TREE_VIEW (tree));
+	gtk_tree_view_append_column (GTK_TREE_VIEW (tree), col);
 
 	if (expander) {
-		gtk_tree_view_set_expander_column (tree, col);
+		gtk_tree_view_set_expander_column (GTK_TREE_VIEW (tree), col);
 	}
 
 	g_signal_connect (col,
 			  "notify::width",
 			  G_CALLBACK (task_tree_column_notify_width_cb),
-			  tree);
+			  GTK_TREE_VIEW (tree));
 }
 
 GtkWidget *
@@ -2511,10 +2516,10 @@
 
 		if (add_newline) {
 			tmp = g_strdup_printf ("\n%s", (gchar *) title);
-			task_tree_add_column (GTK_TREE_VIEW (tree), col, tmp);
+			task_tree_add_column (tree, col, tmp);
 			g_free (tmp);
 		} else {
-			task_tree_add_column (GTK_TREE_VIEW (tree), col, title);
+			task_tree_add_column (tree, col, title);
 		}
 		
 		col = va_arg (args, gint);
@@ -3579,6 +3584,19 @@
 	gtk_widget_queue_draw (GTK_WIDGET (tree));
 }
 
+void
+planner_task_tree_set_nonstandard_days (PlannerTaskTree *tree,
+					  gboolean         nonstandard_days)
+{
+	g_return_if_fail (PLANNER_IS_TASK_TREE (tree));
+
+	if (tree->priv->nonstandard_days == nonstandard_days) {
+		return;
+	}
+	tree->priv->nonstandard_days = nonstandard_days;
+	gtk_widget_queue_draw (GTK_WIDGET (tree));
+}
+
 gboolean
 planner_task_tree_get_highlight_critical (PlannerTaskTree *tree)
 {
@@ -3587,6 +3605,15 @@
 	return tree->priv->highlight_critical;
 }
 
+gboolean
+planner_task_tree_get_nonstandard_days (PlannerTaskTree *tree)
+{
+	g_return_val_if_fail (PLANNER_IS_TASK_TREE (tree), FALSE);
+	
+	return tree->priv->nonstandard_days;
+}
+
+
 void
 planner_task_tree_set_anchor (PlannerTaskTree *tree, GtkTreePath *anchor)
 {


--- orig/src/planner-task-tree.h
+++ mod/src/planner-task-tree.h
@@ -82,6 +82,9 @@
 void         planner_task_tree_set_highlight_critical (PlannerTaskTree       *tree,
 						       gboolean               highlight);
 gboolean     planner_task_tree_get_highlight_critical (PlannerTaskTree       *tree);
+void         planner_task_tree_set_nonstandard_days   (PlannerTaskTree *tree,
+					               gboolean              nonstandard_days);
+gboolean     planner_task_tree_get_nonstandard_days   (PlannerTaskTree *tree);
 void         planner_task_tree_set_anchor             (PlannerTaskTree       *tree,
 						       GtkTreePath           *anchor);
 GtkTreePath* planner_task_tree_get_anchor             (PlannerTaskTree       *tree);


--- orig/src/planner-task-view.c
+++ mod/src/planner-task-view.c
@@ -96,6 +96,8 @@
 							     gpointer         data);
 static void          task_view_highlight_critical_cb        (GtkAction       *action,
 							     gpointer         data);
+static void          task_view_nonstandard_days_cb          (GtkAction       *action,
+							     gpointer         data);
 static void          task_view_edit_columns_cb              (GtkAction       *action,
 							     gpointer         data);
 static void          task_view_selection_changed_cb         (PlannerTaskTree *tree,
@@ -156,10 +158,13 @@
 
 static const GtkToggleActionEntry toggle_entries[] = {
 	{ "HighlightCriticalTasks", NULL, N_("_Highlight Critical Tasks"), NULL, NULL,
-	  G_CALLBACK (task_view_highlight_critical_cb), FALSE }
+	  G_CALLBACK (task_view_highlight_critical_cb), FALSE },
+	{ "NonstandardDays", NULL, N_("_Nonstandard Days"), NULL, NULL,
+	  G_CALLBACK (task_view_nonstandard_days_cb), FALSE }
 };
 
-#define CRITICAL_PATH_KEY "/views/task_view/highlight_critical_path"
+#define CRITICAL_PATH_KEY  "/views/task_view/highlight_critical_path"
+#define NOSTDDAYS_PATH_KEY "/views/task_view/display_nonstandard_days"
 
 G_DEFINE_TYPE (PlannerTaskView, planner_task_view, PLANNER_TYPE_VIEW);
 
@@ -196,7 +201,8 @@
 {
 	PlannerTaskViewPriv *priv;
 	gboolean             show_critical;
-	gchar           *filename;
+	gboolean             show_nostd_days;
+	gchar               *filename;
 
 	priv = PLANNER_TASK_VIEW (view)->priv;
 	
@@ -219,14 +225,20 @@
 	gtk_ui_manager_ensure_update (priv->ui_manager);
 
 	/* Set the initial UI state. */
-	show_critical = planner_conf_get_bool (CRITICAL_PATH_KEY, NULL);
-
+	show_critical =   planner_conf_get_bool (CRITICAL_PATH_KEY, NULL);
+	show_nostd_days = planner_conf_get_bool (NOSTDDAYS_PATH_KEY, NULL);
 	planner_task_tree_set_highlight_critical (PLANNER_TASK_TREE (priv->tree),
 						  show_critical);
+	planner_task_tree_set_nonstandard_days (PLANNER_TASK_TREE (priv->tree),
+						show_nostd_days);
 
 	gtk_toggle_action_set_active (
 		GTK_TOGGLE_ACTION (gtk_action_group_get_action (priv->actions, "HighlightCriticalTasks")),
 		show_critical);
+
+	gtk_toggle_action_set_active (
+		GTK_TOGGLE_ACTION (gtk_action_group_get_action (priv->actions, "NonstandardDays")),
+		show_nostd_days);
 	
 	task_view_selection_changed_cb (PLANNER_TASK_TREE (priv->tree), view);
 
@@ -582,6 +594,25 @@
 }
 
 static void
+task_view_nonstandard_days_cb (GtkAction *action,
+				 gpointer   data)
+{
+	PlannerTaskViewPriv *priv;
+	gboolean             state;
+	
+	priv = PLANNER_TASK_VIEW (data)->priv;
+
+	state = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+
+	planner_task_tree_set_nonstandard_days (
+		PLANNER_TASK_TREE (priv->tree),
+		state);
+
+
+	planner_conf_set_bool (NOSTDDAYS_PATH_KEY, state, NULL);
+}
+
+static void
 task_view_edit_columns_cb (GtkAction *action,
 			   gpointer   data)
 {



* added files

--- /dev/null
+++ mod/{arch}/planner/planner--mop2/planner--mop2--0/nastasi alternativeoutput it--projects/patch-log/patch-1
@@ -0,0 +1,19 @@
+Revision: planner--mop2--0--patch-1
+Archive: nastasi alternativeoutput it--projects
+Creator: Matteo Nastasi aka mop <nastasi alternativeoutput it>
+Date: dom apr  9 14:03:19 CEST 2006
+Standard-date: 2006-04-09 12:03:19 GMT
+Modified-files: autogen.sh configure.in
+    data/planner.schemas.in data/ui/gantt-view.ui
+    libplanner/mrp-calendar.c libplanner/mrp-calendar.h
+    libplanner/mrp-task-manager.c libplanner/mrp-task.c
+    libplanner/mrp-task.h src/planner-gantt-chart.c
+    src/planner-gantt-chart.h src/planner-gantt-row.c
+    src/planner-gantt-view.c src/planner-task-tree.c
+    src/planner-task-tree.h src/planner-task-view.c
+New-patches: nastasi alternativeoutput it--projects/planner--mop2--0--patch-1
+Summary: kurt refactoring of mop05 revision
+Keywords: 
+
+kurt refactoring of mop05 revision
+
--- /dev/null
+++ mod/{arch}/planner/planner--mop2/planner--mop2--0/nastasi alternativeoutput it--projects/patch-log/patch-2
@@ -0,0 +1,12 @@
+Revision: planner--mop2--0--patch-2
+Archive: nastasi alternativeoutput it--projects
+Creator: Matteo Nastasi aka mop <nastasi alternativeoutput it>
+Date: dom apr  9 14:04:43 CEST 2006
+Standard-date: 2006-04-09 12:04:43 GMT
+Modified-files: src/planner-gantt-row.c
+New-patches: nastasi alternativeoutput it--projects/planner--mop2--0--patch-2
+Summary: changed the policy of color management and used trimmed graphical functions
+Keywords: 
+
+changed the policy of color management and used trimmed graphical functions
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]