1 : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 : /*
3 : heraia_ui.c
4 : main menus, callback and utility functions
5 :
6 : (C) Copyright 2005 - 2008 Olivier Delhomme
7 : e-mail : heraia@delhomme.org
8 : URL : http://heraia.tuxfamily.org
9 :
10 : This program is free software; you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation; either version 2, or (at your option)
13 : any later version.
14 :
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with this program; if not, write to the Free Software
22 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 : */
24 :
25 : #include "heraia_types.h"
26 :
27 : static gboolean load_heraia_glade_xml(heraia_window_t *main_window);
28 : static void heraia_ui_connect_signals(heraia_window_t *main_window);
29 : static void record_and_hide_about_box(heraia_window_t *main_window);
30 :
31 : /**
32 : * Quit, file menu
33 : */
34 : void on_quitter1_activate( GtkWidget *widget, gpointer data )
35 1 : {
36 1 : gtk_main_quit();
37 1 : }
38 :
39 : /**
40 : * New, file menu
41 : */
42 : void on_nouveau1_activate(GtkWidget *widget, gpointer data)
43 0 : {
44 0 : heraia_window_t *main_window = (heraia_window_t *) data;
45 :
46 0 : log_message(main_window, G_LOG_LEVEL_WARNING, "Not implemented Yet (Please contribute !)");
47 0 : }
48 :
49 : /**
50 : * Shows apropos's dialog box
51 : */
52 : void a_propos_activate(GtkWidget *widget, gpointer data)
53 0 : {
54 0 : heraia_window_t *main_window = (heraia_window_t *) data;
55 0 : GtkWidget *about_dialog = NULL;
56 :
57 0 : about_dialog = heraia_get_widget(main_window->xmls->main, "about_dialog");
58 :
59 0 : if (about_dialog != NULL)
60 : {
61 : if (GTK_MINOR_VERSION >= 12)
62 : {
63 0 : gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about_dialog), PACKAGE_NAME);
64 : }
65 : if (GTK_MINOR_VERSION >= 6)
66 : {
67 0 : gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about_dialog), PACKAGE_VERSION);
68 : }
69 0 : main_window->win_prop->about_box = move_and_show_dialog_box(about_dialog, main_window->win_prop->about_box);
70 : }
71 0 : }
72 :
73 : /**
74 : * Move the dialog box to the wanted position, shows it and says it in the displayed prop
75 : */
76 : window_prop_t *move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
77 0 : {
78 0 : if (dialog_prop->displayed == FALSE)
79 : {
80 0 : gtk_window_move(GTK_WINDOW(dialog_box), dialog_prop->x, dialog_prop->y);
81 :
82 0 : gtk_widget_show_all(dialog_box);
83 0 : dialog_prop->displayed = TRUE;
84 : }
85 :
86 0 : return dialog_prop;
87 : }
88 :
89 :
90 : /**
91 : * Record position and hide a dialog box
92 : */
93 : window_prop_t *record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
94 0 : {
95 0 : gint x = 0;
96 0 : gint y = 0;
97 :
98 0 : if (dialog_prop->displayed == TRUE)
99 : {
100 :
101 0 : gtk_window_get_position(GTK_WINDOW(dialog_box), &x, &y);
102 :
103 0 : dialog_prop->x = x;
104 0 : dialog_prop->y = y;
105 :
106 0 : gtk_widget_hide(dialog_box);
107 0 : dialog_prop->displayed = FALSE;
108 : }
109 :
110 0 : return dialog_prop;
111 : }
112 :
113 :
114 : /**
115 : * Record position and hide about dialog box
116 : */
117 : static void record_and_hide_about_box(heraia_window_t *main_window)
118 0 : {
119 0 : GtkWidget *about_dialog = NULL;
120 :
121 0 : about_dialog = heraia_get_widget(main_window->xmls->main, "about_dialog");
122 :
123 0 : if (about_dialog != NULL)
124 : {
125 0 : main_window->win_prop->about_box = record_and_hide_dialog_box(about_dialog, main_window->win_prop->about_box);
126 : }
127 0 : }
128 :
129 :
130 : /**
131 : * To close the A propos dialog box (with the "close" button)
132 : */
133 : static void a_propos_response(GtkWidget *widget, gint response, gpointer data)
134 0 : {
135 0 : heraia_window_t *main_window = (heraia_window_t *) data;
136 0 : record_and_hide_about_box(main_window);
137 0 : }
138 :
139 : static void a_propos_close(GtkWidget *widget, gpointer data)
140 0 : {
141 0 : heraia_window_t *main_window = (heraia_window_t *) data;
142 0 : record_and_hide_about_box(main_window);
143 0 : }
144 :
145 : static gboolean a_propos_delete(GtkWidget *widget, GdkEvent *event, gpointer data)
146 0 : {
147 0 : heraia_window_t *main_window = (heraia_window_t *) data;
148 0 : record_and_hide_about_box(main_window);
149 :
150 0 : return TRUE;
151 : }
152 :
153 :
154 : /**
155 : * Delete, edit menu
156 : */
157 : void on_supprimer1_activate( GtkWidget *widget, gpointer data )
158 0 : {
159 0 : heraia_window_t *main_window = (heraia_window_t *) data;
160 :
161 0 : log_message(main_window, G_LOG_LEVEL_WARNING, "Not implemented Yet (Please contribute !)");
162 0 : }
163 :
164 : /**
165 : * Cut, edit menu
166 : */
167 : void on_couper1_activate( GtkWidget *widget, gpointer data )
168 0 : {
169 0 : heraia_window_t *main_window = (heraia_window_t *) data;
170 :
171 0 : log_message(main_window, G_LOG_LEVEL_WARNING, "Not implemented Yet (Please contribute !)");
172 0 : }
173 :
174 : /**
175 : * Copy, edit menu
176 : */
177 : void on_copier1_activate( GtkWidget *widget, gpointer data )
178 0 : {
179 0 : heraia_window_t *main_window = (heraia_window_t *) data;
180 :
181 0 : log_message(main_window, G_LOG_LEVEL_WARNING, "Not implemented Yet (Please contribute !)");
182 0 : }
183 :
184 :
185 : /**
186 : * Paste, edit menu
187 : */
188 : void on_coller1_activate( GtkWidget *widget, gpointer data )
189 0 : {
190 0 : heraia_window_t *main_window = (heraia_window_t *) data;
191 :
192 0 : log_message(main_window, G_LOG_LEVEL_WARNING, "Not implemented Yet (Please contribute !)");
193 0 : }
194 :
195 :
196 : /**
197 : * This function is here to ensure that everything will be
198 : * refreshed upon a signal event.
199 : */
200 : void refresh_event_handler(GtkWidget *widget, gpointer data)
201 1 : {
202 1 : heraia_window_t *main_window = (heraia_window_t *) data;
203 :
204 1 : if (main_window != NULL)
205 : {
206 : /* Beware, this mechanism is not thread safe ! */
207 1 : if (main_window->event == HERAIA_REFRESH_NOTHING)
208 0 : main_window->event = HERAIA_REFRESH_CURSOR_MOVE;
209 :
210 1 : refresh_data_interpretor_window(widget, main_window);
211 1 : refresh_all_plugins(main_window);
212 :
213 1 : main_window->event = HERAIA_REFRESH_NOTHING;
214 : }
215 1 : }
216 :
217 :
218 : /**
219 : * This handles the menuitem "Ouvrir" to open a file
220 : */
221 : void on_ouvrir1_activate(GtkWidget *widget, gpointer data )
222 1 : {
223 1 : heraia_window_t *main_window = (heraia_window_t *) data;
224 :
225 1 : if (select_file_to_load(main_window) == TRUE)
226 : {
227 1 : load_file_to_analyse(main_window, main_window->filename);
228 : }
229 :
230 1 : main_window->event = HERAIA_REFRESH_NEW_FILE;
231 1 : refresh_event_handler(main_window->current_DW->current_hexwidget, main_window);
232 1 : }
233 :
234 :
235 : /**
236 : * Here we attemp to save the edited file
237 : * TODO : be more accurate on error (error type, message and filename)
238 : */
239 : void on_save_activate( GtkWidget *widget, gpointer data )
240 0 : {
241 0 : heraia_window_t *main_window = (heraia_window_t *) data;
242 0 : HERAIA_ERROR erreur = HERAIA_NOERR;
243 0 : gchar *filename = NULL;
244 :
245 0 : if (main_window != NULL)
246 : {
247 0 : erreur = heraia_hex_document_save(main_window);
248 : }
249 :
250 0 : if (erreur != HERAIA_NOERR)
251 : {
252 0 : filename = heraia_hex_document_get_filename(main_window->current_doc);
253 0 : log_message(main_window, G_LOG_LEVEL_ERROR, "Error while saving file %s !", filename);
254 : }
255 0 : }
256 :
257 : /**
258 : * This handle the save_as menu entry (here the filename changes)
259 : */
260 : void on_save_as_activate( GtkWidget *widget, gpointer data )
261 1 : {
262 1 : heraia_window_t *main_window = (heraia_window_t *) data;
263 1 : HERAIA_ERROR erreur = HERAIA_NOERR;
264 1 : gchar *filename = NULL; /* Auto malloc'ed, do not free */
265 :
266 1 : if (main_window != NULL)
267 : {
268 1 : filename = select_a_file_to_save(main_window);
269 :
270 1 : if (filename != NULL)
271 : {
272 1 : erreur = heraia_hex_document_save_as(main_window, filename);
273 : }
274 : else
275 : {
276 0 : erreur = HERAIA_CANCELLED;
277 : }
278 :
279 1 : if (erreur != HERAIA_NOERR)
280 : {
281 0 : if (erreur == HERAIA_CANCELLED)
282 : {
283 0 : log_message(main_window, G_LOG_LEVEL_DEBUG, "Saving file as... : operation cancelled.");
284 : }
285 : else
286 : {
287 0 : log_message(main_window, G_LOG_LEVEL_ERROR, "Error while saving file as %s", main_window->current_doc->file_name);
288 : }
289 : }
290 : else
291 : {
292 : /* updating the window name */
293 1 : update_main_window_name(main_window);
294 1 : log_message(main_window, G_LOG_LEVEL_DEBUG, "File %s saved and now edited.", main_window->current_doc->file_name);
295 : }
296 : }
297 1 : }
298 :
299 : /**
300 : * This handles the menuitem "Data Interpretor" that
301 : * shows or hides the data interpretor window
302 : */
303 : void on_DIMenu_activate(GtkWidget *widget, gpointer data)
304 0 : {
305 :
306 0 : heraia_window_t *main_window = (heraia_window_t *) data;
307 0 : data_window_t *dw = NULL; /* program structure */
308 0 : GtkNotebook *notebook = NULL; /* data interpretor's notebook */
309 :
310 0 : if (main_window != NULL)
311 : {
312 0 : dw = main_window->current_DW;
313 :
314 0 : if (dw != NULL)
315 : {
316 0 : if (dw->diw == NULL)
317 : {
318 0 : dw->diw = heraia_get_widget(main_window->xmls->main, "data_interpretor_window");
319 : }
320 :
321 0 : if (dw->diw != NULL)
322 : {
323 : /* dw->window_displayed = !(dw->window_displayed); */
324 0 : notebook = GTK_NOTEBOOK(heraia_get_widget(main_window->xmls->main, "diw_notebook"));
325 :
326 0 : if (main_window->win_prop->data_interpretor->displayed == FALSE)
327 : {
328 : /* Setting the first page of the notebook as default (Numbers) */
329 0 : gtk_notebook_set_current_page(notebook, dw->tab_displayed);
330 :
331 : /* moving to the right position */
332 0 : main_window->win_prop->data_interpretor = move_and_show_dialog_box(dw->diw, main_window->win_prop->data_interpretor);
333 : /* gtk_widget_show_all(dw->diw); */
334 :
335 0 : refresh_data_interpretor_window(widget, data);
336 : }
337 : else
338 : {
339 : /* recording some prefs from the dialog : position + opened tab */
340 0 : dw->tab_displayed = gtk_notebook_get_current_page(notebook);
341 0 : main_window->win_prop->data_interpretor = record_and_hide_dialog_box(dw->diw, main_window->win_prop->data_interpretor);
342 : /* gtk_widget_hide_all(dw->diw); */
343 : }
344 : }
345 : }
346 : }
347 0 : }
348 :
349 : /**
350 : * When the user destroys or delete the main window
351 : */
352 : gboolean delete_main_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
353 0 : {
354 0 : gtk_widget_destroy(widget);
355 0 : return TRUE;
356 : }
357 :
358 :
359 : /**
360 : * call back functions for the data interpretor window destruction
361 : */
362 : gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
363 0 : {
364 0 : heraia_window_t *main_window = (heraia_window_t *) data;
365 :
366 0 : g_signal_emit_by_name(heraia_get_widget(main_window->xmls->main, "DIMenu"), "activate");
367 :
368 0 : return TRUE;
369 : }
370 :
371 : void destroy_dt_window(GtkWidget *widget, GdkEvent *event, gpointer data)
372 0 : {
373 0 : heraia_window_t *main_window = (heraia_window_t *) data;
374 :
375 0 : g_signal_emit_by_name(heraia_get_widget(main_window->xmls->main, "DIMenu"), "activate");
376 0 : }
377 : /* End of call back functions that handle the data interpretor window */
378 :
379 :
380 : /**
381 : * Returns an absolute path to the filename
382 : * the string should be freed when no longer needed
383 : * very UGLy !
384 : */
385 : static gchar *make_absolute_path(gchar *filename)
386 2 : {
387 2 : gchar *current_dir = NULL;
388 2 : gchar *new_dir = NULL;
389 :
390 2 : if (g_path_is_absolute(filename) == TRUE)
391 : {
392 : /* if the filename is already in an absolute format */
393 1 : return g_path_get_dirname(filename);
394 : }
395 : else
396 : {
397 1 : current_dir = g_get_current_dir();
398 1 : new_dir = g_path_get_dirname(filename);
399 :
400 1 : if (g_chdir(new_dir) == 0)
401 : {
402 1 : g_free(new_dir);
403 1 : new_dir = g_get_current_dir();
404 1 : g_chdir(current_dir);
405 1 : g_free(current_dir);
406 :
407 1 : return new_dir;
408 : }
409 : else
410 : {
411 0 : g_free(current_dir);
412 :
413 0 : return NULL;
414 : }
415 : }
416 : }
417 :
418 :
419 : /**
420 : * Sets the working directory for the file chooser to the directory of the
421 : * filename (even if filename is a relative filename such as
422 : * ../docs/test_file)
423 : */
424 : static void set_the_working_directory(GtkFileChooser *file_chooser, gchar *filename)
425 2 : {
426 2 : gchar *dirname = NULL; /* directory where we want to be, at first, in the file chooser */
427 :
428 2 : dirname = make_absolute_path(filename);
429 :
430 2 : if (dirname != NULL)
431 : {
432 2 : gtk_file_chooser_set_current_folder(file_chooser, dirname);
433 2 : g_free(dirname);
434 : }
435 2 : }
436 :
437 :
438 : /**
439 : * This function does open a file selector dialog box and returns the selected
440 : * filename.
441 : * We do fill the main_window->filename parameter here !
442 : */
443 : gboolean select_file_to_load(heraia_window_t *main_window)
444 1 : {
445 1 : GtkWidget *parent = NULL; /* A parent window (we use main_window) */
446 1 : GtkFileChooser *file_chooser = NULL;
447 1 : gboolean success = FALSE;
448 1 : gchar *filename = NULL; /* filename selected (if any) to be openned */
449 :
450 1 : parent = heraia_get_widget(main_window->xmls->main, "main_window");
451 :
452 1 : file_chooser = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new("Select a file to analyse",
453 : GTK_WINDOW(parent),
454 : GTK_FILE_CHOOSER_ACTION_OPEN,
455 : GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
456 : GTK_STOCK_OPEN, GTK_RESPONSE_OK,
457 : NULL));
458 :
459 : /**
460 : * for the moment we do not want to retrieve multiples selections
461 : * but this could be a valuable thing in the future
462 : */
463 1 : gtk_window_set_modal(GTK_WINDOW(file_chooser), TRUE);
464 1 : gtk_file_chooser_set_select_multiple(file_chooser, FALSE);
465 :
466 : /**
467 : * We want the file selection path to be the one of the previous
468 : * openned file if any !
469 : */
470 1 : if (main_window->filename != NULL)
471 : {
472 1 : set_the_working_directory(file_chooser, main_window->filename);
473 : }
474 :
475 1 : switch (gtk_dialog_run(GTK_DIALOG(file_chooser)))
476 : {
477 : case GTK_RESPONSE_OK:
478 1 : filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
479 1 : log_message(main_window, G_LOG_LEVEL_DEBUG, "filename selected : %s", filename);
480 :
481 : /* this should be managed with lists and not here !! */
482 1 : if (main_window->filename != NULL)
483 : {
484 1 : g_free(main_window->filename);
485 : }
486 :
487 1 : main_window->filename = g_strdup_printf("%s", filename);
488 1 : success = TRUE;
489 1 : break;
490 : case GTK_RESPONSE_CANCEL:
491 : default:
492 0 : success = FALSE;
493 : break;
494 : }
495 :
496 1 : g_free(filename);
497 1 : gtk_widget_destroy(GTK_WIDGET(file_chooser));
498 :
499 1 : return success;
500 : }
501 :
502 : /**
503 : * This function opens a dialog box that allow one to choose a
504 : * file name to the file which is about to be saved
505 : */
506 : gchar *select_a_file_to_save(heraia_window_t *main_window)
507 1 : {
508 1 : GtkWidget *parent = NULL; /* A parent window (we use main_window) */
509 1 : GtkFileChooser *fcd = NULL;
510 1 : gchar *filename = NULL;
511 :
512 1 : parent = heraia_get_widget(main_window->xmls->main, "main_window");
513 :
514 : /* Selection a name to the file to save */
515 1 : fcd = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new("Save As...",
516 : GTK_WINDOW(parent),
517 : GTK_FILE_CHOOSER_ACTION_SAVE,
518 : GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
519 : GTK_STOCK_SAVE, GTK_RESPONSE_OK,
520 : NULL));
521 :
522 : /* window properties : modal, without multi-selection and with confirmation */
523 1 : gtk_window_set_modal(GTK_WINDOW(fcd), TRUE);
524 1 : gtk_file_chooser_set_select_multiple(fcd, FALSE);
525 1 : gtk_file_chooser_set_do_overwrite_confirmation(fcd, TRUE);
526 :
527 : /* we do want to have the file's directory where to save the new file */
528 1 : if (main_window->filename != NULL)
529 : {
530 1 : set_the_working_directory(fcd, main_window->filename);
531 : }
532 :
533 1 : switch(gtk_dialog_run(GTK_DIALOG(fcd)))
534 : {
535 : case GTK_RESPONSE_OK:
536 : /* retrieving the filename */
537 1 : filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fcd));
538 1 : break;
539 : default:
540 0 : filename = NULL;
541 : break;
542 : }
543 :
544 1 : gtk_widget_destroy(GTK_WIDGET(fcd));
545 :
546 1 : return filename;
547 : }
548 :
549 :
550 : /**
551 : * Update main window heraia's name to reflect the current edited file
552 : */
553 : void update_main_window_name(heraia_window_t *main_window)
554 3 : {
555 3 : GtkWidget *widget = NULL;
556 : gchar *filename;
557 :
558 3 : if (main_window != NULL && main_window->current_doc != NULL)
559 : {
560 3 : widget = heraia_get_widget(main_window->xmls->main, "main_window");
561 3 : filename = g_filename_display_basename(main_window->current_doc->file_name);
562 :
563 3 : gtk_window_set_title(GTK_WINDOW(widget), filename);
564 : }
565 3 : }
566 :
567 : /**
568 : * Here we might init some call backs and menu options
569 : * and display the interface (main && sub-windows)
570 : * This function should be called only once at main program's
571 : * init time
572 : */
573 : void init_heraia_interface(heraia_window_t *main_window)
574 1 : {
575 1 : data_window_t *dw = NULL; /* data interpretor structure */
576 1 : GtkWidget *diw = NULL; /* data interpretor window */
577 1 : GtkWidget *menu = NULL; /* the DIMenu diplay option */
578 1 : GtkWidget *window = NULL; /* the main window widget */
579 : all_window_prop_t *win_prop; /* window properties (all) */
580 :
581 : /**
582 : * I can not record why I wrote this code. But it is very clear that
583 : * nowdays it will never be used and is totally useless !!
584 : */
585 :
586 1 : if (main_window != NULL)
587 : {
588 1 : dw = main_window->current_DW;
589 :
590 1 : menu = heraia_get_widget(main_window->xmls->main, "DIMenu");
591 1 : window = heraia_get_widget(main_window->xmls->main, "main_window");
592 1 : win_prop = main_window->win_prop;
593 :
594 :
595 : /* if (dw != NULL && diw != NULL) *//* Something's wrong here ! */
596 : /* { */
597 : /* Connection of the signal to the right function
598 : * in order to interpret things when the cursor is
599 : * moving
600 : */
601 : /*
602 : connect_cursor_moved_signal(main_window);
603 : */
604 : /* gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu), win_prop->data_interpretor->displayed); */
605 :
606 : /* Shows all widgets */
607 : /* move_and_show_dialog_box(window, win_prop->main_dialog); */
608 :
609 : /* Shows or hide the data interpretor window */
610 : /*
611 : if (win_prop->main_dialog->displayed == TRUE)
612 : {
613 : move_and_show_dialog_box(diw, win_prop->main_dialog);
614 : }
615 : else
616 : {
617 : record_and_hide_dialog_box(diw, win_prop->main_dialog);
618 : }
619 :
620 : }*/
621 : }
622 1 : }
623 :
624 :
625 : /**
626 : * Loads the glade xml files that describes the heraia project
627 : * tries the following paths in that order :
628 : * - /etc/heraia/heraia.glade
629 : * - /home/[user]/.heraia/heraia.glade
630 : * - PWD/heraia.glade
631 : */
632 : static gboolean load_heraia_glade_xml(heraia_window_t *main_window)
633 : {
634 1 : gchar *filename = NULL;
635 :
636 1 : if (main_window != NULL && main_window->xmls != NULL)
637 : {
638 :
639 1 : filename = g_strdup_printf("heraia.glade");
640 1 : main_window->xmls->main = load_glade_xml_file(main_window->location_list, filename);
641 1 : g_free(filename);
642 :
643 : /**
644 : * filename = g_strdup_printf("treatment.glade");
645 : * main_window->xmls->treatment = load_glade_xml_file(main_window->location_list, filename);
646 : * g_free(filename);
647 : */
648 :
649 1 : if (main_window->xmls->main == NULL) /* || main_window->xmls->treatment == NULL) */
650 0 : return FALSE;
651 : else
652 1 : return TRUE;
653 : }
654 : else
655 0 : return FALSE;
656 : }
657 :
658 : /**
659 : * Connects the signal that the cursor has moved to
660 : * the refreshing function
661 : */
662 : void connect_cursor_moved_signal(heraia_window_t *main_window)
663 2 : {
664 2 : g_signal_connect(G_OBJECT(main_window->current_DW->current_hexwidget), "cursor_moved",
665 : G_CALLBACK(refresh_event_handler), main_window);
666 2 : }
667 :
668 :
669 : /**
670 : * Connect the signals at the interface
671 : */
672 : static void heraia_ui_connect_signals(heraia_window_t *main_window)
673 1 : {
674 :
675 : /* the data interpretor menu */
676 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "DIMenu")), "activate",
677 : G_CALLBACK (on_DIMenu_activate), main_window);
678 :
679 : /* Quit, file menu */
680 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "quitter1")), "activate",
681 : G_CALLBACK (on_quitter1_activate), main_window);
682 :
683 : /* New, file menu */
684 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "nouveau1")), "activate",
685 : G_CALLBACK (on_nouveau1_activate), main_window);
686 :
687 : /* Open, file menu */
688 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "ouvrir1")), "activate",
689 : G_CALLBACK (on_ouvrir1_activate), main_window);
690 :
691 : /* Save, file menu */
692 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "save")), "activate",
693 : G_CALLBACK (on_save_activate), main_window);
694 :
695 : /* Save As, file menu */
696 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "save_as")), "activate",
697 : G_CALLBACK (on_save_as_activate), main_window);
698 :
699 : /* Cut, edit menu */
700 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "couper1")), "activate",
701 : G_CALLBACK (on_couper1_activate), main_window);
702 :
703 : /* Copy, edit menu */
704 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "copier1")), "activate",
705 : G_CALLBACK (on_copier1_activate), main_window);
706 :
707 : /* Paste, edit menu */
708 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "coller1")), "activate",
709 : G_CALLBACK (on_coller1_activate), main_window);
710 :
711 :
712 : /* about dialog box */
713 1 : g_signal_connect (G_OBJECT(heraia_get_widget(main_window->xmls->main, "a_propos1")), "activate",
714 : G_CALLBACK(a_propos_activate), main_window);
715 :
716 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "about_dialog")), "close",
717 : G_CALLBACK(a_propos_close), main_window);
718 :
719 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "about_dialog")), "response",
720 : G_CALLBACK(a_propos_response), main_window);
721 :
722 1 : g_signal_connect(G_OBJECT(heraia_get_widget(main_window->xmls->main, "about_dialog")), "delete-event",
723 : G_CALLBACK(a_propos_delete), main_window);
724 :
725 :
726 : /* main window killed or destroyed */
727 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "main_window")), "delete_event",
728 : G_CALLBACK (delete_main_window_event), NULL);
729 :
730 1 : g_signal_connect (G_OBJECT (heraia_get_widget(main_window->xmls->main, "main_window")), "destroy",
731 : G_CALLBACK (on_quitter1_activate), NULL);
732 :
733 1 : }
734 :
735 : /**
736 : * Loads, if possible, the glade xml file and then connects the
737 : * signals and inits the following windows :
738 : * - log window
739 : * - data_interpretor window
740 : * - list data types
741 : */
742 : int load_heraia_ui(heraia_window_t *main_window)
743 1 : {
744 1 : gboolean success = FALSE;
745 :
746 : /* load the XML interfaces (main & treatment) */
747 1 : success = load_heraia_glade_xml(main_window);
748 :
749 1 : if (success == TRUE)
750 : {
751 : /* Heraia UI signals */
752 1 : if (main_window->debug == TRUE)
753 : {
754 1 : fprintf(stdout, "connecting heraia_ui signals ");
755 : }
756 :
757 1 : heraia_ui_connect_signals(main_window);
758 :
759 1 : if (main_window->debug == TRUE)
760 : {
761 1 : fprintf(stdout, " [Done]\n");
762 : }
763 :
764 :
765 : /* The Log window */
766 1 : if (main_window->debug == TRUE)
767 : {
768 1 : fprintf(stdout, "log window init interface ");
769 : }
770 :
771 1 : log_window_init_interface(main_window);
772 :
773 1 : if (main_window->debug == TRUE)
774 : {
775 1 : fprintf(stdout, " [Done]\n");
776 : }
777 :
778 :
779 : /* The data interpretor window */
780 1 : if (main_window->debug == TRUE)
781 : {
782 1 : fprintf(stdout, "data interpretor init interface");
783 : }
784 :
785 1 : data_interpretor_init_interface(main_window);
786 :
787 1 : if (main_window->debug == TRUE)
788 : {
789 1 : fprintf(stdout, " [Done]\n");
790 : }
791 :
792 :
793 : /* The list data types window */
794 1 : if (main_window->debug == TRUE)
795 : {
796 1 : fprintf(stdout, "list data types init interface ");
797 : }
798 :
799 1 : list_data_types_init_interface(main_window);
800 :
801 1 : if (main_window->debug == TRUE)
802 : {
803 1 : fprintf(stdout, " [Done]\n");
804 : }
805 :
806 :
807 : /* The data type window (create or edit one type) */
808 1 : if (main_window->debug == TRUE)
809 : {
810 1 : fprintf(stdout, "data type init interface ");
811 : }
812 :
813 1 : data_type_init_interface(main_window);
814 :
815 1 : if (main_window->debug == TRUE)
816 : {
817 1 : fprintf(stdout, " [Done]\n");
818 : }
819 : }
820 :
821 1 : return success;
822 : }
823 :
824 :
825 : /**
826 : * adds a text to a textview
827 : */
828 : void add_text_to_textview(GtkTextView *textview, const char *format, ...)
829 0 : {
830 : va_list args;
831 0 : GtkTextBuffer *tb = NULL;
832 : GtkTextIter iEnd;
833 0 : gchar *display = NULL;
834 0 : GError *err = NULL;
835 :
836 0 : va_start(args, format);
837 0 : display = g_locale_to_utf8(g_strdup_vprintf(format, args), -1, NULL, NULL, &err);
838 0 : va_end(args);
839 :
840 0 : tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)));
841 0 : gtk_text_buffer_get_end_iter(tb, &iEnd);
842 0 : gtk_text_buffer_insert(tb, &iEnd, display, -1);
843 0 : g_free(display);
844 0 : }
845 :
846 :
847 : /**
848 : * Kills the text from a textview
849 : */
850 : void kill_text_from_textview(GtkTextView *textview)
851 0 : {
852 0 : GtkTextBuffer *tb = NULL;
853 : GtkTextIter iStart;
854 : GtkTextIter iEnd;
855 :
856 0 : tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)));
857 0 : gtk_text_buffer_get_start_iter(tb, &iStart);
858 0 : gtk_text_buffer_get_end_iter(tb, &iEnd);
859 0 : gtk_text_buffer_delete (tb, &iStart, &iEnd);
860 0 : }
861 :
862 :
863 : /**
864 : * Try to find the active radio button widget in a group
865 : * This does not take into account inconsistant states
866 : * returns the first active radio button otherwise NULL
867 : */
868 : GtkWidget *gtk_radio_button_get_active(GSList *group)
869 1 : {
870 1 : GSList *tmp_slist = group;
871 :
872 4 : while (tmp_slist)
873 : {
874 3 : if (GTK_TOGGLE_BUTTON (tmp_slist->data)->active)
875 : {
876 1 : return GTK_WIDGET (tmp_slist->data);
877 : }
878 2 : tmp_slist = tmp_slist->next;
879 : }
880 :
881 0 : return NULL;
882 : }
883 :
884 :
885 : /**
886 : * gtk_radio_button_get_active_from_widget:
887 : * @radio_group_member: widget to get radio group from
888 : *
889 : * @returns: the active #GtkRadioButton within the group from
890 : * @radio_group_member
891 : **/
892 : GtkWidget *gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_group_member)
893 1 : {
894 1 : if (radio_group_member)
895 : {
896 1 : return gtk_radio_button_get_active(radio_group_member->group);
897 : }
898 : else
899 : {
900 0 : return NULL;
901 : }
902 : }
903 :
904 :
905 : /**
906 : * Tells whether a GtkCheckMenuItem is Checked or not
907 : */
908 : gboolean is_cmi_checked(GtkWidget *check_menu_item)
909 0 : {
910 0 : return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(check_menu_item));
911 : }
912 :
913 :
914 : /**
915 : * This is a wrapper to the glade xml get widget. It is intended
916 : * to simplify the developpers lives if they have to choose or
917 : * propose other means to do the same thing than libglade (say,
918 : * for example, GtkBuilder :)
919 : */
920 : GtkWidget *heraia_get_widget(GladeXML *xml, gchar *widget_name)
921 89 : {
922 89 : if (xml != NULL && widget_name != NULL)
923 : {
924 89 : return glade_xml_get_widget(xml, widget_name);
925 : }
926 : else
927 : {
928 0 : return NULL;
929 : }
930 : }
931 :
932 :
933 : /**
934 : * Destroys a single widget if it exists
935 : */
936 : void destroy_a_single_widget(GtkWidget *widget)
937 0 : {
938 0 : if (widget != NULL)
939 : {
940 0 : gtk_widget_destroy(widget);
941 : }
942 0 : }
|