leo_sobral@1
|
1 |
#include <gtk/gtksignal.h>
|
leo_sobral@1
|
2 |
#include <gdk/gdkevents.h>
|
leo_sobral@1
|
3 |
#include <gdk/gdkkeysyms.h>
|
leo_sobral@1
|
4 |
|
leo_sobral@1
|
5 |
#include "mmyth_uicommon.h"
|
leo_sobral@1
|
6 |
#include "mmyth_epg_grid_widget.h"
|
leo_sobral@1
|
7 |
|
leo_sobral@1
|
8 |
#include "gmyth_util.h"
|
leo_sobral@1
|
9 |
#include "gmyth_epg.h"
|
leo_sobral@1
|
10 |
|
leo_sobral@1
|
11 |
#define PIXELS_HOUR 105
|
leo_sobral@1
|
12 |
#define PROGRAM_SEPARATION 2
|
leo_sobral@1
|
13 |
|
leo_sobral@1
|
14 |
enum {
|
leo_sobral@1
|
15 |
SELECTION_UPDATED_SIGNAL,
|
leo_sobral@1
|
16 |
LAST_SIGNAL
|
leo_sobral@1
|
17 |
};
|
leo_sobral@1
|
18 |
|
leo_sobral@1
|
19 |
struct _MMythEpgGridWidgetPrivate {
|
leo_sobral@1
|
20 |
/* private widget components */
|
leo_sobral@1
|
21 |
GtkWidget *epg_channels_vbox;
|
leo_sobral@1
|
22 |
GtkWidget *epg_programs_vbox;
|
leo_sobral@1
|
23 |
|
leo_sobral@1
|
24 |
GHashTable *service_model_hash;
|
leo_sobral@1
|
25 |
|
leo_sobral@1
|
26 |
/* guidegrid attributes */
|
leo_sobral@1
|
27 |
gboolean show_favorites;
|
leo_sobral@1
|
28 |
gint current_start_channel_id;
|
leo_sobral@1
|
29 |
|
leo_sobral@1
|
30 |
time_t current_start_time;
|
leo_sobral@1
|
31 |
time_t current_end_time;
|
leo_sobral@1
|
32 |
|
leo_sobral@1
|
33 |
guint selected_channel_index;
|
leo_sobral@1
|
34 |
|
leo_sobral@1
|
35 |
/* GList of ProgramInfo for each Channel */
|
leo_sobral@1
|
36 |
GList * program_list[MAX_DISPLAY_CHANS];
|
leo_sobral@1
|
37 |
GList * channel_list;
|
leo_sobral@1
|
38 |
|
leo_sobral@1
|
39 |
GMythEPG *mmyth_epg;
|
leo_sobral@1
|
40 |
|
leo_sobral@1
|
41 |
gint DISPLAY_CHANS;
|
leo_sobral@1
|
42 |
};
|
leo_sobral@1
|
43 |
|
leo_sobral@1
|
44 |
static void mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass);
|
leo_sobral@1
|
45 |
static void mmyth_epg_grid_widget_init (MMythEpgGridWidget *object);
|
leo_sobral@1
|
46 |
static void mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private);
|
leo_sobral@1
|
47 |
static void mmyth_epg_grid_widget_mount_services (MMythEpgGridWidget *object,
|
leo_sobral@1
|
48 |
int start_time, int end_time);
|
leo_sobral@1
|
49 |
static void mmyth_epg_grid_widget_mount_header (MMythEpgGridWidget *object);
|
leo_sobral@1
|
50 |
static void mmyth_epg_grid_widget_clicked (GtkWidget* widget,
|
leo_sobral@1
|
51 |
GdkEventExpose *event,
|
leo_sobral@1
|
52 |
gpointer data);
|
leo_sobral@1
|
53 |
static GtkWidget *create_event_box_lbl (gchar *str, int width,
|
leo_sobral@1
|
54 |
const GdkColor *bg_color,
|
leo_sobral@1
|
55 |
const GdkColor *fg_color);
|
leo_sobral@1
|
56 |
|
leo_sobral@1
|
57 |
static void mmyth_epg_grid_widget_fill_programinfos(MMythEpgGridWidgetPrivate *private);
|
leo_sobral@1
|
58 |
static void mmyth_epg_grid_widget_fill_program_row_infos(
|
leo_sobral@1
|
59 |
MMythEpgGridWidgetPrivate *private,
|
leo_sobral@1
|
60 |
unsigned int chanNum, unsigned int row);
|
leo_sobral@1
|
61 |
|
leo_sobral@1
|
62 |
static gint mmyth_epg_grid_widget_signals[LAST_SIGNAL] = { 0 };
|
leo_sobral@1
|
63 |
|
leo_sobral@1
|
64 |
G_DEFINE_TYPE(MMythEpgGridWidget, mmyth_epg_grid_widget, GTK_TYPE_EVENT_BOX)
|
leo_sobral@1
|
65 |
|
leo_sobral@1
|
66 |
static void
|
leo_sobral@1
|
67 |
mmyth_epg_grid_widget_class_init (MMythEpgGridWidgetClass *klass)
|
leo_sobral@1
|
68 |
{
|
leo_sobral@1
|
69 |
g_type_class_add_private (klass, sizeof (MMythEpgGridWidgetPrivate));
|
leo_sobral@1
|
70 |
|
leo_sobral@1
|
71 |
mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL] = g_signal_new (
|
leo_sobral@1
|
72 |
"selection_updated",
|
leo_sobral@1
|
73 |
G_TYPE_FROM_CLASS(klass),
|
leo_sobral@1
|
74 |
G_SIGNAL_RUN_FIRST,
|
leo_sobral@1
|
75 |
0,
|
leo_sobral@1
|
76 |
NULL,
|
leo_sobral@1
|
77 |
NULL,
|
leo_sobral@1
|
78 |
g_cclosure_marshal_VOID__POINTER,
|
leo_sobral@1
|
79 |
G_TYPE_NONE,
|
leo_sobral@1
|
80 |
1,
|
leo_sobral@1
|
81 |
G_TYPE_POINTER);
|
leo_sobral@1
|
82 |
}
|
leo_sobral@1
|
83 |
|
leo_sobral@1
|
84 |
static void
|
leo_sobral@1
|
85 |
mmyth_epg_grid_widget_private_init (MMythEpgGridWidgetPrivate *private)
|
leo_sobral@1
|
86 |
{
|
leo_sobral@1
|
87 |
time_t cur_time;
|
leo_sobral@1
|
88 |
|
leo_sobral@1
|
89 |
g_return_if_fail(private != NULL);
|
leo_sobral@1
|
90 |
|
leo_sobral@1
|
91 |
private->epg_channels_vbox = NULL;
|
leo_sobral@1
|
92 |
private->epg_programs_vbox = NULL;
|
leo_sobral@1
|
93 |
private->service_model_hash = NULL;
|
leo_sobral@1
|
94 |
|
leo_sobral@1
|
95 |
private->show_favorites = FALSE;
|
leo_sobral@1
|
96 |
private->current_start_channel_id = -1;
|
leo_sobral@1
|
97 |
|
leo_sobral@1
|
98 |
/* Selected the first diplayable channel initially */
|
leo_sobral@1
|
99 |
private->selected_channel_index = 0;
|
leo_sobral@1
|
100 |
|
leo_sobral@1
|
101 |
/* TODO fix the current start/end time */
|
leo_sobral@1
|
102 |
private->current_start_time = time(&cur_time);
|
leo_sobral@1
|
103 |
private->current_end_time = time(&cur_time) + 10800;
|
leo_sobral@1
|
104 |
|
leo_sobral@1
|
105 |
private->DISPLAY_CHANS = MAX_DISPLAY_CHANS;
|
leo_sobral@1
|
106 |
|
leo_sobral@1
|
107 |
// TODO: Close the epg and unref it in dispose call
|
leo_sobral@1
|
108 |
private->mmyth_epg = gmyth_epg_new ();
|
leo_sobral@1
|
109 |
if (!gmyth_epg_connect (private->mmyth_epg)) {
|
leo_sobral@1
|
110 |
g_warning ("[%s] Could not connect mysql handler to db", __FUNCTION__);
|
leo_sobral@1
|
111 |
g_object_unref (private->mmyth_epg);
|
leo_sobral@1
|
112 |
private->mmyth_epg = NULL;
|
leo_sobral@1
|
113 |
}
|
leo_sobral@1
|
114 |
}
|
leo_sobral@1
|
115 |
|
leo_sobral@1
|
116 |
static void
|
leo_sobral@1
|
117 |
mmyth_epg_grid_widget_init (MMythEpgGridWidget *mmyth_epg_grid_widget)
|
leo_sobral@1
|
118 |
{
|
leo_sobral@1
|
119 |
MMythEpgGridWidgetPrivate *private =
|
leo_sobral@1
|
120 |
MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
|
leo_sobral@1
|
121 |
|
leo_sobral@1
|
122 |
/* init private fields */
|
leo_sobral@1
|
123 |
mmyth_epg_grid_widget_private_init(private);
|
leo_sobral@1
|
124 |
|
leo_sobral@1
|
125 |
mmyth_epg_grid_widget->epg_view_model = NULL;
|
leo_sobral@1
|
126 |
mmyth_epg_grid_widget->selected_grid_item = NULL;
|
leo_sobral@1
|
127 |
|
leo_sobral@1
|
128 |
GtkWidget *epg_event_box = GTK_WIDGET(mmyth_epg_grid_widget);
|
leo_sobral@1
|
129 |
gtk_widget_modify_bg(epg_event_box, GTK_STATE_NORMAL, &main_bg_color);
|
leo_sobral@1
|
130 |
gtk_widget_set_size_request (epg_event_box, 0, 125);
|
leo_sobral@1
|
131 |
|
leo_sobral@1
|
132 |
GtkWidget *epg_main_hbox = gtk_hbox_new (FALSE, 10);
|
leo_sobral@1
|
133 |
gtk_container_set_border_width(GTK_CONTAINER (epg_main_hbox), 10);
|
leo_sobral@1
|
134 |
|
leo_sobral@1
|
135 |
gtk_container_add (GTK_CONTAINER (epg_event_box),
|
leo_sobral@1
|
136 |
epg_main_hbox);
|
leo_sobral@1
|
137 |
|
leo_sobral@1
|
138 |
/* channels vbox */
|
leo_sobral@1
|
139 |
GtkWidget *epg_channels_vbox = gtk_vbox_new (FALSE, 3);
|
leo_sobral@1
|
140 |
private->epg_channels_vbox = epg_channels_vbox;
|
leo_sobral@1
|
141 |
|
leo_sobral@1
|
142 |
/* programs vbox */
|
leo_sobral@1
|
143 |
GtkWidget *epg_programs_vbox = gtk_vbox_new (FALSE, 3);
|
leo_sobral@1
|
144 |
private->epg_programs_vbox = epg_programs_vbox;
|
leo_sobral@1
|
145 |
|
leo_sobral@1
|
146 |
/* packing start */
|
leo_sobral@1
|
147 |
gtk_box_pack_start (GTK_BOX (epg_main_hbox),
|
leo_sobral@1
|
148 |
epg_channels_vbox, FALSE, FALSE, 0);
|
leo_sobral@1
|
149 |
gtk_box_pack_start (GTK_BOX (epg_main_hbox),
|
leo_sobral@1
|
150 |
epg_programs_vbox, FALSE, FALSE, 0);
|
leo_sobral@1
|
151 |
|
leo_sobral@1
|
152 |
/* table header (first line) */
|
leo_sobral@1
|
153 |
mmyth_epg_grid_widget_mount_header(mmyth_epg_grid_widget);
|
leo_sobral@1
|
154 |
|
leo_sobral@1
|
155 |
/* service programs */
|
leo_sobral@1
|
156 |
/* mount service programs with current time */
|
leo_sobral@1
|
157 |
mmyth_epg_grid_widget_mount_services(mmyth_epg_grid_widget,
|
leo_sobral@1
|
158 |
private->current_start_time,
|
leo_sobral@1
|
159 |
private->current_end_time);
|
leo_sobral@1
|
160 |
}
|
leo_sobral@1
|
161 |
|
leo_sobral@1
|
162 |
GtkWidget*
|
leo_sobral@1
|
163 |
mmyth_epg_grid_widget_new ()
|
leo_sobral@1
|
164 |
{
|
leo_sobral@1
|
165 |
return GTK_WIDGET ( gtk_type_new (mmyth_epg_grid_widget_get_type ()));
|
leo_sobral@1
|
166 |
}
|
leo_sobral@1
|
167 |
|
leo_sobral@1
|
168 |
static void
|
leo_sobral@1
|
169 |
mmyth_epg_grid_widget_mount_services(MMythEpgGridWidget *mmyth_epg_grid_widget,
|
leo_sobral@1
|
170 |
int start_time, int end_time)
|
leo_sobral@1
|
171 |
{
|
leo_sobral@1
|
172 |
GList *proglist;
|
leo_sobral@1
|
173 |
GList *channel_list = NULL;
|
leo_sobral@1
|
174 |
GMythChannelInfo *channel_info;
|
leo_sobral@1
|
175 |
|
leo_sobral@1
|
176 |
int chanid;
|
leo_sobral@1
|
177 |
MMythEpgGridWidgetPrivate *private =
|
leo_sobral@1
|
178 |
MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
|
leo_sobral@1
|
179 |
|
leo_sobral@1
|
180 |
// update view_model
|
leo_sobral@1
|
181 |
/* FIXME shallow free or recursive? */
|
leo_sobral@1
|
182 |
if(mmyth_epg_grid_widget->epg_view_model != NULL) {
|
leo_sobral@1
|
183 |
g_list_free(mmyth_epg_grid_widget->epg_view_model);
|
leo_sobral@1
|
184 |
mmyth_epg_grid_widget->epg_view_model = NULL;
|
leo_sobral@1
|
185 |
}
|
leo_sobral@1
|
186 |
|
leo_sobral@1
|
187 |
if(private->service_model_hash != NULL) {
|
leo_sobral@1
|
188 |
g_hash_table_destroy(private->service_model_hash);
|
leo_sobral@1
|
189 |
}
|
leo_sobral@1
|
190 |
|
leo_sobral@1
|
191 |
private->service_model_hash = g_hash_table_new(NULL, NULL);
|
leo_sobral@1
|
192 |
|
leo_sobral@1
|
193 |
/* fill program infos from db */
|
leo_sobral@1
|
194 |
mmyth_epg_grid_widget_fill_programinfos(private);
|
leo_sobral@1
|
195 |
|
leo_sobral@1
|
196 |
channel_list = private->channel_list;
|
leo_sobral@1
|
197 |
|
leo_sobral@1
|
198 |
/* for each channel get_programs() */
|
leo_sobral@1
|
199 |
for (chanid=0; channel_list &&
|
leo_sobral@1
|
200 |
chanid < private->DISPLAY_CHANS; chanid++) {
|
leo_sobral@1
|
201 |
proglist = (GList *) private->program_list[chanid];
|
leo_sobral@1
|
202 |
|
leo_sobral@1
|
203 |
channel_info = (GMythChannelInfo *) channel_list->data;
|
leo_sobral@1
|
204 |
channel_list = g_list_next(channel_list);
|
leo_sobral@1
|
205 |
|
leo_sobral@1
|
206 |
/* Service Title*/
|
leo_sobral@1
|
207 |
GString *name = NULL;
|
leo_sobral@1
|
208 |
if (channel_info->channel_name)
|
leo_sobral@1
|
209 |
name = g_string_new (channel_info->channel_name->str);
|
leo_sobral@1
|
210 |
|
leo_sobral@1
|
211 |
GdkColor title_bg_color;
|
leo_sobral@1
|
212 |
title_bg_color.red = 5000;
|
leo_sobral@1
|
213 |
title_bg_color.green = 9000;
|
leo_sobral@1
|
214 |
title_bg_color.blue = 40000;
|
leo_sobral@1
|
215 |
|
leo_sobral@1
|
216 |
GdkColor title_fg_color;
|
leo_sobral@1
|
217 |
title_fg_color.red = 60000;
|
leo_sobral@1
|
218 |
title_fg_color.green = 60000;
|
leo_sobral@1
|
219 |
title_fg_color.blue = 60000;
|
leo_sobral@1
|
220 |
|
leo_sobral@1
|
221 |
GtkWidget *event_box_channel = create_event_box_lbl(
|
leo_sobral@1
|
222 |
name->str, 90,
|
leo_sobral@1
|
223 |
&title_bg_color,
|
leo_sobral@1
|
224 |
&title_fg_color);
|
leo_sobral@1
|
225 |
|
leo_sobral@1
|
226 |
gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
|
leo_sobral@1
|
227 |
event_box_channel, FALSE, FALSE, 0);
|
leo_sobral@1
|
228 |
|
leo_sobral@1
|
229 |
GtkWidget *epg_line_hbox = gtk_hbox_new (FALSE, 0);
|
leo_sobral@1
|
230 |
|
leo_sobral@1
|
231 |
GdkColor bg_color;
|
leo_sobral@1
|
232 |
bg_color.red = 5000;
|
leo_sobral@1
|
233 |
bg_color.green = 30000;
|
leo_sobral@1
|
234 |
bg_color.blue = 60000;
|
leo_sobral@1
|
235 |
|
leo_sobral@1
|
236 |
GdkColor fg_color;
|
leo_sobral@1
|
237 |
fg_color.red = 60000;
|
leo_sobral@1
|
238 |
fg_color.green = 60000;
|
leo_sobral@1
|
239 |
fg_color.blue = 60000;
|
leo_sobral@1
|
240 |
|
leo_sobral@1
|
241 |
/* Content parsing */
|
leo_sobral@1
|
242 |
GList *epg_grid_list = NULL;
|
leo_sobral@1
|
243 |
|
leo_sobral@1
|
244 |
GMythProgramInfo *proginfo;
|
leo_sobral@1
|
245 |
int pixel_count = 0;
|
leo_sobral@1
|
246 |
for (; proglist; proglist = proglist->next) {
|
leo_sobral@1
|
247 |
proginfo = (GMythProgramInfo *) proglist->data;
|
leo_sobral@1
|
248 |
|
leo_sobral@1
|
249 |
GString *content_name = proginfo->title;
|
leo_sobral@1
|
250 |
|
leo_sobral@1
|
251 |
int initial_time, last_time, duration;
|
leo_sobral@1
|
252 |
|
leo_sobral@1
|
253 |
int schedule_start_time = proginfo->startts;
|
leo_sobral@1
|
254 |
int schedule_end_time = proginfo->endts;
|
leo_sobral@1
|
255 |
|
leo_sobral@1
|
256 |
initial_time =
|
leo_sobral@1
|
257 |
(schedule_start_time < start_time) ? start_time : schedule_start_time;
|
leo_sobral@1
|
258 |
last_time = (schedule_end_time > end_time) ? end_time : schedule_end_time;
|
leo_sobral@1
|
259 |
duration = last_time - initial_time;
|
leo_sobral@1
|
260 |
|
leo_sobral@1
|
261 |
// Verify program time
|
leo_sobral@1
|
262 |
#if 0
|
leo_sobral@1
|
263 |
g_debug ("ServiceID: %d, ScheduleID: %d\n", service->id, schedule->id);
|
leo_sobral@1
|
264 |
fprintf (stderr, "program time\nfrom = %d, to = %d\n",
|
leo_sobral@1
|
265 |
schedule->validFrom, schedule->validTo);
|
leo_sobral@1
|
266 |
|
leo_sobral@1
|
267 |
struct tm loctime;
|
leo_sobral@1
|
268 |
|
leo_sobral@1
|
269 |
/* Convert it to local time representation. */
|
leo_sobral@1
|
270 |
if (localtime_r((time_t *)&schedule->validFrom, &loctime) == NULL) {
|
leo_sobral@1
|
271 |
g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
|
leo_sobral@1
|
272 |
return NULL;
|
leo_sobral@1
|
273 |
}
|
leo_sobral@1
|
274 |
fprintf (stderr, asctime (&loctime));
|
leo_sobral@1
|
275 |
|
leo_sobral@1
|
276 |
if (localtime_r((time_t *)&schedule->validTo, &loctime) == NULL) {
|
leo_sobral@1
|
277 |
g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
|
leo_sobral@1
|
278 |
return NULL;
|
leo_sobral@1
|
279 |
}
|
leo_sobral@1
|
280 |
fprintf (stderr, asctime (&loctime));
|
leo_sobral@1
|
281 |
#endif
|
leo_sobral@1
|
282 |
|
leo_sobral@1
|
283 |
/* fprintf(stderr, "duration = %d\n", duration); */
|
leo_sobral@1
|
284 |
double duration_hour = duration / (double) 3600.0;
|
leo_sobral@1
|
285 |
/* fprintf(stderr, "duration_hour = %lf\n", duration_hour); */
|
leo_sobral@1
|
286 |
|
leo_sobral@1
|
287 |
int size = PIXELS_HOUR * duration_hour;
|
leo_sobral@1
|
288 |
|
leo_sobral@1
|
289 |
/* complete hour */
|
leo_sobral@1
|
290 |
/* FIXME: UGLY WRONG HACK TO ALIGN PROGRAM TIME!!!*/
|
leo_sobral@1
|
291 |
if(last_time%3600 != 0) {
|
leo_sobral@1
|
292 |
size -= PROGRAM_SEPARATION;
|
leo_sobral@1
|
293 |
}
|
leo_sobral@1
|
294 |
if(initial_time%3600 != 0) {
|
leo_sobral@1
|
295 |
size -= PROGRAM_SEPARATION;
|
leo_sobral@1
|
296 |
}
|
leo_sobral@1
|
297 |
|
leo_sobral@1
|
298 |
pixel_count += size + PROGRAM_SEPARATION;
|
leo_sobral@1
|
299 |
GtkWidget *event_box = create_event_box_lbl(content_name->str,
|
leo_sobral@1
|
300 |
size, &bg_color,
|
leo_sobral@1
|
301 |
&fg_color);
|
leo_sobral@1
|
302 |
gtk_widget_add_events(event_box,
|
leo_sobral@1
|
303 |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
|
leo_sobral@1
|
304 |
|
leo_sobral@1
|
305 |
/* create EpgGridItem */
|
leo_sobral@1
|
306 |
EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
|
leo_sobral@1
|
307 |
epg_grid_item->proginfo = proginfo;
|
leo_sobral@1
|
308 |
epg_grid_item->event_box = event_box;
|
leo_sobral@1
|
309 |
epg_grid_item->object = mmyth_epg_grid_widget;
|
leo_sobral@1
|
310 |
|
leo_sobral@1
|
311 |
epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
|
leo_sobral@1
|
312 |
|
leo_sobral@1
|
313 |
gtk_box_pack_start (GTK_BOX (epg_line_hbox),
|
leo_sobral@1
|
314 |
event_box, FALSE, FALSE, PROGRAM_SEPARATION);
|
leo_sobral@1
|
315 |
|
leo_sobral@1
|
316 |
g_signal_connect (G_OBJECT (event_box), "button-press-event",
|
leo_sobral@1
|
317 |
G_CALLBACK (mmyth_epg_grid_widget_clicked),
|
leo_sobral@1
|
318 |
(gpointer*) epg_grid_list);
|
leo_sobral@1
|
319 |
}
|
leo_sobral@1
|
320 |
#if 0
|
leo_sobral@1
|
321 |
printf("chaind = %d!!!!" chanid);fflush(stdout);
|
leo_sobral@1
|
322 |
#endif
|
leo_sobral@1
|
323 |
|
leo_sobral@1
|
324 |
if(!epg_grid_list) {
|
leo_sobral@1
|
325 |
/* No programs for current channel */
|
leo_sobral@1
|
326 |
/* FIXME: size HARDCODED */
|
leo_sobral@1
|
327 |
GtkWidget *event_box = create_event_box_lbl("No program list available",
|
leo_sobral@1
|
328 |
PIXELS_HOUR * 3, &bg_color,
|
leo_sobral@1
|
329 |
&fg_color);
|
leo_sobral@1
|
330 |
gtk_widget_add_events(event_box,
|
leo_sobral@1
|
331 |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
|
leo_sobral@1
|
332 |
|
leo_sobral@1
|
333 |
/* create EpgGridItem */
|
leo_sobral@1
|
334 |
EpgGridItem *epg_grid_item = g_new(EpgGridItem, 1);
|
leo_sobral@1
|
335 |
epg_grid_item->proginfo = NULL;
|
leo_sobral@1
|
336 |
epg_grid_item->event_box = event_box;
|
leo_sobral@1
|
337 |
epg_grid_item->object = mmyth_epg_grid_widget;
|
leo_sobral@1
|
338 |
|
leo_sobral@1
|
339 |
epg_grid_list = g_list_prepend(epg_grid_list, (gpointer) epg_grid_item);
|
leo_sobral@1
|
340 |
|
leo_sobral@1
|
341 |
gtk_box_pack_start (GTK_BOX (epg_line_hbox),
|
leo_sobral@1
|
342 |
event_box, FALSE, FALSE, PROGRAM_SEPARATION);
|
leo_sobral@1
|
343 |
|
leo_sobral@1
|
344 |
g_signal_connect (G_OBJECT (event_box), "button-press-event",
|
leo_sobral@1
|
345 |
G_CALLBACK (mmyth_epg_grid_widget_clicked),
|
leo_sobral@1
|
346 |
(gpointer*) epg_grid_list);
|
leo_sobral@1
|
347 |
}
|
leo_sobral@1
|
348 |
|
leo_sobral@1
|
349 |
epg_grid_list = g_list_reverse(epg_grid_list);
|
leo_sobral@1
|
350 |
mmyth_epg_grid_widget->epg_view_model =
|
leo_sobral@1
|
351 |
g_list_append(mmyth_epg_grid_widget->epg_view_model, epg_grid_list);
|
leo_sobral@1
|
352 |
|
leo_sobral@1
|
353 |
gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
|
leo_sobral@1
|
354 |
epg_line_hbox, FALSE, FALSE, 0);
|
leo_sobral@1
|
355 |
}
|
leo_sobral@1
|
356 |
}
|
leo_sobral@1
|
357 |
|
leo_sobral@1
|
358 |
static void
|
leo_sobral@1
|
359 |
mmyth_epg_grid_widget_mount_header(MMythEpgGridWidget *mmyth_epg_grid_widget)
|
leo_sobral@1
|
360 |
{
|
leo_sobral@1
|
361 |
MMythEpgGridWidgetPrivate *private =
|
leo_sobral@1
|
362 |
MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(mmyth_epg_grid_widget);
|
leo_sobral@1
|
363 |
|
leo_sobral@1
|
364 |
struct tm hour_tm;
|
leo_sobral@1
|
365 |
const gchar name_title[] = "Today";
|
leo_sobral@1
|
366 |
GtkWidget * lbl_title = gtk_label_new(name_title);
|
leo_sobral@1
|
367 |
|
leo_sobral@1
|
368 |
gtk_misc_set_alignment (GTK_MISC(lbl_title), 0.0, 0.5);
|
leo_sobral@1
|
369 |
|
leo_sobral@1
|
370 |
gtk_box_pack_start (GTK_BOX (private->epg_channels_vbox),
|
leo_sobral@1
|
371 |
lbl_title, FALSE, FALSE, 0);
|
leo_sobral@1
|
372 |
|
leo_sobral@1
|
373 |
/* hours title line */
|
leo_sobral@1
|
374 |
GtkWidget *epg_programs_hours_hbox = gtk_hbox_new (TRUE, 0);
|
leo_sobral@1
|
375 |
|
leo_sobral@1
|
376 |
if (localtime_r((time_t *)&private->current_start_time, &hour_tm) == NULL) {
|
leo_sobral@1
|
377 |
g_warning ("localtime_r error in mmyth_epg_grid_widget!\n");
|
leo_sobral@1
|
378 |
return NULL;
|
leo_sobral@1
|
379 |
}
|
leo_sobral@1
|
380 |
|
leo_sobral@1
|
381 |
if (hour_tm.tm_min>30) {
|
leo_sobral@1
|
382 |
hour_tm.tm_min = 30;
|
leo_sobral@1
|
383 |
} else if (hour_tm.tm_min>0) {
|
leo_sobral@1
|
384 |
hour_tm.tm_min = 0;
|
leo_sobral@1
|
385 |
}
|
leo_sobral@1
|
386 |
|
leo_sobral@1
|
387 |
gchar hour1_str[10];
|
leo_sobral@1
|
388 |
strftime(hour1_str, 8, "%H:%M", &hour_tm);
|
leo_sobral@1
|
389 |
GtkWidget * lbl_hour1 = gtk_label_new(hour1_str);
|
leo_sobral@1
|
390 |
gtk_misc_set_alignment (GTK_MISC(lbl_hour1), 0.0, 0.5);
|
leo_sobral@1
|
391 |
|
leo_sobral@1
|
392 |
hour_tm.tm_hour++;
|
leo_sobral@1
|
393 |
gchar hour2_str[10];
|
leo_sobral@1
|
394 |
strftime(hour2_str, 8, "%H:%M", &hour_tm);
|
leo_sobral@1
|
395 |
GtkWidget * lbl_hour2 = gtk_label_new(hour2_str);
|
leo_sobral@1
|
396 |
gtk_misc_set_alignment (GTK_MISC(lbl_hour2), 0.0, 0.5);
|
leo_sobral@1
|
397 |
|
leo_sobral@1
|
398 |
hour_tm.tm_hour++;
|
leo_sobral@1
|
399 |
gchar hour3_str[10];
|
leo_sobral@1
|
400 |
strftime(hour3_str, 8, "%H:%M", &hour_tm);
|
leo_sobral@1
|
401 |
GtkWidget * lbl_hour3 = gtk_label_new(hour3_str);
|
leo_sobral@1
|
402 |
gtk_misc_set_alignment (GTK_MISC(lbl_hour3), 0.0, 0.5);
|
leo_sobral@1
|
403 |
|
leo_sobral@1
|
404 |
gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
|
leo_sobral@1
|
405 |
lbl_hour1, TRUE, TRUE, 0);
|
leo_sobral@1
|
406 |
gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
|
leo_sobral@1
|
407 |
lbl_hour2, TRUE, TRUE, 0);
|
leo_sobral@1
|
408 |
gtk_box_pack_start (GTK_BOX (epg_programs_hours_hbox),
|
leo_sobral@1
|
409 |
lbl_hour3, TRUE, TRUE, 0);
|
leo_sobral@1
|
410 |
|
leo_sobral@1
|
411 |
gtk_box_pack_start (GTK_BOX (private->epg_programs_vbox),
|
leo_sobral@1
|
412 |
epg_programs_hours_hbox, FALSE, FALSE, 0);
|
leo_sobral@1
|
413 |
}
|
leo_sobral@1
|
414 |
|
leo_sobral@1
|
415 |
/******************************************************************************
|
leo_sobral@1
|
416 |
* INTERNAL CALLBACKS FOR STATE CHANGE *
|
leo_sobral@1
|
417 |
*****************************************************************************/
|
leo_sobral@1
|
418 |
static void
|
leo_sobral@1
|
419 |
mmyth_epg_grid_widget_deselect_service(MMythEpgGridWidget *mmyth_epg_grid_widget)
|
leo_sobral@1
|
420 |
{
|
leo_sobral@1
|
421 |
EpgGridItem *epg_grid_item;
|
leo_sobral@1
|
422 |
|
leo_sobral@1
|
423 |
/* deselect*/
|
leo_sobral@1
|
424 |
if(mmyth_epg_grid_widget->selected_grid_item != NULL) {
|
leo_sobral@1
|
425 |
epg_grid_item =
|
leo_sobral@1
|
426 |
(EpgGridItem*) mmyth_epg_grid_widget->selected_grid_item->data;
|
leo_sobral@1
|
427 |
gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_NORMAL);
|
leo_sobral@1
|
428 |
}
|
leo_sobral@1
|
429 |
}
|
leo_sobral@1
|
430 |
|
leo_sobral@1
|
431 |
static void
|
leo_sobral@1
|
432 |
mmyth_epg_grid_widget_clicked (GtkWidget* widget,
|
leo_sobral@1
|
433 |
GdkEventExpose *event, gpointer data)
|
leo_sobral@1
|
434 |
{
|
leo_sobral@1
|
435 |
g_return_if_fail(data != NULL);
|
leo_sobral@1
|
436 |
|
leo_sobral@1
|
437 |
GList *epg_grid_item_list = (GList *) data;
|
leo_sobral@1
|
438 |
EpgGridItem *epg_grid_item = (EpgGridItem *) epg_grid_item_list->data;
|
leo_sobral@1
|
439 |
|
leo_sobral@1
|
440 |
/* update the selected service */
|
leo_sobral@1
|
441 |
mmyth_epg_grid_widget_update_service( epg_grid_item->object, (GList*) data );
|
leo_sobral@1
|
442 |
}
|
leo_sobral@1
|
443 |
|
leo_sobral@1
|
444 |
void
|
leo_sobral@1
|
445 |
mmyth_epg_grid_widget_update_service(MMythEpgGridWidget * object,
|
leo_sobral@1
|
446 |
GList *selected_grid_list)
|
leo_sobral@1
|
447 |
{
|
leo_sobral@1
|
448 |
g_return_if_fail(object != NULL);
|
leo_sobral@1
|
449 |
g_return_if_fail(selected_grid_list != NULL);
|
leo_sobral@1
|
450 |
|
leo_sobral@1
|
451 |
EpgGridItem *epg_grid_item = (EpgGridItem *) selected_grid_list->data;
|
leo_sobral@1
|
452 |
|
leo_sobral@1
|
453 |
mmyth_epg_grid_widget_deselect_service(epg_grid_item->object);
|
leo_sobral@1
|
454 |
|
leo_sobral@1
|
455 |
/* updating current selected schedule_item and schedule_list*/
|
leo_sobral@1
|
456 |
object->selected_grid_item = selected_grid_list;
|
leo_sobral@1
|
457 |
|
leo_sobral@1
|
458 |
/* set state of the event box */
|
leo_sobral@1
|
459 |
gtk_widget_set_state(GTK_WIDGET(epg_grid_item->event_box), GTK_STATE_SELECTED);
|
leo_sobral@1
|
460 |
/* emit update signal for listeners */
|
leo_sobral@1
|
461 |
g_signal_emit(object,
|
leo_sobral@1
|
462 |
mmyth_epg_grid_widget_signals[SELECTION_UPDATED_SIGNAL],
|
leo_sobral@1
|
463 |
0,
|
leo_sobral@1
|
464 |
(gpointer) epg_grid_item);
|
leo_sobral@1
|
465 |
}
|
leo_sobral@1
|
466 |
|
leo_sobral@1
|
467 |
static GtkWidget *
|
leo_sobral@1
|
468 |
create_event_box_lbl(gchar *str, int width, const GdkColor *bg_color,
|
leo_sobral@1
|
469 |
const GdkColor *fg_color)
|
leo_sobral@1
|
470 |
{
|
leo_sobral@1
|
471 |
GtkWidget *event_box = gtk_event_box_new();
|
leo_sobral@1
|
472 |
GtkWidget *lbl = gtk_label_new(str);
|
leo_sobral@1
|
473 |
gtk_label_set_ellipsize(GTK_LABEL(lbl), PANGO_ELLIPSIZE_END);
|
leo_sobral@1
|
474 |
|
leo_sobral@1
|
475 |
gtk_widget_modify_bg(event_box, GTK_STATE_NORMAL, bg_color);
|
leo_sobral@1
|
476 |
gtk_widget_modify_fg(lbl, GTK_STATE_NORMAL, fg_color);
|
leo_sobral@1
|
477 |
|
leo_sobral@1
|
478 |
/* selected colors are const*/
|
leo_sobral@1
|
479 |
GdkColor selected_bg_color;
|
leo_sobral@1
|
480 |
selected_bg_color.red = 100;
|
leo_sobral@1
|
481 |
selected_bg_color.green = 40000;
|
leo_sobral@1
|
482 |
selected_bg_color.blue = 100;
|
leo_sobral@1
|
483 |
|
leo_sobral@1
|
484 |
GdkColor selected_fg_color;
|
leo_sobral@1
|
485 |
selected_fg_color.red = 100;
|
leo_sobral@1
|
486 |
selected_fg_color.green = 100;
|
leo_sobral@1
|
487 |
selected_fg_color.blue = 100;
|
leo_sobral@1
|
488 |
|
leo_sobral@1
|
489 |
gtk_widget_modify_bg(event_box, GTK_STATE_SELECTED, &selected_bg_color);
|
leo_sobral@1
|
490 |
gtk_widget_modify_fg(lbl, GTK_STATE_SELECTED, &selected_fg_color);
|
leo_sobral@1
|
491 |
|
leo_sobral@1
|
492 |
gtk_misc_set_alignment (GTK_MISC(lbl), 0.0, 0.5);
|
leo_sobral@1
|
493 |
gtk_container_add (GTK_CONTAINER (event_box),
|
leo_sobral@1
|
494 |
lbl);
|
leo_sobral@1
|
495 |
gtk_widget_set_size_request(event_box, width, -1);
|
leo_sobral@1
|
496 |
|
leo_sobral@1
|
497 |
return event_box;
|
leo_sobral@1
|
498 |
}
|
leo_sobral@1
|
499 |
|
leo_sobral@1
|
500 |
/******************************************************************************
|
leo_sobral@1
|
501 |
* METHODS *
|
leo_sobral@1
|
502 |
*****************************************************************************/
|
leo_sobral@1
|
503 |
|
leo_sobral@1
|
504 |
/* Callback for hardware keys */
|
leo_sobral@1
|
505 |
gboolean
|
leo_sobral@1
|
506 |
mmyth_epg_grid_widget_key_press (MMythEpgGridWidget * object,
|
leo_sobral@1
|
507 |
GtkWidget * widget, GdkEventKey * event)
|
leo_sobral@1
|
508 |
{
|
leo_sobral@1
|
509 |
MMythEpgGridWidgetPrivate *private =
|
leo_sobral@1
|
510 |
MMYTH_EPG_GRID_WIDGET_GET_PRIVATE(object);
|
leo_sobral@1
|
511 |
|
leo_sobral@1
|
512 |
EpgGridItem *epg_grid_item;
|
leo_sobral@1
|
513 |
GList *tmp;
|
leo_sobral@1
|
514 |
|
leo_sobral@1
|
515 |
/* List of selected_grid_item */
|
leo_sobral@1
|
516 |
GList *selected_view_model;
|
leo_sobral@1
|
517 |
|
leo_sobral@1
|
518 |
gint channel_index;
|
leo_sobral@1
|
519 |
|
leo_sobral@1
|
520 |
if(object->selected_grid_item == NULL) {
|
leo_sobral@1
|
521 |
g_warning ("No program selected");
|
leo_sobral@1
|
522 |
return FALSE;
|
leo_sobral@1
|
523 |
}
|
leo_sobral@1
|
524 |
|
leo_sobral@1
|
525 |
epg_grid_item = (EpgGridItem*) object->selected_grid_item->data;
|
leo_sobral@1
|
526 |
|
leo_sobral@1
|
527 |
channel_index = private->selected_channel_index;
|
leo_sobral@1
|
528 |
|
leo_sobral@1
|
529 |
switch (event->keyval) {
|
leo_sobral@1
|
530 |
case GDK_Up:
|
leo_sobral@1
|
531 |
selected_view_model = g_list_nth( object->epg_view_model, channel_index - 1 );
|
leo_sobral@1
|
532 |
if(selected_view_model != NULL) {
|
leo_sobral@1
|
533 |
private->selected_channel_index = channel_index - 1;
|
leo_sobral@1
|
534 |
tmp = (GList *) selected_view_model->data;
|
leo_sobral@1
|
535 |
/* TODO: select a better centralized item
|
leo_sobral@1
|
536 |
currently is picking the 1st or last item */
|
leo_sobral@1
|
537 |
if(g_list_next(object->selected_grid_item) == NULL &&
|
leo_sobral@1
|
538 |
g_list_previous(object->selected_grid_item) != NULL) {
|
leo_sobral@1
|
539 |
/* in this case the new selected will be the last */
|
leo_sobral@1
|
540 |
tmp = g_list_last(tmp);
|
leo_sobral@1
|
541 |
}
|
leo_sobral@1
|
542 |
|
leo_sobral@1
|
543 |
/* update the selected service */
|
leo_sobral@1
|
544 |
mmyth_epg_grid_widget_update_service( object, tmp );
|
leo_sobral@1
|
545 |
}
|
leo_sobral@1
|
546 |
return TRUE;
|
leo_sobral@1
|
547 |
case GDK_Down:
|
leo_sobral@1
|
548 |
selected_view_model = g_list_nth( object->epg_view_model, channel_index + 1 );
|
leo_sobral@1
|
549 |
if(selected_view_model != NULL) {
|
leo_sobral@1
|
550 |
private->selected_channel_index = channel_index + 1;
|
leo_sobral@1
|
551 |
tmp = (GList *) selected_view_model->data;
|
leo_sobral@1
|
552 |
/* TODO: select a better centralized item
|
leo_sobral@1
|
553 |
currently is picking the 1st or last item */
|
leo_sobral@1
|
554 |
if(g_list_next(object->selected_grid_item) == NULL &&
|
leo_sobral@1
|
555 |
g_list_previous(object->selected_grid_item) != NULL) {
|
leo_sobral@1
|
556 |
/* in this case the new selected will be the last */
|
leo_sobral@1
|
557 |
tmp = g_list_last(tmp);
|
leo_sobral@1
|
558 |
}
|
leo_sobral@1
|
559 |
|
leo_sobral@1
|
560 |
/* update the selected service */
|
leo_sobral@1
|
561 |
mmyth_epg_grid_widget_update_service( object, tmp );
|
leo_sobral@1
|
562 |
}
|
leo_sobral@1
|
563 |
return TRUE;
|
leo_sobral@1
|
564 |
case GDK_Left:
|
leo_sobral@1
|
565 |
tmp = g_list_previous( object->selected_grid_item );
|
leo_sobral@1
|
566 |
if(tmp != NULL) {
|
leo_sobral@1
|
567 |
/* update the selected service */
|
leo_sobral@1
|
568 |
mmyth_epg_grid_widget_update_service( object, tmp );
|
leo_sobral@1
|
569 |
}
|
leo_sobral@1
|
570 |
return TRUE;
|
leo_sobral@1
|
571 |
case GDK_Right:
|
leo_sobral@1
|
572 |
tmp = g_list_next( object->selected_grid_item );
|
leo_sobral@1
|
573 |
if(tmp != NULL) {
|
leo_sobral@1
|
574 |
/* update the selected service */
|
leo_sobral@1
|
575 |
mmyth_epg_grid_widget_update_service( object, tmp );
|
leo_sobral@1
|
576 |
}
|
leo_sobral@1
|
577 |
return TRUE;
|
leo_sobral@1
|
578 |
default:
|
leo_sobral@1
|
579 |
return TRUE;
|
leo_sobral@1
|
580 |
}
|
leo_sobral@1
|
581 |
|
leo_sobral@1
|
582 |
return FALSE;
|
leo_sobral@1
|
583 |
}
|
leo_sobral@1
|
584 |
|
leo_sobral@1
|
585 |
static void
|
leo_sobral@1
|
586 |
mmyth_epg_grid_widget_fill_programinfos (MMythEpgGridWidgetPrivate *private)
|
leo_sobral@1
|
587 |
{
|
leo_sobral@1
|
588 |
GList *channels_list = NULL;
|
leo_sobral@1
|
589 |
int y;
|
leo_sobral@1
|
590 |
|
leo_sobral@1
|
591 |
if ((private->mmyth_epg != NULL) &&
|
leo_sobral@1
|
592 |
(gmyth_epg_get_channel_list (private->mmyth_epg, &channels_list) < 0 )) {
|
leo_sobral@1
|
593 |
private->channel_list = NULL;
|
leo_sobral@1
|
594 |
return;
|
leo_sobral@1
|
595 |
}
|
leo_sobral@1
|
596 |
|
leo_sobral@1
|
597 |
private->channel_list = channels_list;
|
leo_sobral@1
|
598 |
|
leo_sobral@1
|
599 |
for (y = 0; y < private->DISPLAY_CHANS && channels_list; y++) {
|
leo_sobral@1
|
600 |
GMythChannelInfo *channel_info = (GMythChannelInfo *) channels_list->data;
|
leo_sobral@1
|
601 |
|
leo_sobral@1
|
602 |
mmyth_epg_grid_widget_fill_program_row_infos(
|
leo_sobral@1
|
603 |
private, channel_info->channel_ID, y);
|
leo_sobral@1
|
604 |
|
leo_sobral@1
|
605 |
channels_list = g_list_next (channels_list);
|
leo_sobral@1
|
606 |
}
|
leo_sobral@1
|
607 |
}
|
leo_sobral@1
|
608 |
|
leo_sobral@1
|
609 |
static void
|
leo_sobral@1
|
610 |
mmyth_epg_grid_widget_fill_program_row_infos(MMythEpgGridWidgetPrivate *private,
|
leo_sobral@1
|
611 |
guint chanNum, guint row)
|
leo_sobral@1
|
612 |
{
|
leo_sobral@1
|
613 |
gint res = gmyth_epg_get_program_list (private->mmyth_epg,
|
leo_sobral@1
|
614 |
&(private->program_list[row]),
|
leo_sobral@1
|
615 |
chanNum, private->current_start_time,
|
leo_sobral@1
|
616 |
private->current_end_time);
|
leo_sobral@1
|
617 |
|
leo_sobral@1
|
618 |
if (res < 0) {
|
leo_sobral@1
|
619 |
g_warning ("[%s] Error while retrieving epg programs", __FUNCTION__);
|
leo_sobral@1
|
620 |
}
|
leo_sobral@1
|
621 |
}
|
leo_sobral@1
|
622 |
|