00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00024 #include <gtk/gtk.h>
00025 #include <time.h>
00026
00027 #include "application-data.h"
00028 #include "log-player.h"
00029 #include "log-player-dbus.h"
00030 #include "time-period.h"
00031
00032
00033
00034 void player_set_status_label (guint64 timestamp, const gchar *prefix)
00035 {
00036 synema_instance_t *inst = synema_instance ();
00037 gchar *buffer = g_malloc (sizeof (char) * PLAYER_DATE_BUTTON_BUFFER_LEN);
00038 gchar *finalbuffer = NULL;
00039 GDate *date = g_date_new ();
00040 gint hours,mins;
00041 GTimeVal timeval = {timestamp, 0};
00042 GtkWidget *label = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_status");
00043 guint64 tmptime = 0;
00044
00045 g_date_set_time_val (date, &timeval);
00046 g_date_strftime (buffer, PLAYER_DATE_BUTTON_BUFFER_LEN, "%x", date);
00047
00048 tmptime = player_date_to_timestamp (date, 0, 0);
00049 tmptime = timestamp - tmptime;
00050 hours = tmptime / 3600;
00051 mins = (tmptime - 3600*hours) / 60;
00052
00053 finalbuffer = g_strdup_printf ("%s\n%s at %02d:%02d", prefix, buffer, hours, mins);
00054 gtk_label_set_text (GTK_LABEL (label), finalbuffer);
00055
00056 g_free (buffer);
00057 g_free (finalbuffer);
00058 g_date_free (date);
00059 }
00060
00061
00062
00063 static gboolean date_button_get_date (GtkButton *button, GDate *date)
00064 {
00065 g_date_set_parse (date, gtk_button_get_label (button));
00066
00067 return g_date_valid (date);
00068 }
00069
00070
00071
00072 static gint date_button_set_label (GtkButton *button, GDate *date)
00073 {
00074 gchar *buffer = g_malloc (sizeof (char) * PLAYER_DATE_BUTTON_BUFFER_LEN);
00075
00076 if (g_date_strftime (buffer, PLAYER_DATE_BUTTON_BUFFER_LEN, PLAYER_DATE_BUTTON_STRFTIME_FORMAT, date) == 0) {
00077 g_free (buffer);
00078 return -1;
00079 }
00080 gtk_button_set_label (button, buffer);
00081
00082 g_free (buffer);
00083 return 0;
00084 }
00085
00086
00087
00088 static int player_stop_after_combo_get_type ()
00089 {
00090 synema_instance_t *inst = synema_instance ();
00091 gint type = 0;
00092 GtkComboBox *box = GTK_COMBO_BOX (gtk_builder_get_object (inst->builder, "player_combo_playtime"));
00093 GtkTreeIter iter;
00094
00095 if (gtk_combo_box_get_active_iter (box, &iter)) {
00096 gtk_tree_model_get (gtk_combo_box_get_model (box), &iter, 1, &type, -1);
00097 return type;
00098 } else {
00099 return 0;
00100 }
00101 }
00102
00103 guint64 player_date_to_timestamp (GDate *date, guint hours, guint mins)
00104 {
00105 struct tm tmbuffer = {0};
00106
00107 g_date_to_struct_tm (date, &tmbuffer);
00108 tmbuffer.tm_hour = hours;
00109 tmbuffer.tm_min = mins;
00110 tmbuffer.tm_sec = 0;
00111
00112 return mktime (&tmbuffer);
00113 }
00114
00115
00116
00117 static void player_on_play_button_pressed (GtkButton *button, gpointer user_data)
00118 {
00119 synema_instance_t *inst = synema_instance ();
00120 gboolean change_gui = TRUE;
00121
00122
00123 if (inst->player_status == PLAYER_STOPPED) {
00124 GDate *date = g_date_new ();
00125 guint64 start_time = 0;
00126 guint64 duration = 0;
00127
00128 if (GPOINTER_TO_INT (user_data)) {
00129 if (date_button_get_date (GTK_BUTTON (gtk_builder_get_object (inst->builder, "player_button_date")), date)) {
00130 start_time = player_date_to_timestamp (date,
00131 gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (inst->builder, "player_spinbutton_hour"))),
00132 gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (inst->builder, "player_spinbutton_min"))));
00133
00134 if (start_time == -1) {
00135 g_warning ("player_on_play_button_pressed: Could not calculate a timestamp from the start date");
00136 g_date_free (date);
00137 return;
00138 }
00139
00140 duration = gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (inst->builder, "player_spinbutton_playtime")));
00141 switch (player_stop_after_combo_get_type ()) {
00142 case WEEK:
00143 duration *=7;
00144 case DAY:
00145 duration *=24;
00146 case HOUR:
00147 duration *=60;
00148 case MINUTE:
00149 duration *=60;
00150 case SECOND:
00151
00152 break;
00153
00154
00155 case YEAR:
00156 duration *=12;
00157 case MONTH:
00158 g_date_add_months (date, duration);
00159 duration = player_date_to_timestamp (date,
00160 gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (inst->builder, "player_spinbutton_hour"))),
00161 gtk_spin_button_get_value (GTK_SPIN_BUTTON (gtk_builder_get_object (inst->builder, "player_spinbutton_min"))));
00162
00163 duration -= start_time;
00164 break;
00165 case LIVE:
00166 case LAST_TIME_PERIOD_T:
00167 duration = 0;
00168 }
00169 } else {
00170 g_warning ("player_on_play_button_pressed: Could not recognise the start date");
00171 g_date_free (date);
00172 return;
00173 }
00174
00175 change_gui = player_dbus_start (start_time, duration);
00176 if (!change_gui)
00177 g_warning ("player_on_stop_button_pressed: Could not stop the player (DBus error)");
00178 }
00179
00180 if (change_gui) {
00181 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_button_date"), FALSE);
00182 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_hour"), FALSE);
00183 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_label_date_double_dot"), FALSE);
00184 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_min"), FALSE);
00185 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_playtime"), FALSE);
00186 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_combo_playtime"), FALSE);
00187 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_label_date"), FALSE);
00188 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_label_stopafter"), FALSE);
00189
00190 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_button_stop"), TRUE);
00191 gtk_image_set_from_stock (GTK_IMAGE (gtk_builder_get_object (inst->builder, "player_button_playpause_image")),
00192 GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_BUTTON);
00193 inst->player_status = PLAYER_PLAYING;
00194 inst->player_curr_time = start_time;
00195 player_set_status_label (start_time, "Playing logs from");
00196 }
00197 }
00198
00199
00200 else if (inst->player_status == PLAYER_PLAYING) {
00201 if (!player_dbus_set_paused (TRUE)) {
00202 g_warning ("player_on_play_button_pressed: Could not pause the player (DBus error)");
00203 } else {
00204 gtk_image_set_from_stock (GTK_IMAGE (gtk_builder_get_object (inst->builder, "player_button_playpause_image")),
00205 GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_BUTTON);
00206
00207 inst->player_status = PLAYER_PAUSED;
00208 player_set_status_label (inst->player_curr_time, "Player paused on");
00209 }
00210 }
00211
00212
00213 else {
00214 if (!player_dbus_set_paused (FALSE)) {
00215 g_warning ("player_on_play_button_pressed: Could not resume the player (DBus error)");
00216 } else {
00217 gtk_image_set_from_stock (GTK_IMAGE (gtk_builder_get_object (inst->builder, "player_button_playpause_image")),
00218 GTK_STOCK_MEDIA_PAUSE, GTK_ICON_SIZE_BUTTON);
00219
00220 inst->player_status = PLAYER_PLAYING;
00221 }
00222 }
00223 }
00224
00225
00226
00227 void player_on_stop_button_pressed (GtkButton *button, gpointer user_data)
00228 {
00229 synema_instance_t *inst = synema_instance ();
00230 gboolean change_gui = TRUE;
00231
00232 if (GPOINTER_TO_INT (user_data)) {
00233 change_gui = player_dbus_stop ();
00234 if (!change_gui)
00235 g_warning ("player_on_stop_button_pressed: Could not stop the player (DBus error)");
00236 }
00237
00238 if (change_gui) {
00239 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_button_date"), TRUE);
00240 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_hour"), TRUE);
00241 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_label_date_double_dot"), TRUE);
00242 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_min"), TRUE);
00243 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_playtime"), TRUE);
00244 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_combo_playtime"), TRUE);
00245 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_label_date"), TRUE);
00246 gtk_widget_set_sensitive ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_label_stopafter"), TRUE);
00247
00248 gtk_widget_set_sensitive (GTK_WIDGET (button), FALSE);
00249 gtk_image_set_from_stock (GTK_IMAGE (gtk_builder_get_object (inst->builder, "player_button_playpause_image")),
00250 GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_BUTTON);
00251 gtk_label_set_text (GTK_LABEL (gtk_builder_get_object (inst->builder, "player_status")), "Player not running");
00252
00253 inst->player_status = PLAYER_STOPPED;
00254 }
00255 }
00256
00257
00258
00259 static void player_show_date_calendar (GtkButton *button, gpointer user_data)
00260 {
00261 synema_instance_t *inst = synema_instance ();
00262 gchar *dlg_objects[] = {"calendar_dialog", NULL};
00263 gchar *path = NULL;
00264 GDate *date = g_date_new ();
00265 GError *err = NULL;
00266 gint result;
00267 GtkWidget *calendar = NULL;
00268 GtkWidget *dialog = NULL;
00269 guint year, month, day;
00270
00271
00272
00273 path = g_strdup_printf ("%s/window.ui", inst->data_dir);
00274 gtk_builder_add_objects_from_file (inst->builder, path, dlg_objects, &err);
00275 g_free (path);
00276 if (err) {
00277 g_warning ("player_show_date_calendar: %s", err->message);
00278 g_clear_error (&err);
00279 return;
00280 }
00281
00282
00283
00284 calendar = (GtkWidget *) gtk_builder_get_object (inst->builder, "calendar");
00285 if (date_button_get_date (button, date)) {
00286 gtk_calendar_select_month (GTK_CALENDAR (calendar), g_date_get_month (date) - 1, g_date_get_year (date));
00287 gtk_calendar_select_day (GTK_CALENDAR (calendar), g_date_get_day (date));
00288 }
00289
00290
00291
00292 dialog = (GtkWidget *) gtk_builder_get_object (inst->builder, "calendar_dialog");
00293 result = gtk_dialog_run (GTK_DIALOG (dialog));
00294
00295 switch (result) {
00296 case GTK_RESPONSE_OK:
00297 gtk_calendar_get_date (GTK_CALENDAR (calendar), &year, &month, &day);
00298 g_date_set_dmy (date, day, month + 1, year);
00299 date_button_set_label (button, date);
00300 break;
00301
00302 default:
00303 break;
00304 }
00305
00306 g_date_free (date);
00307 gtk_widget_destroy (dialog);
00308 }
00309
00310
00311
00312 static void player_on_spin_hour_wrapped (GtkSpinButton *button, gpointer user_data)
00313 {
00314 GDate *date = g_date_new ();
00315 GtkButton *datebutton = GTK_BUTTON (user_data);
00316
00317 if (date_button_get_date (datebutton, date)) {
00318 if (gtk_spin_button_get_value (button) == 0)
00319 g_date_add_days (date, 1);
00320 else
00321 g_date_subtract_days (date, 1);
00322
00323 date_button_set_label (datebutton, date);
00324 }
00325 }
00326
00327
00328
00339 static void player_on_spin_minute_wrapped (GtkSpinButton *button, gpointer user_data)
00340 {
00341 GtkSpinButton *hour = GTK_SPIN_BUTTON (user_data);
00342
00343 if (gtk_spin_button_get_value (button) == 0)
00344 gtk_spin_button_spin (hour, GTK_SPIN_STEP_FORWARD, 1);
00345 else
00346 gtk_spin_button_spin (hour, GTK_SPIN_STEP_BACKWARD, 1);
00347 }
00348
00349
00350
00360 static void player_populate_stopafter_combo (GtkSpinButton *button, gpointer user_data)
00361 {
00362 char *name = NULL;
00363 gint active = -1, i;
00364 GtkWidget *combo = user_data;
00365 GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX(combo)));
00366 GtkTreeIter iter;
00367
00368 active = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
00369
00370 gtk_list_store_clear (store);
00371 for (i=LIVE+1; i<LAST_TIME_PERIOD_T; i++) {
00372 name = time_period_get_display_name_type_value (i, gtk_spin_button_get_value (button), FALSE);
00373 gtk_list_store_append (store, &iter);
00374 gtk_list_store_set (store, &iter, 0, name, 1, i, -1);
00375 g_free (name);
00376 }
00377
00378 gtk_combo_box_set_active (GTK_COMBO_BOX (combo), active);
00379 }
00380
00381
00382
00394 static int player_get_scale_index_from_speed (double speed)
00395 {
00396 double speed_scale_ratio[] = {1.0/60, 1.0/30, .1, .25, .5, 1, 2, 4, 10, 30, 60,
00397 120, 300, 900, 3600, 86400, 604800};
00398 int i;
00399
00400 for (i=0; i<17; i++) {
00401 if (speed == speed_scale_ratio[i])
00402 return i;
00403 }
00404 return PLAYER_SPEED_SCALE_INDEX_NORMAL;
00405 }
00406
00407
00408
00418 static double player_get_speed_scale (GtkRange *scale)
00419 {
00420 double speed_scale_ratio[] = {1.0/60, 1.0/30, .1, .25, .5, 1, 2, 4, 10, 30, 60,
00421 120, 300, 900, 3600, 86400, 604800};
00422 return speed_scale_ratio[(int) gtk_range_get_value (scale)];
00423 }
00424
00425
00426
00435 static void player_on_speed_scale_value_change (GtkScale *scale, gpointer user_data)
00436 {
00437
00438 const char *speed_scale_labels[] = {"1/60", "1/30", "1/10", "1/4", "1/2",
00439 "Normal", "2 sec", "4 sec", "10 sec", "30 sec",
00440 "1 min", "2 min", "5 min",
00441 "15 min", "1 hour", "1 day",
00442 "1 week "};
00443 gboolean change_mark = TRUE;
00444
00445 if (GPOINTER_TO_INT (user_data)) {
00446 change_mark = player_dbus_set_speed (player_get_speed_scale (GTK_RANGE (scale)));
00447 if (!change_mark)
00448 g_warning ("player_on_speed_scale_value_change: Could not update the speed scale (DBus error)");
00449 }
00450
00451 if (change_mark) {
00452 gint value = gtk_range_get_value (GTK_RANGE (scale));
00453 gtk_scale_clear_marks (scale);
00454 gtk_scale_add_mark (scale, value, GTK_POS_BOTTOM, speed_scale_labels[value]);
00455 }
00456 }
00457
00458
00459
00468 static void player_decrement_speed_scale (GtkButton *button, gpointer user_data)
00469 {
00470 gtk_range_set_value (GTK_RANGE (user_data), gtk_range_get_value (GTK_RANGE (user_data)) - 1);
00471 }
00472
00473
00474
00483 static void player_increment_speed_scale (GtkButton *button, gpointer user_data)
00484 {
00485 gtk_range_set_value (GTK_RANGE (user_data), gtk_range_get_value (GTK_RANGE (user_data)) + 1);
00486 }
00487
00488
00489
00498 static void player_on_lookup_button_clicked (GtkButton *button, gpointer user_data)
00499 {
00500 player_dbus_try_ping (TRUE);
00501 }
00502
00503
00504
00505 void player_update_values_from_dbus ()
00506 {
00507 if (!player_dbus_try_ping (FALSE))
00508 return;
00509
00510 synema_instance_t *inst = synema_instance ();
00511 gboolean started = FALSE;
00512 gboolean paused = FALSE;
00513 GDate *date = g_date_new ();
00514 gdouble speed = 0;
00515 GtkWidget *datebutton = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_button_date");
00516 GtkWidget *hourspin = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_hour");
00517 GtkWidget *minspin = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_min");
00518 GtkWidget *scale = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_speed_scale");
00519 GtkWidget *stopaftercombo = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_combo_playtime");
00520 guint64 duration;
00521 guint64 start_date;
00522 time_t tt;
00523 struct tm tm;
00524
00525
00526 player_dbus_get_state (&started, &paused);
00527 if (started) {
00528
00529 inst->player_status = PLAYER_STOPPED;
00530 player_on_play_button_pressed (GTK_BUTTON (gtk_builder_get_object (inst->builder, "player_button_playpause")), GINT_TO_POINTER (0));
00531
00532
00533 if (paused)
00534 player_on_play_button_pressed (GTK_BUTTON (gtk_builder_get_object (inst->builder, "player_button_playpause")), GINT_TO_POINTER (0));
00535
00536 if (player_dbus_get_start_date (&start_date))
00537 tt = start_date;
00538 else
00539 tt = time (NULL);
00540 } else {
00541
00542 player_on_stop_button_pressed (GTK_BUTTON (gtk_builder_get_object (inst->builder, "player_button_stop")), GINT_TO_POINTER (0));
00543
00544 tt = time (NULL);
00545 }
00546
00547
00548
00549 localtime_r (&tt, &tm);
00550 g_date_set_time_t (date, tt);
00551 date_button_set_label (GTK_BUTTON (datebutton), date);
00552 gtk_spin_button_set_value (GTK_SPIN_BUTTON (hourspin), tm.tm_hour);
00553 gtk_spin_button_set_value (GTK_SPIN_BUTTON (minspin), tm.tm_min);
00554 g_date_free (date);
00555
00556
00557
00558 if (started && player_dbus_get_duration (&duration)) {
00570 g_warning ("player_update_values_from_dbus: Playback duration fetching not implemented");
00571 }
00572 gtk_combo_box_set_active (GTK_COMBO_BOX (stopaftercombo), 0);
00573
00574
00575
00576 gtk_range_set_value (GTK_RANGE (scale),
00577 player_dbus_get_speed (&speed) ?
00578 player_get_scale_index_from_speed (speed) :
00579 PLAYER_SPEED_SCALE_INDEX_NORMAL);
00580 player_on_speed_scale_value_change (GTK_SCALE (scale), GINT_TO_POINTER (0));
00581 }
00582
00583
00584
00585 void player_setup_widgets ()
00586 {
00587 synema_instance_t *inst = synema_instance ();
00588 GtkCellRenderer *renderer = NULL;
00589 GtkWidget *datebutton = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_button_date");
00590 GtkWidget *hourspin = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_hour");
00591 GtkWidget *minspin = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_min");
00592 GtkWidget *scale = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_speed_scale");
00593 GtkWidget *stopaftercombo = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_combo_playtime");
00594 GtkWidget *stopafterspin = (GtkWidget *) gtk_builder_get_object (inst->builder, "player_spinbutton_playtime");
00595
00596
00597
00598 g_signal_connect (datebutton, "clicked", G_CALLBACK (player_show_date_calendar), NULL);
00599 g_signal_connect (hourspin, "wrapped", G_CALLBACK (player_on_spin_hour_wrapped), datebutton);
00600 g_signal_connect (minspin, "wrapped", G_CALLBACK (player_on_spin_minute_wrapped), hourspin);
00601
00602
00603
00604 g_signal_connect (stopafterspin, "value-changed", G_CALLBACK (player_populate_stopafter_combo), stopaftercombo);
00605
00606
00607
00608 renderer = gtk_cell_renderer_text_new ();
00609 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (stopaftercombo), renderer, FALSE);
00610 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (stopaftercombo), renderer, "text", 0, NULL);
00611 player_populate_stopafter_combo (GTK_SPIN_BUTTON (stopafterspin), stopaftercombo);
00612
00613
00614
00615 g_signal_connect ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_speed_minus"),
00616 "clicked", G_CALLBACK (player_decrement_speed_scale), scale);
00617 g_signal_connect ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_speed_plus"),
00618 "clicked", G_CALLBACK (player_increment_speed_scale), scale);
00619 g_signal_connect (scale, "value-changed", G_CALLBACK (player_on_speed_scale_value_change), GINT_TO_POINTER (1));
00620
00621
00622
00623 g_signal_connect ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_button_playpause"),
00624 "clicked", G_CALLBACK (player_on_play_button_pressed), GINT_TO_POINTER (1));
00625 g_signal_connect ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_button_stop"),
00626 "clicked", G_CALLBACK (player_on_stop_button_pressed), GINT_TO_POINTER (1));
00627
00628
00629
00630 g_signal_connect ((GtkWidget *) gtk_builder_get_object (inst->builder, "player_lookup_button"),
00631 "clicked", G_CALLBACK (player_on_lookup_button_clicked), NULL);
00632
00633
00634
00635 player_update_values_from_dbus ();
00636 }