diff -r 000000000000 -r 517da097a261 maemo-ui/src/mmyth_epg_grid_widget.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/maemo-ui/src/mmyth_epg_grid_widget.c	Thu Nov 30 21:29:38 2006 +0000
@@ -0,0 +1,622 @@
+#include <gtk/gtksignal.h>
+#include <gdk/gdkevents.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "mmyth_uicommon.h"
+#include "mmyth_epg_grid_widget.h"
+
+#include "gmyth_util.h" 
+#include "gmyth_epg.h"
+
+#define PIXELS_HOUR 105
+#define PROGRAM_SEPARATION 2
+
+enum {
+  SELECTION_UPDATED_SIGNAL,
+  LAST_SIGNAL
+};
+
+struct _MMythEpgGridWidgetPrivate {
+    /* private widget components */
+    GtkWidget *epg_channels_vbox;
+    GtkWidget *epg_programs_vbox;
+ 
+    GHashTable *service_model_hash;
+    
+    /* guidegrid attributes */
+    gboolean show_favorites;
+    gint current_start_channel_id;
+    
+    time_t current_start_time;
+    time_t current_end_time;
+
+    guint selected_channel_index;
+    
+    /* GList of ProgramInfo for each Channel */
+    GList * program_list[MAX_DISPLAY_CHANS];
+    GList * channel_list;
+    
+    GMythEPG *mmyth_epg;
+    
+    gint DISPLAY_CHANS;
+};
+
+static void mmyth_epg_grid_widget_class_init          (MMythEpgGridWidgetClass *klass);
+static void mmyth_epg_grid_widget_init                (MMythEpgGridWidget *object);
+static void mmyth_epg_grid_widget_private_init        (MMythEpgGridWidgetPrivate *private);
+static void mmyth_epg_grid_widget_mount_services      (MMythEpgGridWidget *object, 
+                                                       int start_time, int end_time);
+static void mmyth_epg_grid_widget_mount_header        (MMythEpgGridWidget *object);
+static void mmyth_epg_grid_widget_clicked             (GtkWidget* widget, 
+                                                       GdkEventExpose *event, 
+                                                       gpointer data);
+static GtkWidget *create_event_box_lbl                (gchar *str, int width, 
+                                                       const GdkColor *bg_color, 
+                                                       const GdkColor *fg_color);
+
+static void mmyth_epg_grid_widget_fill_programinfos(MMythEpgGridWidgetPrivate *private);
+static void mmyth_epg_grid_widget_fill_program_row_infos(
+                    MMythEpgGridWidgetPrivate *private, 
+                    unsigned int chanNum, unsigned int row);
+
+static gint mmyth_epg_grid_widget_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE(MMythEpgGridWidget, mmyth_epg_grid_widget, GTK_TYPE_EVENT_BOX)
+    
+static void
+mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass)
+{
+  g_type_class_add_private (klass, sizeof (MMythEpgGridWidgetPrivate));
+  
+  mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL] = g_signal_new (
+                     "selection_updated",
+					 G_TYPE_FROM_CLASS(klass), 
+					 G_SIGNAL_RUN_FIRST,
+					 0,
+                     NULL,
+                     NULL,
+					 g_cclosure_marshal_VOID__POINTER, 
+                     G_TYPE_NONE, 
+                     1,
+                     G_TYPE_POINTER);
+}
+
+static void 
+mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private)
+{
+    time_t cur_time;
+    
+    g_return_if_fail(private != NULL);     
+
+    private->epg_channels_vbox   = NULL;
+    private->epg_programs_vbox   = NULL;
+    private->service_model_hash  = NULL;
+
+    private->show_favorites = FALSE;
+    private->current_start_channel_id = -1;
+
+    /* Selected the first diplayable channel initially */
+    private->selected_channel_index = 0;
+        
+    /* TODO fix the current start/end time */
+    private->current_start_time = time(&cur_time);
+    private->current_end_time = time(&cur_time) + 10800;   
+    
+    private->DISPLAY_CHANS = MAX_DISPLAY_CHANS;
+    
+    // TODO: Close the epg and unref it in dispose call
+    private->mmyth_epg = gmyth_epg_new ();
+    if (!gmyth_epg_connect (private->mmyth_epg)) {
+    	g_warning ("[%s] Could not connect mysql handler to db", __FUNCTION__);
+    	g_object_unref (private->mmyth_epg);
+    	private->mmyth_epg = NULL;
+    }
+}
+
+static void
+mmyth_epg_grid_widget_init (MMythEpgGridWidget *mmyth_epg_grid_widget)
+{
+    MMythEpgGridWidgetPrivate *private = 
+        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
+    
+    /* init private fields */
+    mmyth_epg_grid_widget_private_init(private);
+
+    mmyth_epg_grid_widget->epg_view_model      = NULL;
+    mmyth_epg_grid_widget->selected_grid_item  = NULL;
+
+    GtkWidget *epg_event_box = GTK_WIDGET(mmyth_epg_grid_widget);
+    gtk_widget_modify_bg(epg_event_box, GTK_STATE_NORMAL, &main_bg_color);
+    gtk_widget_set_size_request (epg_event_box, 0, 125);
+    
+    GtkWidget *epg_main_hbox = gtk_hbox_new (FALSE, 10);
+    gtk_container_set_border_width(GTK_CONTAINER (epg_main_hbox), 10);
+    
+    gtk_container_add (GTK_CONTAINER (epg_event_box),
+                       epg_main_hbox);
+		        
+    /* channels vbox */
+    GtkWidget *epg_channels_vbox = gtk_vbox_new (FALSE, 3); 
+    private->epg_channels_vbox = epg_channels_vbox; 
+
+    /* programs vbox */
+    GtkWidget *epg_programs_vbox = gtk_vbox_new (FALSE, 3);
+    private->epg_programs_vbox = epg_programs_vbox;
+    
+    /* packing start */
+    gtk_box_pack_start (GTK_BOX (epg_main_hbox),
+	                epg_channels_vbox, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (epg_main_hbox),
+                        epg_programs_vbox, FALSE, FALSE, 0);
+
+    /* table header (first line) */  
+    mmyth_epg_grid_widget_mount_header(mmyth_epg_grid_widget);                 
+    
+    /* service programs */ 
+    /* mount service programs with current time */
+    mmyth_epg_grid_widget_mount_services(mmyth_epg_grid_widget, 
+                                         private->current_start_time,
+                                         private->current_end_time);                                           
+}
+
+GtkWidget*
+mmyth_epg_grid_widget_new ()
+{
+  return GTK_WIDGET ( gtk_type_new (mmyth_epg_grid_widget_get_type ()));
+}
+
+static void
+mmyth_epg_grid_widget_mount_services(MMythEpgGridWidget *mmyth_epg_grid_widget, 
+                                     int start_time, int end_time)
+{
+    GList *proglist;
+    GList *channel_list = NULL;
+    GMythChannelInfo *channel_info;
+
+    int chanid;
+    MMythEpgGridWidgetPrivate *private = 
+        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
+	
+	// update view_model
+	/* FIXME shallow free or recursive? */
+	if(mmyth_epg_grid_widget->epg_view_model != NULL) {
+		g_list_free(mmyth_epg_grid_widget->epg_view_model);
+		mmyth_epg_grid_widget->epg_view_model = NULL;
+	}
+	
+	if(private->service_model_hash != NULL) {
+		g_hash_table_destroy(private->service_model_hash);
+	}
+
+	private->service_model_hash = g_hash_table_new(NULL, NULL);
+
+    /* fill program infos from db */
+    mmyth_epg_grid_widget_fill_programinfos(private);
+    
+    channel_list = private->channel_list;
+ 
+    /* for each channel get_programs() */
+    for (chanid=0; channel_list &&
+                   chanid < private->DISPLAY_CHANS; chanid++) {
+        proglist = (GList *) private->program_list[chanid];        
+    
+        channel_info = (GMythChannelInfo *) channel_list->data;
+        channel_list = g_list_next(channel_list);        
+
+        /* Service Title*/
+        GString *name = NULL;
+        if (channel_info->channel_name)
+        	name = g_string_new (channel_info->channel_name->str);
+		
+		GdkColor title_bg_color;
+		title_bg_color.red = 5000;
+		title_bg_color.green = 9000;
+		title_bg_color.blue = 40000;        
+		
+		GdkColor title_fg_color;
+		title_fg_color.red = 60000;
+		title_fg_color.green = 60000;
+		title_fg_color.blue = 60000;        
+		
+		GtkWidget *event_box_channel = create_event_box_lbl(
+                                                        name->str, 90, 
+									                    &title_bg_color, 
+									                    &title_fg_color);
+
+        gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
+		                    event_box_channel, FALSE, FALSE, 0);
+
+  		GtkWidget *epg_line_hbox = gtk_hbox_new (FALSE, 0);      
+
+	    GdkColor bg_color;
+	    bg_color.red = 5000;
+	    bg_color.green = 30000;
+	    bg_color.blue = 60000;        
+	
+	    GdkColor fg_color;
+	    fg_color.red = 60000;
+	    fg_color.green = 60000;
+	    fg_color.blue = 60000;        
+		
+		/* Content parsing */
+        GList *epg_grid_list = NULL;
+
+        GMythProgramInfo *proginfo;
+        int pixel_count = 0;
+        for (; proglist; proglist = proglist->next) {
+            proginfo = (GMythProgramInfo *) proglist->data;
+            
+            GString *content_name = proginfo->title;
+                    
+       	    int initial_time, last_time, duration;
+
+            int schedule_start_time = proginfo->startts;
+            int schedule_end_time   = proginfo->endts;
+
+	        initial_time = 
+                (schedule_start_time < start_time) ? start_time : schedule_start_time;
+            last_time = (schedule_end_time > end_time) ? end_time : schedule_end_time;
+	        duration = last_time - initial_time;
+		    
+            // Verify program time 
+            #if 0
+			    g_debug ("ServiceID: %d, ScheduleID: %d\n", service->id, schedule->id);
+                fprintf (stderr, "program time\nfrom = %d, to = %d\n", 
+                         schedule->validFrom, schedule->validTo); 
+                
+                struct tm loctime;
+    
+                /* Convert it to local time representation. */
+                if (localtime_r((time_t *)&schedule->validFrom, &loctime) == NULL) {
+                    g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
+                    return NULL;
+                }            
+                fprintf (stderr, asctime (&loctime)); 
+                
+                if (localtime_r((time_t *)&schedule->validTo, &loctime) == NULL) {
+                    g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
+                    return NULL;
+                } 
+                fprintf (stderr, asctime (&loctime)); 
+            #endif
+    		
+    	    /* fprintf(stderr, "duration = %d\n", duration); */
+    	    double duration_hour = duration / (double) 3600.0;
+    	    /* fprintf(stderr, "duration_hour = %lf\n", duration_hour); */
+    		
+            int size = PIXELS_HOUR * duration_hour;
+                
+            /* complete hour */
+            /* FIXME: UGLY WRONG HACK TO ALIGN PROGRAM TIME!!!*/
+            if(last_time%3600 != 0) {
+                size -= PROGRAM_SEPARATION;                
+            }
+            if(initial_time%3600 != 0) {
+                size -= PROGRAM_SEPARATION;                
+            }
+
+            pixel_count += size + PROGRAM_SEPARATION;
+	        GtkWidget *event_box = create_event_box_lbl(content_name->str, 
+							  size, &bg_color, 
+							  &fg_color);
+							  gtk_widget_add_events(event_box, 
+							  GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+            
+            /* create EpgGridItem */
+            EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
+            epg_grid_item->proginfo  = proginfo;
+            epg_grid_item->event_box = event_box;
+            epg_grid_item->object    = mmyth_epg_grid_widget;
+            
+            epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);                                   		                        
+
+     	    gtk_box_pack_start (GTK_BOX (epg_line_hbox),
+	                            event_box, FALSE, FALSE, PROGRAM_SEPARATION);
+	                                 
+   	        g_signal_connect (G_OBJECT (event_box), "button-press-event",
+		                      G_CALLBACK (mmyth_epg_grid_widget_clicked), 
+                              (gpointer*) epg_grid_list);
+        }
+#if 0
+        printf("chaind = %d!!!!" chanid);fflush(stdout);
+#endif        
+
+        if(!epg_grid_list) {
+            /* No programs for current channel */
+            /* FIXME: size HARDCODED */
+            GtkWidget *event_box = create_event_box_lbl("No program list available",
+                              PIXELS_HOUR * 3, &bg_color,
+                              &fg_color);
+                              gtk_widget_add_events(event_box,
+                              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+
+            /* create EpgGridItem */
+            EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
+            epg_grid_item->proginfo  = NULL;
+            epg_grid_item->event_box = event_box;
+            epg_grid_item->object    = mmyth_epg_grid_widget;
+
+            epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
+            
+            gtk_box_pack_start (GTK_BOX (epg_line_hbox),
+	                            event_box, FALSE, FALSE, PROGRAM_SEPARATION);            	
+	                                 
+   	        g_signal_connect (G_OBJECT (event_box), "button-press-event",
+		                      G_CALLBACK (mmyth_epg_grid_widget_clicked),
+                              (gpointer*) epg_grid_list);
+        }
+
+        epg_grid_list = g_list_reverse(epg_grid_list);
+        mmyth_epg_grid_widget->epg_view_model = 
+              g_list_append(mmyth_epg_grid_widget->epg_view_model, epg_grid_list);
+        
+	    gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
+	                        epg_line_hbox, FALSE, FALSE,  0);                    		    		
+    }
+}
+
+static void
+mmyth_epg_grid_widget_mount_header(MMythEpgGridWidget *mmyth_epg_grid_widget)
+{	          	    
+    MMythEpgGridWidgetPrivate *private = 
+        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
+    
+    struct tm hour_tm;
+    const gchar name_title[] = "Today";    
+    GtkWidget * lbl_title = gtk_label_new(name_title);
+
+    gtk_misc_set_alignment (GTK_MISC(lbl_title), 0.0, 0.5);
+    
+    gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
+                        lbl_title, FALSE, FALSE, 0);
+
+	/* hours title line */
+    GtkWidget *epg_programs_hours_hbox = gtk_hbox_new (TRUE, 0); 
+
+    if (localtime_r((time_t *)&private->current_start_time, &hour_tm) == NULL) {
+        g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
+        return NULL;
+    }    
+
+    if (hour_tm.tm_min>30) {
+        hour_tm.tm_min = 30;
+    } else if (hour_tm.tm_min>0) {
+        hour_tm.tm_min = 0;
+    }
+        
+    gchar hour1_str[10];
+    strftime(hour1_str, 8, "%H:%M", &hour_tm);
+    GtkWidget * lbl_hour1 = gtk_label_new(hour1_str);
+    gtk_misc_set_alignment (GTK_MISC(lbl_hour1), 0.0, 0.5);    
+	
+    hour_tm.tm_hour++;
+    gchar hour2_str[10];    
+    strftime(hour2_str, 8, "%H:%M", &hour_tm);
+    GtkWidget * lbl_hour2 = gtk_label_new(hour2_str);
+    gtk_misc_set_alignment (GTK_MISC(lbl_hour2), 0.0, 0.5);        
+
+    hour_tm.tm_hour++;
+	gchar hour3_str[10];    
+    strftime(hour3_str, 8, "%H:%M", &hour_tm);
+    GtkWidget * lbl_hour3 = gtk_label_new(hour3_str);
+    gtk_misc_set_alignment (GTK_MISC(lbl_hour3), 0.0, 0.5);        
+    
+    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
+                        lbl_hour1, TRUE, TRUE, 0);                    
+    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
+                        lbl_hour2, TRUE, TRUE, 0);                    
+    gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
+                        lbl_hour3, TRUE, TRUE, 0); 
+ 
+    gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
+                        epg_programs_hours_hbox, FALSE, FALSE, 0);                        
+}
+
+/******************************************************************************
+ *              INTERNAL CALLBACKS FOR STATE CHANGE                           *
+ *****************************************************************************/
+static void 
+mmyth_epg_grid_widget_deselect_service(MMythEpgGridWidget *mmyth_epg_grid_widget)
+{
+	EpgGridItem *epg_grid_item;
+	
+  	/* deselect*/
+    if(mmyth_epg_grid_widget->selected_grid_item != NULL) {
+    	epg_grid_item = 
+            (EpgGridItem*) mmyth_epg_grid_widget->selected_grid_item->data;
+    	gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_NORMAL);
+    }            
+}
+
+static void 
+mmyth_epg_grid_widget_clicked (GtkWidget* widget, 
+                               GdkEventExpose *event, gpointer data)
+{           
+    g_return_if_fail(data != NULL);
+
+    GList *epg_grid_item_list = (GList *) data;
+    EpgGridItem *epg_grid_item = (EpgGridItem *) epg_grid_item_list->data;
+
+    /* update the selected service */
+    mmyth_epg_grid_widget_update_service( epg_grid_item->object, (GList*) data );       
+}
+
+void
+mmyth_epg_grid_widget_update_service(MMythEpgGridWidget * object,
+                                     GList *selected_grid_list)
+{
+    g_return_if_fail(object != NULL);
+    g_return_if_fail(selected_grid_list != NULL);
+		
+	EpgGridItem *epg_grid_item = (EpgGridItem *) selected_grid_list->data;
+
+    mmyth_epg_grid_widget_deselect_service(epg_grid_item->object);
+
+    /* updating current selected schedule_item and schedule_list*/
+    object->selected_grid_item = selected_grid_list;
+    
+    /* set state of the event box */
+    gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_SELECTED);
+    /* emit update signal for listeners */
+    g_signal_emit(object, 
+                  mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL],
+                  0,
+                  (gpointer) epg_grid_item);
+}
+
+static GtkWidget * 
+create_event_box_lbl(gchar *str, int width, const GdkColor *bg_color, 
+                     const GdkColor *fg_color) 
+{
+    GtkWidget *event_box = gtk_event_box_new();
+	GtkWidget *lbl = gtk_label_new(str);
+    gtk_label_set_ellipsize(GTK_LABEL(lbl), PANGO_ELLIPSIZE_END);
+
+    gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, bg_color);    
+    gtk_widget_modify_fg(lbl, GTK_STATE_NORMAL, fg_color);    
+    
+    /* selected colors are const*/
+    GdkColor selected_bg_color;
+    selected_bg_color.red = 100;
+    selected_bg_color.green = 40000;
+    selected_bg_color.blue = 100;        
+
+    GdkColor selected_fg_color;
+    selected_fg_color.red = 100;
+    selected_fg_color.green = 100;
+    selected_fg_color.blue = 100;        
+            
+    gtk_widget_modify_bg(event_box, GTK_STATE_SELECTED, &selected_bg_color);    
+    gtk_widget_modify_fg(lbl, GTK_STATE_SELECTED, &selected_fg_color);    
+    
+    gtk_misc_set_alignment (GTK_MISC(lbl), 0.0, 0.5);    
+	gtk_container_add (GTK_CONTAINER (event_box),
+                       lbl);
+	gtk_widget_set_size_request(event_box, width, -1);
+	                       
+    return event_box;
+}
+
+/******************************************************************************
+ *                            METHODS                                         *
+ *****************************************************************************/
+
+/* Callback for hardware keys */
+gboolean
+mmyth_epg_grid_widget_key_press (MMythEpgGridWidget * object, 
+                                 GtkWidget * widget, GdkEventKey * event)
+{
+    MMythEpgGridWidgetPrivate *private = 
+        MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(object);
+  
+    EpgGridItem *epg_grid_item;
+    GList *tmp;
+    
+    /* List of selected_grid_item */
+    GList *selected_view_model;
+    
+    gint channel_index;
+    
+	if(object->selected_grid_item == NULL) {
+        g_warning ("No program selected");
+	    return FALSE;
+	} 
+    
+    epg_grid_item = (EpgGridItem*) object->selected_grid_item->data;    
+    
+    channel_index = private->selected_channel_index;
+    
+    switch (event->keyval) {
+        case GDK_Up:        
+            selected_view_model = g_list_nth( object->epg_view_model, channel_index - 1 );
+            if(selected_view_model != NULL) {
+                private->selected_channel_index = channel_index - 1;
+   	            tmp = (GList *) selected_view_model->data;               
+                /* TODO: select a better centralized item 
+                   currently is picking the 1st or last item */
+                if(g_list_next(object->selected_grid_item) == NULL &&
+                   g_list_previous(object->selected_grid_item) != NULL) {
+                    /* in this case the new selected will be the last */ 
+                    tmp = g_list_last(tmp);
+                }
+
+	            /* update the selected service */
+                mmyth_epg_grid_widget_update_service( object, tmp );
+            }    
+        return TRUE;         
+        case GDK_Down:
+            selected_view_model = g_list_nth( object->epg_view_model, channel_index + 1 );            
+            if(selected_view_model != NULL) {   	            
+                private->selected_channel_index = channel_index + 1;
+   	            tmp = (GList *) selected_view_model->data;
+                /* TODO: select a better centralized item 
+                   currently is picking the 1st or last item */
+                if(g_list_next(object->selected_grid_item) == NULL &&
+                   g_list_previous(object->selected_grid_item) != NULL) {
+                    /* in this case the new selected will be the last */ 
+                    tmp = g_list_last(tmp);
+                }
+
+	            /* update the selected service */
+                mmyth_epg_grid_widget_update_service( object, tmp );
+            }
+        return TRUE;        
+        case GDK_Left:    
+            tmp = g_list_previous( object->selected_grid_item );
+            if(tmp != NULL) {
+	            /* update the selected service */
+                mmyth_epg_grid_widget_update_service( object, tmp );
+            }
+        return TRUE;        
+        case GDK_Right:
+            tmp = g_list_next( object->selected_grid_item );
+            if(tmp != NULL) {
+	            /* update the selected service */
+                mmyth_epg_grid_widget_update_service( object, tmp );
+            }
+        return TRUE;        
+	    default:
+	    return TRUE;
+    }
+    
+    return FALSE;
+}
+
+static void 
+mmyth_epg_grid_widget_fill_programinfos (MMythEpgGridWidgetPrivate *private)
+{
+    GList *channels_list = NULL;
+    int y;
+
+    if ((private->mmyth_epg != NULL) &&
+	   	(gmyth_epg_get_channel_list (private->mmyth_epg, &channels_list) < 0 )) {
+			private->channel_list = NULL;
+			return;
+    }
+    
+    private->channel_list = channels_list;
+    
+    for (y = 0; y < private->DISPLAY_CHANS && channels_list; y++) {
+        GMythChannelInfo *channel_info = (GMythChannelInfo *) channels_list->data;
+
+        mmyth_epg_grid_widget_fill_program_row_infos(
+                            private, channel_info->channel_ID, y);
+
+        channels_list = g_list_next (channels_list);
+    }
+}
+
+static void 
+mmyth_epg_grid_widget_fill_program_row_infos(MMythEpgGridWidgetPrivate *private,
+                                             guint chanNum, guint row)
+{    
+    gint res =  gmyth_epg_get_program_list (private->mmyth_epg,
+    					&(private->program_list[row]),
+                        chanNum, private->current_start_time, 
+                        private->current_end_time);
+                        
+    if (res < 0) {
+    	g_warning ("[%s] Error while retrieving epg programs", __FUNCTION__);
+    }
+}
+