Re: [Planner Dev] "Nonstandard Days" and "Dominant tasks" - 5th patch - the end of the tunnel ? ; )



On Tue, 2006-03-21 at 11:08 +0100, Matteo Nastasi wrote:
> Hi guys, attached the 5th revision of my patch.
> 
> Your comments are wellcome.

I didn't want to torture you any longer with picky stylistic issues, so
I went ahead and made some adjustments in terms of spacing, and one
instance of omitted braces on a for statement.  Patch attached.

I did notice something though, it appears when zooming out on a project
until the weekend nonworking time is no longer greyed out in the gantt
background.  Looks like the gantt bars white out during the weekend time
creating a striped look.  This is new behavior.

http://www.maute.us/planner/images/WeekendStriping.png

> ADDENDA: I think that I solve the vertical alignement problem of the 
> text at right of the tasks in gantt view, can you verify it ?

Looks like they're vertically centered now.  I don't see a bug report
for vertical alignment though - maybe I missed it.

-- 
Kurt Maute <kurt maute us>
? planner/{arch}
? planner/docs/user-guide/eu/Makefile
? planner/docs/user-guide/eu/Makefile.in
? planner/docs/user-guide/eu/omf_timestamp
? planner/docs/user-guide/eu/planner-eu.omf.out
Index: planner/autogen.sh
===================================================================
RCS file: /cvs/gnome/planner/autogen.sh,v
retrieving revision 1.7
diff -u -r1.7 autogen.sh
--- planner/autogen.sh	16 Apr 2005 16:30:25 -0000	1.7
+++ planner/autogen.sh	22 Mar 2006 03:22:59 -0000
@@ -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"
 
Index: planner/configure.in
===================================================================
RCS file: /cvs/gnome/planner/configure.in,v
retrieving revision 1.69
diff -u -r1.69 configure.in
--- planner/configure.in	24 Jan 2006 04:59:01 -0000	1.69
+++ planner/configure.in	22 Mar 2006 03:22:59 -0000
@@ -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,10 +338,15 @@
 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 ***"
Index: planner/data/planner.schemas.in
===================================================================
RCS file: /cvs/gnome/planner/data/planner.schemas.in,v
retrieving revision 1.1
diff -u -r1.1 planner.schemas.in
--- planner/data/planner.schemas.in	19 Feb 2005 16:22:05 -0000	1.1
+++ planner/data/planner.schemas.in	22 Mar 2006 03:23:00 -0000
@@ -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>
Index: planner/data/ui/gantt-view.ui
===================================================================
RCS file: /cvs/gnome/planner/data/ui/gantt-view.ui,v
retrieving revision 1.10
diff -u -r1.10 gantt-view.ui
--- planner/data/ui/gantt-view.ui	19 Apr 2005 20:01:41 -0000	1.10
+++ planner/data/ui/gantt-view.ui	22 Mar 2006 03:23:00 -0000
@@ -14,6 +14,7 @@
       <placeholder name="View specific placeholder bottom">
         <menuitem    action="EditColumns"/>
         <menuitem    action="HighlightCriticalTasks"/>
+        <menuitem    action="NonstandardDays"/>
       </placeholder>
     </menu>
 
Index: planner/libplanner/mrp-calendar.c
===================================================================
RCS file: /cvs/gnome/planner/libplanner/mrp-calendar.c,v
retrieving revision 1.7
diff -u -r1.7 mrp-calendar.c
--- planner/libplanner/mrp-calendar.c	24 Feb 2005 22:31:41 -0000	1.7
+++ planner/libplanner/mrp-calendar.c	22 Mar 2006 03:23:00 -0000
@@ -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, 
Index: planner/libplanner/mrp-calendar.h
===================================================================
RCS file: /cvs/gnome/planner/libplanner/mrp-calendar.h,v
retrieving revision 1.3
diff -u -r1.3 mrp-calendar.h
--- planner/libplanner/mrp-calendar.h	29 Jun 2004 09:06:44 -0000	1.3
+++ planner/libplanner/mrp-calendar.h	22 Mar 2006 03:23:00 -0000
@@ -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__ */
Index: planner/libplanner/mrp-task-manager.c
===================================================================
RCS file: /cvs/gnome/planner/libplanner/mrp-task-manager.c,v
retrieving revision 1.18
diff -u -r1.18 mrp-task-manager.c
--- planner/libplanner/mrp-task-manager.c	25 Oct 2005 21:26:40 -0000	1.18
+++ planner/libplanner/mrp-task-manager.c	22 Mar 2006 03:23:01 -0000
@@ -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,
Index: planner/libplanner/mrp-task.c
===================================================================
RCS file: /cvs/gnome/planner/libplanner/mrp-task.c,v
retrieving revision 1.14
diff -u -r1.14 mrp-task.c
--- planner/libplanner/mrp-task.c	23 Nov 2005 03:41:43 -0000	1.14
+++ planner/libplanner/mrp-task.c	22 Mar 2006 03:23:01 -0000
@@ -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
  * 
@@ -1512,6 +1599,28 @@
 	g_return_val_if_fail (MRP_IS_TASK (task), NULL);
 	
 	return task->priv->assignments;
+}
+
+/**
+ * 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);
 }
 
 /**
Index: planner/libplanner/mrp-task.h
===================================================================
RCS file: /cvs/gnome/planner/libplanner/mrp-task.h,v
retrieving revision 1.6
diff -u -r1.6 mrp-task.h
--- planner/libplanner/mrp-task.h	18 Feb 2005 17:27:56 -0000	1.6
+++ planner/libplanner/mrp-task.h	22 Mar 2006 03:23:01 -0000
@@ -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);
Index: planner/src/planner-gantt-chart.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-gantt-chart.c,v
retrieving revision 1.19
diff -u -r1.19 planner-gantt-chart.c
--- planner/src/planner-gantt-chart.c	9 Oct 2004 14:36:14 -0000	1.19
+++ planner/src/planner-gantt-chart.c	22 Mar 2006 03:23:01 -0000
@@ -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
@@ -1916,4 +1922,33 @@
 	g_return_val_if_fail (PLANNER_IS_GANTT_CHART (chart), FALSE);
 
 	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;
 }
Index: planner/src/planner-gantt-chart.h
===================================================================
RCS file: /cvs/gnome/planner/src/planner-gantt-chart.h,v
retrieving revision 1.6
diff -u -r1.6 planner-gantt-chart.h
--- planner/src/planner-gantt-chart.h	4 Oct 2004 22:29:19 -0000	1.6
+++ planner/src/planner-gantt-chart.h	22 Mar 2006 03:23:01 -0000
@@ -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__ */
Index: planner/src/planner-gantt-row.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-gantt-row.c,v
retrieving revision 1.27
diff -u -r1.27 planner-gantt-row.c
--- planner/src/planner-gantt-row.c	16 Oct 2005 14:36:11 -0000	1.27
+++ planner/src/planner-gantt-row.c	22 Mar 2006 03:23:02 -0000
@@ -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_rectangle 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) {
+			gdk_draw_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);
+		
+		gdk_draw_line (drawable, gc, ttime_x1, ttime_y1,
+					   ttime_x2-1, ttime_y1);
+		gdk_draw_line (drawable, gc, ttime_x1, ttime_y1,
+					   ttime_x1, cy1-1);
+		}
+		else {
+			gdk_draw_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);
+			
+			gdk_draw_line (drawable, gc, ttime_x1, ttime_y2,
+						   ttime_x2-1, ttime_y2);
+			gdk_draw_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,20 +1314,433 @@
 							 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);
+			gdk_draw_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 (planner_scale_conf[level].nonworking_limit <= 
+						cur_end - cur_start) {						
+						delta = 1.0;
+					}
+					else {
+						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) {
+						gdk_draw_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);
+						gdk_draw_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);
+			}
+			gdk_draw_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,
 					    priv->complete_gc,
@@ -991,8 +1751,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);
+ 				gdk_draw_line (drawable, priv->frame_gc, cx1, cy1, cx2, cy1);
+ 				gdk_draw_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
+ 				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
+ 			}
+ 		}
+#endif
 
 		if (!highlight_critical || !critical) {
 			gdk_gc_set_foreground (priv->fill_gc, &priv->color_normal_light);
@@ -1037,26 +1820,36 @@
 				       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) {
+				gdk_draw_line (drawable, priv->frame_gc,
+						cx1, cy1, cx1, cy2);
+			}
+			if (cx2 == rx2) {
+				gdk_draw_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;
@@ -1137,11 +1930,14 @@
 	rx2 = MIN (cx2 + TEXT_PADDING + priv->text_width, width);
 
 	if (priv->layout != NULL && rx1 < rx2) {
-		/* FIXME: Center the text vertically? */
+		/* 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 ??? ;). */
+		   
 		gdk_draw_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) {
@@ -1250,7 +2046,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 +2158,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 +2291,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 +2332,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 +2386,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 +2420,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 +2522,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 +2619,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 +2822,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;
Index: planner/src/planner-gantt-view.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-gantt-view.c,v
retrieving revision 1.28
diff -u -r1.28 planner-gantt-view.c
--- planner/src/planner-gantt-view.c	23 Apr 2005 10:33:09 -0000	1.28
+++ planner/src/planner-gantt-view.c	22 Mar 2006 03:23:02 -0000
@@ -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),
@@ -825,6 +841,29 @@
 	planner_task_tree_set_highlight_critical (
                 PLANNER_TASK_TREE (priv->tree),
 		state);
+}
+
+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
Index: planner/src/planner-task-tree.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-tree.c,v
retrieving revision 1.61
diff -u -r1.61 planner-task-tree.c
--- planner/src/planner-task-tree.c	12 Apr 2005 22:20:47 -0000	1.61
+++ planner/src/planner-task-tree.c	22 Mar 2006 03:23:03 -0000
@@ -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)
 {
@@ -3586,6 +3604,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)
Index: planner/src/planner-task-tree.h
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-tree.h,v
retrieving revision 1.11
diff -u -r1.11 planner-task-tree.h
--- planner/src/planner-task-tree.h	12 Apr 2005 22:20:47 -0000	1.11
+++ planner/src/planner-task-tree.h	22 Mar 2006 03:23:03 -0000
@@ -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);
Index: planner/src/planner-task-view.c
===================================================================
RCS file: /cvs/gnome/planner/src/planner-task-view.c,v
retrieving revision 1.24
diff -u -r1.24 planner-task-view.c
--- planner/src/planner-task-view.c	23 Apr 2005 10:33:10 -0000	1.24
+++ planner/src/planner-task-view.c	22 Mar 2006 03:23:03 -0000
@@ -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);
 
@@ -579,6 +591,25 @@
 		state);
 
 	planner_conf_set_bool (CRITICAL_PATH_KEY, state, NULL);
+}
+
+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


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