1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/maemo-ui/src/mmyth_epg_grid_widget.c Sat Dec 02 03:40:20 2006 +0000
1.3 @@ -0,0 +1,622 @@
1.4 +#include <gtk/gtksignal.h>
1.5 +#include <gdk/gdkevents.h>
1.6 +#include <gdk/gdkkeysyms.h>
1.7 +
1.8 +#include "mmyth_uicommon.h"
1.9 +#include "mmyth_epg_grid_widget.h"
1.10 +
1.11 +#include "gmyth_util.h"
1.12 +#include "gmyth_epg.h"
1.13 +
1.14 +#define PIXELS_HOUR 105
1.15 +#define PROGRAM_SEPARATION 2
1.16 +
1.17 +enum {
1.18 + SELECTION_UPDATED_SIGNAL,
1.19 + LAST_SIGNAL
1.20 +};
1.21 +
1.22 +struct _MMythEpgGridWidgetPrivate {
1.23 + /* private widget components */
1.24 + GtkWidget *epg_channels_vbox;
1.25 + GtkWidget *epg_programs_vbox;
1.26 +
1.27 + GHashTable *service_model_hash;
1.28 +
1.29 + /* guidegrid attributes */
1.30 + gboolean show_favorites;
1.31 + gint current_start_channel_id;
1.32 +
1.33 + time_t current_start_time;
1.34 + time_t current_end_time;
1.35 +
1.36 + guint selected_channel_index;
1.37 +
1.38 + /* GList of ProgramInfo for each Channel */
1.39 + GList * program_list[MAX_DISPLAY_CHANS];
1.40 + GList * channel_list;
1.41 +
1.42 + GMythEPG *mmyth_epg;
1.43 +
1.44 + gint DISPLAY_CHANS;
1.45 +};
1.46 +
1.47 +static void mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass);
1.48 +static void mmyth_epg_grid_widget_init (MMythEpgGridWidget *object);
1.49 +static void mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private);
1.50 +static void mmyth_epg_grid_widget_mount_services (MMythEpgGridWidget *object,
1.51 + int start_time, int end_time);
1.52 +static void mmyth_epg_grid_widget_mount_header (MMythEpgGridWidget *object);
1.53 +static void mmyth_epg_grid_widget_clicked (GtkWidget* widget,
1.54 + GdkEventExpose *event,
1.55 + gpointer data);
1.56 +static GtkWidget *create_event_box_lbl (gchar *str, int width,
1.57 + const GdkColor *bg_color,
1.58 + const GdkColor *fg_color);
1.59 +
1.60 +static void mmyth_epg_grid_widget_fill_programinfos(MMythEpgGridWidgetPrivate *private);
1.61 +static void mmyth_epg_grid_widget_fill_program_row_infos(
1.62 + MMythEpgGridWidgetPrivate *private,
1.63 + unsigned int chanNum, unsigned int row);
1.64 +
1.65 +static gint mmyth_epg_grid_widget_signals[LAST_SIGNAL] = { 0 };
1.66 +
1.67 +G_DEFINE_TYPE(MMythEpgGridWidget, mmyth_epg_grid_widget, GTK_TYPE_EVENT_BOX)
1.68 +
1.69 +static void
1.70 +mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass)
1.71 +{
1.72 + g_type_class_add_private (klass, sizeof (MMythEpgGridWidgetPrivate));
1.73 +
1.74 + mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL] = g_signal_new (
1.75 + "selection_updated",
1.76 + G_TYPE_FROM_CLASS(klass),
1.77 + G_SIGNAL_RUN_FIRST,
1.78 + 0,
1.79 + NULL,
1.80 + NULL,
1.81 + g_cclosure_marshal_VOID__POINTER,
1.82 + G_TYPE_NONE,
1.83 + 1,
1.84 + G_TYPE_POINTER);
1.85 +}
1.86 +
1.87 +static void
1.88 +mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private)
1.89 +{
1.90 + time_t cur_time;
1.91 +
1.92 + g_return_if_fail(private != NULL);
1.93 +
1.94 + private->epg_channels_vbox = NULL;
1.95 + private->epg_programs_vbox = NULL;
1.96 + private->service_model_hash = NULL;
1.97 +
1.98 + private->show_favorites = FALSE;
1.99 + private->current_start_channel_id = -1;
1.100 +
1.101 + /* Selected the first diplayable channel initially */
1.102 + private->selected_channel_index = 0;
1.103 +
1.104 + /* TODO fix the current start/end time */
1.105 + private->current_start_time = time(&cur_time);
1.106 + private->current_end_time = time(&cur_time) + 10800;
1.107 +
1.108 + private->DISPLAY_CHANS = MAX_DISPLAY_CHANS;
1.109 +
1.110 + // TODO: Close the epg and unref it in dispose call
1.111 + private->mmyth_epg = gmyth_epg_new ();
1.112 + if (!gmyth_epg_connect (private->mmyth_epg)) {
1.113 + g_warning ("[%s] Could not connect mysql handler to db", __FUNCTION__);
1.114 + g_object_unref (private->mmyth_epg);
1.115 + private->mmyth_epg = NULL;
1.116 + }
1.117 +}
1.118 +
1.119 +static void
1.120 +mmyth_epg_grid_widget_init (MMythEpgGridWidget *mmyth_epg_grid_widget)
1.121 +{
1.122 + MMythEpgGridWidgetPrivate *private =
1.123 + MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
1.124 +
1.125 + /* init private fields */
1.126 + mmyth_epg_grid_widget_private_init(private);
1.127 +
1.128 + mmyth_epg_grid_widget->epg_view_model = NULL;
1.129 + mmyth_epg_grid_widget->selected_grid_item = NULL;
1.130 +
1.131 + GtkWidget *epg_event_box = GTK_WIDGET(mmyth_epg_grid_widget);
1.132 + gtk_widget_modify_bg(epg_event_box, GTK_STATE_NORMAL, &main_bg_color);
1.133 + gtk_widget_set_size_request (epg_event_box, 0, 125);
1.134 +
1.135 + GtkWidget *epg_main_hbox = gtk_hbox_new (FALSE, 10);
1.136 + gtk_container_set_border_width(GTK_CONTAINER (epg_main_hbox), 10);
1.137 +
1.138 + gtk_container_add (GTK_CONTAINER (epg_event_box),
1.139 + epg_main_hbox);
1.140 +
1.141 + /* channels vbox */
1.142 + GtkWidget *epg_channels_vbox = gtk_vbox_new (FALSE, 3);
1.143 + private->epg_channels_vbox = epg_channels_vbox;
1.144 +
1.145 + /* programs vbox */
1.146 + GtkWidget *epg_programs_vbox = gtk_vbox_new (FALSE, 3);
1.147 + private->epg_programs_vbox = epg_programs_vbox;
1.148 +
1.149 + /* packing start */
1.150 + gtk_box_pack_start (GTK_BOX (epg_main_hbox),
1.151 + epg_channels_vbox, FALSE, FALSE, 0);
1.152 + gtk_box_pack_start (GTK_BOX (epg_main_hbox),
1.153 + epg_programs_vbox, FALSE, FALSE, 0);
1.154 +
1.155 + /* table header (first line) */
1.156 + mmyth_epg_grid_widget_mount_header(mmyth_epg_grid_widget);
1.157 +
1.158 + /* service programs */
1.159 + /* mount service programs with current time */
1.160 + mmyth_epg_grid_widget_mount_services(mmyth_epg_grid_widget,
1.161 + private->current_start_time,
1.162 + private->current_end_time);
1.163 +}
1.164 +
1.165 +GtkWidget*
1.166 +mmyth_epg_grid_widget_new ()
1.167 +{
1.168 + return GTK_WIDGET ( gtk_type_new (mmyth_epg_grid_widget_get_type ()));
1.169 +}
1.170 +
1.171 +static void
1.172 +mmyth_epg_grid_widget_mount_services(MMythEpgGridWidget *mmyth_epg_grid_widget,
1.173 + int start_time, int end_time)
1.174 +{
1.175 + GList *proglist;
1.176 + GList *channel_list = NULL;
1.177 + GMythChannelInfo *channel_info;
1.178 +
1.179 + int chanid;
1.180 + MMythEpgGridWidgetPrivate *private =
1.181 + MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
1.182 +
1.183 + // update view_model
1.184 + /* FIXME shallow free or recursive? */
1.185 + if(mmyth_epg_grid_widget->epg_view_model != NULL) {
1.186 + g_list_free(mmyth_epg_grid_widget->epg_view_model);
1.187 + mmyth_epg_grid_widget->epg_view_model = NULL;
1.188 + }
1.189 +
1.190 + if(private->service_model_hash != NULL) {
1.191 + g_hash_table_destroy(private->service_model_hash);
1.192 + }
1.193 +
1.194 + private->service_model_hash = g_hash_table_new(NULL, NULL);
1.195 +
1.196 + /* fill program infos from db */
1.197 + mmyth_epg_grid_widget_fill_programinfos(private);
1.198 +
1.199 + channel_list = private->channel_list;
1.200 +
1.201 + /* for each channel get_programs() */
1.202 + for (chanid=0; channel_list &&
1.203 + chanid < private->DISPLAY_CHANS; chanid++) {
1.204 + proglist = (GList *) private->program_list[chanid];
1.205 +
1.206 + channel_info = (GMythChannelInfo *) channel_list->data;
1.207 + channel_list = g_list_next(channel_list);
1.208 +
1.209 + /* Service Title*/
1.210 + GString *name = NULL;
1.211 + if (channel_info->channel_name)
1.212 + name = g_string_new (channel_info->channel_name->str);
1.213 +
1.214 + GdkColor title_bg_color;
1.215 + title_bg_color.red = 5000;
1.216 + title_bg_color.green = 9000;
1.217 + title_bg_color.blue = 40000;
1.218 +
1.219 + GdkColor title_fg_color;
1.220 + title_fg_color.red = 60000;
1.221 + title_fg_color.green = 60000;
1.222 + title_fg_color.blue = 60000;
1.223 +
1.224 + GtkWidget *event_box_channel = create_event_box_lbl(
1.225 + name->str, 90,
1.226 + &title_bg_color,
1.227 + &title_fg_color);
1.228 +
1.229 + gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
1.230 + event_box_channel, FALSE, FALSE, 0);
1.231 +
1.232 + GtkWidget *epg_line_hbox = gtk_hbox_new (FALSE, 0);
1.233 +
1.234 + GdkColor bg_color;
1.235 + bg_color.red = 5000;
1.236 + bg_color.green = 30000;
1.237 + bg_color.blue = 60000;
1.238 +
1.239 + GdkColor fg_color;
1.240 + fg_color.red = 60000;
1.241 + fg_color.green = 60000;
1.242 + fg_color.blue = 60000;
1.243 +
1.244 + /* Content parsing */
1.245 + GList *epg_grid_list = NULL;
1.246 +
1.247 + GMythProgramInfo *proginfo;
1.248 + int pixel_count = 0;
1.249 + for (; proglist; proglist = proglist->next) {
1.250 + proginfo = (GMythProgramInfo *) proglist->data;
1.251 +
1.252 + GString *content_name = proginfo->title;
1.253 +
1.254 + int initial_time, last_time, duration;
1.255 +
1.256 + int schedule_start_time = proginfo->startts;
1.257 + int schedule_end_time = proginfo->endts;
1.258 +
1.259 + initial_time =
1.260 + (schedule_start_time < start_time) ? start_time : schedule_start_time;
1.261 + last_time = (schedule_end_time > end_time) ? end_time : schedule_end_time;
1.262 + duration = last_time - initial_time;
1.263 +
1.264 + // Verify program time
1.265 + #if 0
1.266 + g_debug ("ServiceID: %d, ScheduleID: %d\n", service->id, schedule->id);
1.267 + fprintf (stderr, "program time\nfrom = %d, to = %d\n",
1.268 + schedule->validFrom, schedule->validTo);
1.269 +
1.270 + struct tm loctime;
1.271 +
1.272 + /* Convert it to local time representation. */
1.273 + if (localtime_r((time_t *)&schedule->validFrom, &loctime) == NULL) {
1.274 + g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
1.275 + return NULL;
1.276 + }
1.277 + fprintf (stderr, asctime (&loctime));
1.278 +
1.279 + if (localtime_r((time_t *)&schedule->validTo, &loctime) == NULL) {
1.280 + g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
1.281 + return NULL;
1.282 + }
1.283 + fprintf (stderr, asctime (&loctime));
1.284 + #endif
1.285 +
1.286 + /* fprintf(stderr, "duration = %d\n", duration); */
1.287 + double duration_hour = duration / (double) 3600.0;
1.288 + /* fprintf(stderr, "duration_hour = %lf\n", duration_hour); */
1.289 +
1.290 + int size = PIXELS_HOUR * duration_hour;
1.291 +
1.292 + /* complete hour */
1.293 + /* FIXME: UGLY WRONG HACK TO ALIGN PROGRAM TIME!!!*/
1.294 + if(last_time%3600 != 0) {
1.295 + size -= PROGRAM_SEPARATION;
1.296 + }
1.297 + if(initial_time%3600 != 0) {
1.298 + size -= PROGRAM_SEPARATION;
1.299 + }
1.300 +
1.301 + pixel_count += size + PROGRAM_SEPARATION;
1.302 + GtkWidget *event_box = create_event_box_lbl(content_name->str,
1.303 + size, &bg_color,
1.304 + &fg_color);
1.305 + gtk_widget_add_events(event_box,
1.306 + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
1.307 +
1.308 + /* create EpgGridItem */
1.309 + EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
1.310 + epg_grid_item->proginfo = proginfo;
1.311 + epg_grid_item->event_box = event_box;
1.312 + epg_grid_item->object = mmyth_epg_grid_widget;
1.313 +
1.314 + epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
1.315 +
1.316 + gtk_box_pack_start (GTK_BOX (epg_line_hbox),
1.317 + event_box, FALSE, FALSE, PROGRAM_SEPARATION);
1.318 +
1.319 + g_signal_connect (G_OBJECT (event_box), "button-press-event",
1.320 + G_CALLBACK (mmyth_epg_grid_widget_clicked),
1.321 + (gpointer*) epg_grid_list);
1.322 + }
1.323 +#if 0
1.324 + printf("chaind = %d!!!!" chanid);fflush(stdout);
1.325 +#endif
1.326 +
1.327 + if(!epg_grid_list) {
1.328 + /* No programs for current channel */
1.329 + /* FIXME: size HARDCODED */
1.330 + GtkWidget *event_box = create_event_box_lbl("No program list available",
1.331 + PIXELS_HOUR * 3, &bg_color,
1.332 + &fg_color);
1.333 + gtk_widget_add_events(event_box,
1.334 + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
1.335 +
1.336 + /* create EpgGridItem */
1.337 + EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
1.338 + epg_grid_item->proginfo = NULL;
1.339 + epg_grid_item->event_box = event_box;
1.340 + epg_grid_item->object = mmyth_epg_grid_widget;
1.341 +
1.342 + epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
1.343 +
1.344 + gtk_box_pack_start (GTK_BOX (epg_line_hbox),
1.345 + event_box, FALSE, FALSE, PROGRAM_SEPARATION);
1.346 +
1.347 + g_signal_connect (G_OBJECT (event_box), "button-press-event",
1.348 + G_CALLBACK (mmyth_epg_grid_widget_clicked),
1.349 + (gpointer*) epg_grid_list);
1.350 + }
1.351 +
1.352 + epg_grid_list = g_list_reverse(epg_grid_list);
1.353 + mmyth_epg_grid_widget->epg_view_model =
1.354 + g_list_append(mmyth_epg_grid_widget->epg_view_model, epg_grid_list);
1.355 +
1.356 + gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
1.357 + epg_line_hbox, FALSE, FALSE, 0);
1.358 + }
1.359 +}
1.360 +
1.361 +static void
1.362 +mmyth_epg_grid_widget_mount_header(MMythEpgGridWidget *mmyth_epg_grid_widget)
1.363 +{
1.364 + MMythEpgGridWidgetPrivate *private =
1.365 + MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
1.366 +
1.367 + struct tm hour_tm;
1.368 + const gchar name_title[] = "Today";
1.369 + GtkWidget * lbl_title = gtk_label_new(name_title);
1.370 +
1.371 + gtk_misc_set_alignment (GTK_MISC(lbl_title), 0.0, 0.5);
1.372 +
1.373 + gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
1.374 + lbl_title, FALSE, FALSE, 0);
1.375 +
1.376 + /* hours title line */
1.377 + GtkWidget *epg_programs_hours_hbox = gtk_hbox_new (TRUE, 0);
1.378 +
1.379 + if (localtime_r((time_t *)&private->current_start_time, &hour_tm) == NULL) {
1.380 + g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
1.381 + return NULL;
1.382 + }
1.383 +
1.384 + if (hour_tm.tm_min>30) {
1.385 + hour_tm.tm_min = 30;
1.386 + } else if (hour_tm.tm_min>0) {
1.387 + hour_tm.tm_min = 0;
1.388 + }
1.389 +
1.390 + gchar hour1_str[10];
1.391 + strftime(hour1_str, 8, "%H:%M", &hour_tm);
1.392 + GtkWidget * lbl_hour1 = gtk_label_new(hour1_str);
1.393 + gtk_misc_set_alignment (GTK_MISC(lbl_hour1), 0.0, 0.5);
1.394 +
1.395 + hour_tm.tm_hour++;
1.396 + gchar hour2_str[10];
1.397 + strftime(hour2_str, 8, "%H:%M", &hour_tm);
1.398 + GtkWidget * lbl_hour2 = gtk_label_new(hour2_str);
1.399 + gtk_misc_set_alignment (GTK_MISC(lbl_hour2), 0.0, 0.5);
1.400 +
1.401 + hour_tm.tm_hour++;
1.402 + gchar hour3_str[10];
1.403 + strftime(hour3_str, 8, "%H:%M", &hour_tm);
1.404 + GtkWidget * lbl_hour3 = gtk_label_new(hour3_str);
1.405 + gtk_misc_set_alignment (GTK_MISC(lbl_hour3), 0.0, 0.5);
1.406 +
1.407 + gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
1.408 + lbl_hour1, TRUE, TRUE, 0);
1.409 + gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
1.410 + lbl_hour2, TRUE, TRUE, 0);
1.411 + gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
1.412 + lbl_hour3, TRUE, TRUE, 0);
1.413 +
1.414 + gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
1.415 + epg_programs_hours_hbox, FALSE, FALSE, 0);
1.416 +}
1.417 +
1.418 +/******************************************************************************
1.419 + * INTERNAL CALLBACKS FOR STATE CHANGE *
1.420 + *****************************************************************************/
1.421 +static void
1.422 +mmyth_epg_grid_widget_deselect_service(MMythEpgGridWidget *mmyth_epg_grid_widget)
1.423 +{
1.424 + EpgGridItem *epg_grid_item;
1.425 +
1.426 + /* deselect*/
1.427 + if(mmyth_epg_grid_widget->selected_grid_item != NULL) {
1.428 + epg_grid_item =
1.429 + (EpgGridItem*) mmyth_epg_grid_widget->selected_grid_item->data;
1.430 + gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_NORMAL);
1.431 + }
1.432 +}
1.433 +
1.434 +static void
1.435 +mmyth_epg_grid_widget_clicked (GtkWidget* widget,
1.436 + GdkEventExpose *event, gpointer data)
1.437 +{
1.438 + g_return_if_fail(data != NULL);
1.439 +
1.440 + GList *epg_grid_item_list = (GList *) data;
1.441 + EpgGridItem *epg_grid_item = (EpgGridItem *) epg_grid_item_list->data;
1.442 +
1.443 + /* update the selected service */
1.444 + mmyth_epg_grid_widget_update_service( epg_grid_item->object, (GList*) data );
1.445 +}
1.446 +
1.447 +void
1.448 +mmyth_epg_grid_widget_update_service(MMythEpgGridWidget * object,
1.449 + GList *selected_grid_list)
1.450 +{
1.451 + g_return_if_fail(object != NULL);
1.452 + g_return_if_fail(selected_grid_list != NULL);
1.453 +
1.454 + EpgGridItem *epg_grid_item = (EpgGridItem *) selected_grid_list->data;
1.455 +
1.456 + mmyth_epg_grid_widget_deselect_service(epg_grid_item->object);
1.457 +
1.458 + /* updating current selected schedule_item and schedule_list*/
1.459 + object->selected_grid_item = selected_grid_list;
1.460 +
1.461 + /* set state of the event box */
1.462 + gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_SELECTED);
1.463 + /* emit update signal for listeners */
1.464 + g_signal_emit(object,
1.465 + mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL],
1.466 + 0,
1.467 + (gpointer) epg_grid_item);
1.468 +}
1.469 +
1.470 +static GtkWidget *
1.471 +create_event_box_lbl(gchar *str, int width, const GdkColor *bg_color,
1.472 + const GdkColor *fg_color)
1.473 +{
1.474 + GtkWidget *event_box = gtk_event_box_new();
1.475 + GtkWidget *lbl = gtk_label_new(str);
1.476 + gtk_label_set_ellipsize(GTK_LABEL(lbl), PANGO_ELLIPSIZE_END);
1.477 +
1.478 + gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, bg_color);
1.479 + gtk_widget_modify_fg(lbl, GTK_STATE_NORMAL, fg_color);
1.480 +
1.481 + /* selected colors are const*/
1.482 + GdkColor selected_bg_color;
1.483 + selected_bg_color.red = 100;
1.484 + selected_bg_color.green = 40000;
1.485 + selected_bg_color.blue = 100;
1.486 +
1.487 + GdkColor selected_fg_color;
1.488 + selected_fg_color.red = 100;
1.489 + selected_fg_color.green = 100;
1.490 + selected_fg_color.blue = 100;
1.491 +
1.492 + gtk_widget_modify_bg(event_box, GTK_STATE_SELECTED, &selected_bg_color);
1.493 + gtk_widget_modify_fg(lbl, GTK_STATE_SELECTED, &selected_fg_color);
1.494 +
1.495 + gtk_misc_set_alignment (GTK_MISC(lbl), 0.0, 0.5);
1.496 + gtk_container_add (GTK_CONTAINER (event_box),
1.497 + lbl);
1.498 + gtk_widget_set_size_request(event_box, width, -1);
1.499 +
1.500 + return event_box;
1.501 +}
1.502 +
1.503 +/******************************************************************************
1.504 + * METHODS *
1.505 + *****************************************************************************/
1.506 +
1.507 +/* Callback for hardware keys */
1.508 +gboolean
1.509 +mmyth_epg_grid_widget_key_press (MMythEpgGridWidget * object,
1.510 + GtkWidget * widget, GdkEventKey * event)
1.511 +{
1.512 + MMythEpgGridWidgetPrivate *private =
1.513 + MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(object);
1.514 +
1.515 + EpgGridItem *epg_grid_item;
1.516 + GList *tmp;
1.517 +
1.518 + /* List of selected_grid_item */
1.519 + GList *selected_view_model;
1.520 +
1.521 + gint channel_index;
1.522 +
1.523 + if(object->selected_grid_item == NULL) {
1.524 + g_warning ("No program selected");
1.525 + return FALSE;
1.526 + }
1.527 +
1.528 + epg_grid_item = (EpgGridItem*) object->selected_grid_item->data;
1.529 +
1.530 + channel_index = private->selected_channel_index;
1.531 +
1.532 + switch (event->keyval) {
1.533 + case GDK_Up:
1.534 + selected_view_model = g_list_nth( object->epg_view_model, channel_index - 1 );
1.535 + if(selected_view_model != NULL) {
1.536 + private->selected_channel_index = channel_index - 1;
1.537 + tmp = (GList *) selected_view_model->data;
1.538 + /* TODO: select a better centralized item
1.539 + currently is picking the 1st or last item */
1.540 + if(g_list_next(object->selected_grid_item) == NULL &&
1.541 + g_list_previous(object->selected_grid_item) != NULL) {
1.542 + /* in this case the new selected will be the last */
1.543 + tmp = g_list_last(tmp);
1.544 + }
1.545 +
1.546 + /* update the selected service */
1.547 + mmyth_epg_grid_widget_update_service( object, tmp );
1.548 + }
1.549 + return TRUE;
1.550 + case GDK_Down:
1.551 + selected_view_model = g_list_nth( object->epg_view_model, channel_index + 1 );
1.552 + if(selected_view_model != NULL) {
1.553 + private->selected_channel_index = channel_index + 1;
1.554 + tmp = (GList *) selected_view_model->data;
1.555 + /* TODO: select a better centralized item
1.556 + currently is picking the 1st or last item */
1.557 + if(g_list_next(object->selected_grid_item) == NULL &&
1.558 + g_list_previous(object->selected_grid_item) != NULL) {
1.559 + /* in this case the new selected will be the last */
1.560 + tmp = g_list_last(tmp);
1.561 + }
1.562 +
1.563 + /* update the selected service */
1.564 + mmyth_epg_grid_widget_update_service( object, tmp );
1.565 + }
1.566 + return TRUE;
1.567 + case GDK_Left:
1.568 + tmp = g_list_previous( object->selected_grid_item );
1.569 + if(tmp != NULL) {
1.570 + /* update the selected service */
1.571 + mmyth_epg_grid_widget_update_service( object, tmp );
1.572 + }
1.573 + return TRUE;
1.574 + case GDK_Right:
1.575 + tmp = g_list_next( object->selected_grid_item );
1.576 + if(tmp != NULL) {
1.577 + /* update the selected service */
1.578 + mmyth_epg_grid_widget_update_service( object, tmp );
1.579 + }
1.580 + return TRUE;
1.581 + default:
1.582 + return TRUE;
1.583 + }
1.584 +
1.585 + return FALSE;
1.586 +}
1.587 +
1.588 +static void
1.589 +mmyth_epg_grid_widget_fill_programinfos (MMythEpgGridWidgetPrivate *private)
1.590 +{
1.591 + GList *channels_list = NULL;
1.592 + int y;
1.593 +
1.594 + if ((private->mmyth_epg != NULL) &&
1.595 + (gmyth_epg_get_channel_list (private->mmyth_epg, &channels_list) < 0 )) {
1.596 + private->channel_list = NULL;
1.597 + return;
1.598 + }
1.599 +
1.600 + private->channel_list = channels_list;
1.601 +
1.602 + for (y = 0; y < private->DISPLAY_CHANS && channels_list; y++) {
1.603 + GMythChannelInfo *channel_info = (GMythChannelInfo *) channels_list->data;
1.604 +
1.605 + mmyth_epg_grid_widget_fill_program_row_infos(
1.606 + private, channel_info->channel_ID, y);
1.607 +
1.608 + channels_list = g_list_next (channels_list);
1.609 + }
1.610 +}
1.611 +
1.612 +static void
1.613 +mmyth_epg_grid_widget_fill_program_row_infos(MMythEpgGridWidgetPrivate *private,
1.614 + guint chanNum, guint row)
1.615 +{
1.616 + gint res = gmyth_epg_get_program_list (private->mmyth_epg,
1.617 + &(private->program_list[row]),
1.618 + chanNum, private->current_start_time,
1.619 + private->current_end_time);
1.620 +
1.621 + if (res < 0) {
1.622 + g_warning ("[%s] Error while retrieving epg programs", __FUNCTION__);
1.623 + }
1.624 +}
1.625 +