1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <gtk/gtk.h>
6 #include <string.h>
7 #include <libintl.h>
8
9 #include "callbacks.h"
10 #include "interface.h"
11 #include "support.h"
12 #include "configlib.h"
13 #include "main.h"
14
15 extern GtkWidget *mainWindow;
16
17 void
on_nouveau_activate(GtkMenuItem * menuitem,gpointer user_data)18 on_nouveau_activate (GtkMenuItem *menuitem,
19 gpointer user_data)
20 {
21 GtkWidget *dialog;
22 gint retour;
23
24 dialog = GTK_WIDGET(create_newConfirmDialog());
25 retour = gtk_dialog_run(GTK_DIALOG(dialog));
26
27 switch(retour)
28 {
29 case GTK_RESPONSE_ACCEPT:
30 newConfig();
31 break;
32
33 case GTK_RESPONSE_CANCEL:
34 break;
35 }
36
37 gtk_widget_destroy(dialog);
38 }
39
40
41 void
on_ouvrir_activate(GtkMenuItem * menuitem,gpointer user_data)42 on_ouvrir_activate (GtkMenuItem *menuitem,
43 gpointer user_data)
44 {
45 GtkWidget *dialog;
46 gint retour;
47 gchar *filename, *tmp;
48 config_t *conf;
49
50 dialog = gtk_file_chooser_dialog_new(
51 gettext("Open new configuration"),
52 GTK_WINDOW(mainWindow),
53 GTK_FILE_CHOOSER_ACTION_OPEN,
54 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
55 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
56 NULL);
57
58 retour = gtk_dialog_run(GTK_DIALOG(dialog));
59 switch(retour)
60 {
61 case GTK_RESPONSE_ACCEPT:
62 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
63 if (filename == NULL)
64 {
65 ErrorBox(mainWindow,
66 gettext("No config file specified.\n"
67 "Internal Error, aborting.\n")
68 );
69 break;
70 }
71
72 conf = parseConfig(filename);
73 if (! conf)
74 {
75 ErrorBox(mainWindow,
76 gettext("Error parsing config file.\n"
77 "Aborting.\n")
78 );
79 break;
80 }
81
82 g_object_set_data(G_OBJECT(mainWindow), "_conf_filename", filename);
83 if (! setConfig(conf, mainWindow))
84 {
85 ErrorBox(mainWindow,
86 gettext("Configuration file is invalid.\n"
87 "Aborting.\n")
88 );
89 g_object_set_data(G_OBJECT(mainWindow), "_conf_filename", NULL);
90 g_free(filename);
91 }
92 _conf_freeConfig( conf ); /* Avoid leak ;) */
93 break;
94
95 case GTK_RESPONSE_CANCEL:
96 break;
97
98 }
99
100 gtk_widget_destroy(dialog);
101 }
102
103
104 gboolean
on_enregistrer_activate(GtkMenuItem * menuitem,gpointer user_data)105 on_enregistrer_activate (GtkMenuItem *menuitem,
106 gpointer user_data)
107 {
108 GtkWidget *main, *dialog;
109 gchar *filename;
110 gboolean retval = FALSE;
111 config_t *conf;
112 FILE *configFile;
113
114 main = mainWindow;
115 if ( (filename = g_object_get_data(G_OBJECT(main), "_conf_filename")) != NULL)
116 {
117 conf = buildConfig();
118 if (conf == NULL)
119 {
120 ErrorBox(main, gettext("An error was detected during the configuration building.\n"
121 "Settings are not acceptable. Please reconfigure cPige.\n"
122 "This would happens for example if you've not added an URL.\n")
123 );
124 } else {
125 if ( (configFile = (FILE *)g_fopen(filename, "w")) == NULL)
126 {
127 ErrorBox(main,
128 gettext("Unable to open your config file for writing.\n"
129 "Please verify rights.\n")
130 );
131 } else {
132 g_object_set_data(G_OBJECT(main), "_conf_filename", filename);
133 _conf_writeConfig( configFile , conf );
134 _conf_freeConfig( conf );
135 fclose(configFile);
136 retval = TRUE;
137 }
138 }
139 } else
140 return on_enregistrer_sous_activate(NULL, user_data);
141
142 return retval;
143 }
144
145
146 gboolean
on_enregistrer_sous_activate(GtkMenuItem * menuitem,gpointer user_data)147 on_enregistrer_sous_activate (GtkMenuItem *menuitem,
148 gpointer user_data)
149 {
150 GtkWidget *saveDialog;
151 GtkWidget *dialog;
152 GtkWidget *main;
153 gint retour;
154 gboolean retval = FALSE;
155 gchar *filename;
156 FILE *configFile;
157 config_t *conf;
158
159 main = mainWindow;
160 conf = buildConfig();
161 if (conf == NULL)
162 {
163 ErrorBox(main,
164 gettext("An error was detected during the configuration building.\n"
165 "Settings are not acceptable. Please reconfigure cPige.\n"
166 "This would happens for example if you've not added an URL.\n")
167 );
168 return;
169 }
170
171 saveDialog = GTK_WIDGET(create_FileSaveDialog());
172 retour = gtk_dialog_run(GTK_DIALOG(saveDialog));
173 switch (retour)
174 {
175 case GTK_RESPONSE_OK:
176 case GTK_RESPONSE_ACCEPT:
177 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(saveDialog));
178 if ( (configFile = (FILE *)g_fopen(filename, "w")) == NULL)
179 {
180 gtk_widget_destroy(GTK_WIDGET(saveDialog));
181 ErrorBox(
182 main,
183 gettext("Unable to open config file for writing.\nSettings will *NOT* be saved.\n")
184 );
185 } else {
186 g_object_set_data(G_OBJECT(main), "_conf_filename", strdup(filename));
187 gtk_widget_destroy(GTK_WIDGET(saveDialog));
188 _conf_writeConfig( configFile, conf );
189 fclose(configFile);
190 retval = TRUE;
191 }
192
193 g_free(filename);
194 break;
195
196 case GTK_RESPONSE_CANCEL:
197 default:
198 gtk_widget_destroy(GTK_WIDGET(saveDialog));
199 break;
200 }
201
202 _conf_freeConfig( conf );
203
204 return retval;
205 }
206
207
208 void
on_quitter_activate(GtkMenuItem * menuitem,gpointer user_data)209 on_quitter_activate (GtkMenuItem *menuitem,
210 gpointer user_data)
211 {
212 GtkWidget *dialog;
213 gint ret;
214 gint is_quit = 1;
215
216 if (is_cpige_running())
217 {
218 dialog = gtk_message_dialog_new(
219 GTK_WINDOW(mainWindow),
220 GTK_DIALOG_DESTROY_WITH_PARENT,
221 GTK_MESSAGE_QUESTION,
222 GTK_BUTTONS_YES_NO,
223 gettext("Warning, cPige is currently recording.\n"
224 "Exiting will shutdown cPige.\n"
225 "Do you really want to continue ?\n")
226 );
227
228 ret = gtk_dialog_run(GTK_DIALOG(dialog));
229 switch(ret)
230 {
231 case GTK_RESPONSE_YES:
232 kill_cpige();
233 break;
234
235 case GTK_RESPONSE_NO:
236 default:
237 is_quit = 0;
238 break;
239 }
240 gtk_widget_destroy(GTK_WIDGET(dialog));
241 }
242
243 if (is_quit)
244 exit(0);
245 }
246
247 void
on_AddUrlBUtton_pressed(GtkButton * button,gpointer user_data)248 on_AddUrlBUtton_pressed (GtkButton *button,
249 gpointer user_data)
250 {
251 GtkTreeView *URLTree;
252 GtkDialog *addurlDialog;
253 GtkEntry *urlEntry;
254 gint retour;
255
256 addurlDialog = GTK_DIALOG(create_URLAddDialog());
257
258 retour = gtk_dialog_run(addurlDialog);
259 switch (retour)
260 {
261 case GTK_RESPONSE_OK:
262 URLTree = GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(button), "URLTreeView"));
263 urlEntry = GTK_ENTRY(lookup_widget(GTK_WIDGET(addurlDialog), "URLAddEntry"));
264 addURL(URLTree, (gchar *)gtk_entry_get_text(urlEntry));
265 something_changed(NULL, NULL);
266 break;
267 default:
268 /* No action */
269 break;
270 }
271 gtk_widget_destroy(GTK_WIDGET(addurlDialog));
272 }
273
274 void
on_DelURLButton_pressed(GtkButton * button,gpointer user_data)275 on_DelURLButton_pressed (GtkButton *button,
276 gpointer user_data)
277 {
278 GtkTreeView *URLTree;
279 GtkTreeSelection *Selection;
280 GtkTreeIter iter;
281 GtkListStore *ListStore;
282
283 URLTree = (GtkTreeView *)lookup_widget((GtkWidget *)button, "URLTreeView");
284 ListStore = GTK_LIST_STORE(gtk_tree_view_get_model(URLTree));
285 if (! ListStore)
286 {
287 g_printf("No valid ListStore found. Could not remove an item.\n");
288 return;
289 }
290
291 Selection = gtk_tree_view_get_selection(URLTree);
292
293 if (gtk_tree_selection_get_selected (Selection,
294 NULL,
295 &iter))
296 gtk_list_store_remove(ListStore, &iter);
297
298 something_changed(NULL, NULL);
299 }
300
301 void
on_IntervalTypeComboBox_changed(GtkComboBox * combobox,gpointer user_data)302 on_IntervalTypeComboBox_changed (GtkComboBox *combobox,
303 gpointer user_data)
304 {
305 gint idx;
306 GtkSpinButton *spinButton;
307
308 spinButton = GTK_SPIN_BUTTON(lookup_widget(GTK_WIDGET(combobox), "IntervalDelaySpinButton"));
309
310 idx = gtk_combo_box_get_active(combobox);
311 if (idx == 0) /* Hour */
312 {
313 gtk_spin_button_set_adjustment(spinButton, GTK_ADJUSTMENT(gtk_adjustment_new (1, 1, 12, 1, 1, 1)));
314 gtk_spin_button_set_value(spinButton, 1);
315 } else if (idx == 1) { /* Minute */
316 gtk_spin_button_set_adjustment(spinButton, GTK_ADJUSTMENT(gtk_adjustment_new (10, 10, 30, 10, 10, 10)));
317 gtk_spin_button_set_value(spinButton, 10);
318 } else {
319 g_printf("Unknown interval type (%d)\n", idx);
320 }
321 }
322
323
324 void
on_pigeModeButton_pressed(GtkButton * button,gpointer user_data)325 on_pigeModeButton_pressed (GtkButton *button,
326 gpointer user_data)
327 {
328 GtkFrame *PigeFrame;
329 GtkToggleButton *weekbackup, *useNumbers, *pigeMetaButton;
330 gboolean state;
331
332 PigeFrame = GTK_FRAME(lookup_widget(GTK_WIDGET(button), "PigeModeFrame"));
333
334 weekbackup = GTK_TOGGLE_BUTTON(lookup_widget(GTK_WIDGET(button), "WeekBackupButton"));
335 useNumbers = GTK_TOGGLE_BUTTON(lookup_widget(GTK_WIDGET(button), "useNumbersButton"));
336 pigeMetaButton = GTK_TOGGLE_BUTTON(lookup_widget(GTK_WIDGET(button), "pigeMetaButton"));
337
338 state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
339 if (state == FALSE) /* Button *was* active. */
340 {
341 gtk_widget_set_sensitive(GTK_WIDGET(PigeFrame), FALSE);
342 gtk_widget_set_sensitive(GTK_WIDGET(useNumbers), TRUE);
343 gtk_widget_set_sensitive(GTK_WIDGET(weekbackup), FALSE);
344 gtk_widget_set_sensitive(GTK_WIDGET(pigeMetaButton), FALSE);
345 }
346 else /* Button *was* inactive */
347 {
348 gtk_widget_set_sensitive(GTK_WIDGET(PigeFrame), TRUE);
349 gtk_widget_set_sensitive(GTK_WIDGET(useNumbers), FALSE);
350 gtk_widget_set_sensitive(GTK_WIDGET(weekbackup), TRUE);
351 gtk_widget_set_sensitive(GTK_WIDGET(pigeMetaButton), TRUE);
352 }
353 }
354
355
356 void
on_startButton_clicked(GtkButton * button,gpointer user_data)357 on_startButton_clicked (GtkButton *button,
358 gpointer user_data)
359 {
360 gboolean state;
361 GtkWidget *image;
362 GtkWidget *wid;
363 GtkWidget *main;
364 int i;
365 gchar *DisableFrames[] = {"ParametersFrame", "ExtraParametersFrame", NULL};
366 gchar *iter, *filename;
367
368 main = mainWindow;
369
370 if ( (filename = g_object_get_data(G_OBJECT(main), "_conf_filename")) == NULL)
371 {
372 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
373 WarningBox( main,
374 gettext("You must save your configuration before launching cPige.\n")
375 );
376
377 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
378 return;
379 }
380
381 state = (gboolean)g_object_get_data(G_OBJECT(button), "savemode");
382 if ((state == TRUE) &&
383 (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) == TRUE))
384 {
385 if (on_enregistrer_activate(NULL, user_data) == TRUE)
386 {
387 gtk_button_set_label(button, gettext("Start"));
388 g_object_set_data(G_OBJECT(button), "savemode", FALSE);
389 }
390 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
391 return;
392 }
393
394 image = lookup_widget(GTK_WIDGET(button), "startButtonImage");
395 state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
396
397 if (state == TRUE)
398 {
399 if (! launch_cpige())
400 {
401 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
402 return;
403 }
404
405 gtk_button_set_label(button, gettext("Stop"));
406 /* Icon gtk-stop */
407 gtk_image_set_from_stock(GTK_IMAGE(image), GTK_STOCK_QUIT, GTK_ICON_SIZE_BUTTON);
408 } else {
409 gtk_button_set_label(button, gettext("Start"));
410 /* Icon gtk-media-play */
411 gtk_image_set_from_stock(GTK_IMAGE(image), GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_BUTTON);
412 g_object_set_data(G_OBJECT(mainWindow), "stopping", (void *)NULL);
413 kill_cpige();
414 }
415 gtk_button_set_image(button, image);
416
417 for (i = 0; DisableFrames[i] != NULL; i++)
418 {
419 wid = lookup_widget(GTK_WIDGET(button), DisableFrames[i]);
420 gtk_widget_set_sensitive(wid, !state);
421 }
422 }
423
424 void
on_LogfileCheckButton_pressed(GtkButton * button,gpointer user_data)425 on_LogfileCheckButton_pressed (GtkButton *button,
426 gpointer user_data)
427 {
428 GtkWidget *lbutton, *entry;
429 gboolean state;
430
431 lbutton = lookup_widget(GTK_WIDGET(button), "LogfileChooserButton");
432 entry = lookup_widget(GTK_WIDGET(button), "LogfileEntry");
433 state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
434 if (state == FALSE) /* The button was active, and is not inactive */
435 {
436 gtk_widget_set_sensitive(lbutton, FALSE);
437 gtk_widget_set_sensitive(entry, FALSE);
438 } else { /* The button was inactive and is now active */
439 gtk_widget_set_sensitive(lbutton, TRUE);
440 gtk_widget_set_sensitive(entry, TRUE);
441 }
442
443 something_changed(NULL, NULL);
444 }
445
446 void
on_log_open_pressed(GtkButton * button,gpointer user_data)447 on_log_open_pressed (GtkButton *button,
448 gpointer user_data)
449 {
450 GtkWidget *saveDialog;
451 GtkWidget *logentry;
452 gint retour;
453 gchar *filename;
454 FILE *logFile;
455
456 saveDialog = GTK_WIDGET(create_FileSaveDialog());
457 retour = gtk_dialog_run(GTK_DIALOG(saveDialog));
458 switch (retour)
459 {
460 case GTK_RESPONSE_OK:
461 case GTK_RESPONSE_ACCEPT:
462 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(saveDialog));
463 if ( (logFile = (FILE *)g_fopen(filename, "w")) == NULL)
464 {
465 gtk_widget_destroy(GTK_WIDGET(saveDialog));
466 ErrorBox(
467 mainWindow,
468 gettext("Unable to open config file for writing.\nSettings will *NOT* be saved.\n")
469 );
470 } else {
471 gtk_widget_destroy(GTK_WIDGET(saveDialog));
472 logentry = lookup_widget(GTK_WIDGET(button), "LogfileEntry");
473 gtk_entry_set_text(GTK_ENTRY(logentry), filename);
474 something_changed(NULL, NULL);
475 fclose(logFile);
476 }
477
478 g_free(filename);
479 break;
480
481 case GTK_RESPONSE_CANCEL:
482 default:
483 gtk_widget_destroy(GTK_WIDGET(saveDialog));
484 break;
485 }
486
487 }
488
489
490 void
url_edited_callback(GtkCellRendererText * cell,gchar * path_string,gchar * new_text,gpointer model)491 url_edited_callback (GtkCellRendererText *cell,
492 gchar *path_string,
493 gchar *new_text,
494 gpointer model)
495 {
496 GtkTreeIter iter;
497
498 if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(model), &iter, path_string) == FALSE)
499 {
500 g_printf("Edited wrong cell!!\n");
501 return;
502 }
503
504 gtk_list_store_set(model, &iter, 0, new_text, -1);
505 something_changed(NULL, NULL);
506 }
507
something_changed(GtkButton * button,gpointer user_data)508 void something_changed(GtkButton *button,
509 gpointer user_data)
510 {
511 gint state;
512 GtkWidget *startButton;
513 /* Something in the configuration has changed.
514 *
515 * cPige GUI will change the Start Button
516 * to Save / Start
517 */
518
519 /* Retreive start button state */
520 startButton = lookup_widget(GTK_WIDGET(mainWindow), "startButton");
521
522 state = (gboolean)g_object_get_data(G_OBJECT(startButton), "savemode");
523 if (state == 0)
524 {
525 /* Button is not in save mode. Switch to save mode ;) */
526 g_object_set_data(G_OBJECT(startButton), "savemode", (gpointer)TRUE);
527 gtk_button_set_label(GTK_BUTTON(startButton), gettext("Apply"));
528 }
529 }
530
531
532 /* GIOFunc */
cPigeEvent(GIOChannel * source,GIOCondition condition,gpointer data)533 gboolean cPigeEvent (GIOChannel *source,
534 GIOCondition condition,
535 gpointer data)
536 {
537 GError *error = NULL;
538 GtkWidget *titleWidget, *nextTitleWidget;
539 GtkWidget *progress;
540 GtkWidget *startButton;
541 gchar *line;
542 gsize line_len, terminator;
543 gchar *title;
544 gchar *next_title;
545 gchar *left;
546 gchar *percent_str;
547 if ((condition & G_IO_IN) || (condition & G_IO_PRI))
548 {
549 /* Lookup widget to update */
550 titleWidget = lookup_widget(GTK_WIDGET(mainWindow), "titleEntry");
551 nextTitleWidget = lookup_widget(GTK_WIDGET(mainWindow), "nexttitleEntry");
552 progress = lookup_widget(GTK_WIDGET(mainWindow), "timeleftProgressBar");
553
554 /* there is data to read */
555 if (g_io_channel_read_line(source, &line, &line_len, &terminator, &error) != G_IO_STATUS_NORMAL)
556 {
557 g_warning("Error reading the line ...\n");
558 gtk_entry_set_text(GTK_ENTRY(titleWidget), "");
559 gtk_entry_set_text(GTK_ENTRY(nextTitleWidget), "");
560 gtk_progress_set_percentage(GTK_PROGRESS(progress), 0.0);
561 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), "timeleft");
562 return FALSE;
563 }
564
565 line[terminator] = '\0';
566
567 if ((line_len < 9) || (strncmp((char *)line, "CPIGEGUI", 8) != 0))
568 {
569 g_free(line);
570 return TRUE;
571 }
572
573 line += 9;
574 line_len -= 9;
575
576 title = (gchar *)strtok(line, ":");
577 next_title = (gchar *)strtok(NULL, ":");
578 left = (gchar *)strtok(NULL, ":");
579 percent_str = (gchar *)strtok(NULL, ":");
580
581 /* Now, update widgets */
582 if (title)
583 gtk_entry_set_text(GTK_ENTRY(titleWidget), title);
584 if ((next_title) && (strlen(next_title)))
585 gtk_entry_set_text(GTK_ENTRY(nextTitleWidget), next_title);
586
587 if ((left == NULL) || (*left == 0))
588 gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress));
589 else
590 {
591 if ((percent_str) && (strlen(percent_str)))
592 {
593 int percentage, hour, min, sec, left_sec;
594 gchar statusText[100];
595 memset(statusText, 0, 100);
596
597 left_sec = atoi(left);
598 hour = left_sec / 3600;
599 min = (left_sec / 60) - (hour*60);
600 sec = left_sec - (hour*3600) - (min*60);
601 percentage = atoi(percent_str);
602 gtk_progress_set_percentage(GTK_PROGRESS(progress), ((float)percentage / 100.0));
603 snprintf(statusText, 100, "%dh %dm %ds (%d%%)", hour, min, sec, percentage);
604 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), statusText);
605 }
606 }
607
608 g_free(line);
609
610 } else if (condition & G_IO_HUP) {
611 if (g_object_get_data(G_OBJECT(mainWindow), "stopping") != NULL)
612 g_object_set_data(G_OBJECT(mainWindow), "stopping", NULL);
613 else
614 ErrorBox(mainWindow, gettext("cPige exited.\n"));
615
616 startButton = GTK_WIDGET(lookup_widget(GTK_WIDGET(mainWindow), "startButton"));
617 gtk_button_set_label(GTK_BUTTON(startButton), gettext("Start"));
618 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(startButton), FALSE);
619
620 return FALSE;
621 } else {
622 g_printf("Uncatched event received: %d\n", condition);
623 return FALSE;
624 }
625 }
626