Heraia  0.1.8
heraia_ui.c
Go to the documentation of this file.
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 - 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24 /** @file heraia_ui.c
25  * This file has all the functions to manage heraia's ui
26  * - signals definitions and functions
27  * - widgets activations
28  * - closing / openning windows
29  */
30 
31 #include <libheraia.h>
32 
33 static void set_a_propos_properties(GtkWidget *about_dialog);
34 
35 static gboolean load_heraia_xml(heraia_struct_t *main_struct);
36 
37 static void heraia_ui_connect_signals(heraia_struct_t *main_struct);
38 
39 static void record_and_hide_about_box(heraia_struct_t *main_struct);
40 
41 static gboolean unsaved_documents(heraia_struct_t *main_struct);
42 
43 static void close_one_document(heraia_struct_t *main_struct, doc_t *closing_doc, gint index);
44 static gboolean close_a_project(heraia_struct_t *main_struct, const gchar *question);
45 static gboolean close_heraia(heraia_struct_t *main_struct);
46 
47 static void on_projects_close_activate(GtkWidget *widget, gpointer data);
48 static void on_projects_open_activate(GtkWidget *widget, gpointer data);
49 static void on_projects_save_as_activate(GtkWidget *widget, gpointer data);
50 
51 /**
52  * @fn void on_quit_activate(GtkWidget *widget, gpointer data)
53  * Quit, file menu
54  * @param widget : the widget that issued the signal
55  * @param data : user data MUST be heraia_struct_t *main_struct main structure
56  */
57 void on_quit_activate(GtkWidget *widget, gpointer data)
58 {
59  heraia_struct_t *main_struct = (heraia_struct_t *) data;
60  gboolean quit_heraia = FALSE;
61 
62  quit_heraia = close_heraia(main_struct);
63 
64  if (quit_heraia == TRUE)
65  {
66  gtk_main_quit();
67  }
68 }
69 
70 
71 /**
72  * @fn void on_new_activate(GtkWidget *widget, gpointer data)
73  * New, file menu
74  * @param widget : the widget that issued the signal
75  * @param data : user data MUST be heraia_struct_t *main_struct main structure
76  */
77 void on_new_activate(GtkWidget *widget, gpointer data)
78 {
79  heraia_struct_t *main_struct = (heraia_struct_t *) data;
80  Heraia_Document *new_hex_doc = NULL;
81  GtkWidget *new_hex_widget = NULL;
82  doc_t *doc = NULL;
83 
84  new_hex_doc = hex_document_new();
85 
86  if (new_hex_doc != NULL)
87  {
88  new_hex_doc->file_name = g_strdup_printf(Q_("No name"));
89  new_hex_doc->changed = TRUE;
90 
91  /* creating a new view to this new document */
92  new_hex_widget = hex_document_add_view(new_hex_doc);
93 
94  /* Sets some option : insert mode */
95  gtk_hex_set_insert_mode(GTK_HEX(new_hex_widget), TRUE);
96  gtk_hex_show_offsets(GTK_HEX(new_hex_widget), is_toggle_button_activated(main_struct->xmls->main, "mp_display_offset_bt"));
97 
98  /* signal connection on cursor moves */
99  connect_cursor_moved_signal(main_struct, new_hex_widget);
100 
101  /* joining those two new structures in one */
102  doc = new_doc_t(new_hex_doc, new_hex_widget);
103 
104  /* Adding this new doc to the list of docs (here a GPtrArray) */
105  g_ptr_array_add(main_struct->documents, doc);
106 
107  add_new_tab_in_main_window(main_struct, doc);
108  set_notebook_tab_label_color(main_struct, TRUE);
109 
110  grey_main_widgets(main_struct->xmls->main, FALSE);
111 
112  log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Hexwidget : %p"), doc->hex_widget);
113 
114  /* updating the window name */
115  update_main_window_name(main_struct);
116 
117  if (main_struct->current_doc != NULL)
118  {
119  /* Not thread safe here ? */
120  main_struct->event = HERAIA_REFRESH_NEW_FILE;
121  refresh_event_handler(main_struct->current_doc->hex_widget, main_struct);
122  }
123 
124  }
125 }
126 
127 
128 /**
129  * @fn void on_preferences_activate(GtkWidget *widget, gpointer data)
130  * Preferences, file menu :
131  * Displays the preference window (as a modal window)
132  * @param widget : the widget that issued the signal
133  * @param data : user data MUST be heraia_struct_t *main_struct main structure
134  */
135 void on_preferences_activate(GtkWidget *widget, gpointer data)
136 {
137  heraia_struct_t *main_struct = (heraia_struct_t *) data;
138  GtkWidget *pref_window = NULL;
139 
140  pref_window = heraia_get_widget(main_struct->xmls->main, "main_preferences_window");
141 
142  if (pref_window != NULL)
143  {
144  move_and_show_dialog_box(pref_window, main_struct->win_prop->main_pref_window);
145  }
146 
147 }
148 
149 
150 /**
151  * @fn void set_a_propos_properties(GtkWidget *about_dialog)
152  * Sets name and version in the dialog box
153  * @param about_dialog the widget that contain all the about box
154  */
155 static void set_a_propos_properties(GtkWidget *about_dialog)
156 {
157 
158  if (about_dialog != NULL)
159  {
160  gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about_dialog), PACKAGE_NAME);
161  gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about_dialog), PACKAGE_VERSION);
162  }
163 }
164 
165 
166 /**
167  * @fn void a_propos_activate(GtkWidget *widget, gpointer data)
168  * Shows apropos's dialog box
169  * @param widget : the widget that issued the signal
170  * @param data : user data MUST be heraia_struct_t *main_struct main structure
171  */
172 void a_propos_activate(GtkWidget *widget, gpointer data)
173 {
174  heraia_struct_t *main_struct = (heraia_struct_t *) data;
175  GtkWidget *about_dialog = NULL;
176 
177  about_dialog = heraia_get_widget(main_struct->xmls->main, "about_dialog");
178 
179  if (about_dialog != NULL)
180  {
181  set_a_propos_properties(about_dialog);
182  move_and_show_dialog_box(about_dialog, main_struct->win_prop->about_box);
183  }
184 }
185 
186 
187 /**
188  * @fn void move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
189  * Move the dialog box to the wanted position, shows it and says it in the displayed prop
190  * @param dialog_box : the dialog box we want to move and show
191  * @param dialog_prop : window_prop_t properties structure corresponding to the dialog box
192  */
193 void move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
194 {
195  if (dialog_prop != NULL)
196  {
197 
198  if (dialog_prop->displayed == FALSE)
199  {
200  if (dialog_prop->x > 0 && dialog_prop->y > 0)
201  {
202  gtk_window_move(GTK_WINDOW(dialog_box), dialog_prop->x, dialog_prop->y);
203  }
204 
205  if (dialog_prop->width > 0 && dialog_prop->height > 0)
206  {
207  gtk_window_resize(GTK_WINDOW(dialog_box), dialog_prop->width, dialog_prop->height);
208  }
209 
210  gtk_widget_show_all(dialog_box);
211  dialog_prop->displayed = TRUE;
212  }
213  }
214 }
215 
216 
217 /**
218  * @fn void record_dialog_box_position(GtkWidget *dialog_box, window_prop_t *dialog_prop)
219  * Records one dialog position
220  * @param dialog_box : a dialog box from which we want to record the position
221  * @param[in,out] dialog_prop : window_prop_t properties structure corresponding to the dialog box
222  */
223 void record_dialog_box_position(GtkWidget *dialog_box, window_prop_t *dialog_prop)
224 {
225  gint x = 0;
226  gint y = 0;
227  gint width = WPT_DEFAULT_WIDTH;
228  gint height = WPT_DEFAULT_HEIGHT;
229 
230  if (dialog_prop != NULL && dialog_prop->displayed == TRUE)
231  {
232  if (dialog_box != NULL)
233  {
234  gtk_window_get_position(GTK_WINDOW(dialog_box), &x, &y);
235  gtk_window_get_size(GTK_WINDOW(dialog_box), &width, &height);
236  dialog_prop->x = x;
237  dialog_prop->y = y;
238  dialog_prop->width = width;
239  dialog_prop->height = height;
240  }
241  }
242 }
243 
244 
245 /**
246  * @fn void record_all_dialog_box_positions(heraia_struct_t *main_struct)
247  * Records all the positions of the displayed windows
248  * @param[in,out] main_struct : main structure
249  */
251 {
252  GtkWidget *dialog_box = NULL;
253 
254  if (main_struct != NULL &&
255  main_struct->xmls != NULL &&
256  main_struct->xmls->main != NULL &&
257  main_struct->win_prop != NULL &&
258  main_struct->current_DW != NULL)
259  {
260  /* data interpretor */
261  dialog_box = main_struct->current_DW->diw;
262  record_dialog_box_position(dialog_box, main_struct->win_prop->data_interpretor);
263 
264  /* About box */
265  dialog_box = heraia_get_widget (main_struct->xmls->main, "about_dialog");
266  record_dialog_box_position(dialog_box, main_struct->win_prop->about_box);
267 
268  /* Log window */
269  dialog_box = heraia_get_widget (main_struct->xmls->main, "log_window");
270  record_dialog_box_position(dialog_box, main_struct->win_prop->log_box);
271 
272  /* main_dialog */
273  dialog_box = heraia_get_widget (main_struct->xmls->main, "main_window");
274  record_dialog_box_position(dialog_box, main_struct->win_prop->main_dialog);
275 
276  /* plugin_list */
277  dialog_box = heraia_get_widget (main_struct->xmls->main, "plugin_list_window");
278  record_dialog_box_position(dialog_box, main_struct->win_prop->plugin_list);
279 
280  /* list data types */
281  /* dialog_box = heraia_get_widget (main_struct->xmls->main, "list_data_types_window");
282  record_dialog_box_position(dialog_box, main_struct->win_prop->ldt);
283  */
284 
285  /* main_preferences */
286  dialog_box = heraia_get_widget (main_struct->xmls->main, "main_preferences_window");
287  record_dialog_box_position(dialog_box, main_struct->win_prop->main_pref_window);
288 
289  /* goto dialog box */
290  dialog_box = heraia_get_widget (main_struct->xmls->main, "goto_dialog");
291  record_dialog_box_position(dialog_box, main_struct->win_prop->goto_window);
292 
293  /* result window */
294  dialog_box = heraia_get_widget (main_struct->xmls->main, "result_window");
295  record_dialog_box_position(dialog_box, main_struct->win_prop->result_window);
296 
297  /* find window */
298  dialog_box = heraia_get_widget (main_struct->xmls->main, "find_window");
299  record_dialog_box_position(dialog_box, main_struct->win_prop->find_window);
300 
301  /* find and replace window */
302  dialog_box = heraia_get_widget (main_struct->xmls->main, "fr_window");
303  record_dialog_box_position(dialog_box, main_struct->win_prop->fr_window);
304  }
305 }
306 
307 
308 /**
309  * @fn void record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
310  * Record position and hide a dialog box
311  * @param dialog_box : the dialog box we want to record its position and then hide
312  * @param dialog_prop : window_prop_t properties structure corresponding to the dialog box
313  */
314 void record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
315 {
316 
317  if (dialog_prop->displayed == TRUE)
318  {
319  record_dialog_box_position(dialog_box, dialog_prop);
320 
321  gtk_widget_hide(dialog_box);
322  dialog_prop->displayed = FALSE;
323  }
324 }
325 
326 
327 /**
328  * @fn static void record_and_hide_about_box(heraia_struct_t *main_struct)
329  * Record position and hide about dialog box
330  * @param [in,out] main_struct : main structure
331  */
333 {
334  GtkWidget *about_dialog = NULL;
335 
336  about_dialog = heraia_get_widget(main_struct->xmls->main, "about_dialog");
337 
338  if (about_dialog != NULL)
339  {
340  record_and_hide_dialog_box(about_dialog, main_struct->win_prop->about_box);
341  }
342 }
343 
344 
345 /**
346  * @fn void a_propos_response(GtkWidget *widget, gint response, gpointer data)
347  * To close the A propos dialog box (with the "close" button)
348  * @param widget : calling widget (may be NULL as we don't use this)
349  * @param response : may be whatever you want as we neither use this !
350  * @param data : MUST be heraia_struct_t *main_struct main structure
351  */
352 static void a_propos_response(GtkWidget *widget, gint response, gpointer data)
353 {
354  heraia_struct_t *main_struct = (heraia_struct_t *) data;
355  record_and_hide_about_box(main_struct);
356 }
357 
358 
359 /**
360  * @fn void a_propos_close(GtkWidget *widget, gpointer data)
361  * To close the A propos dialog box
362  * @param widget : calling widget (may be NULL as we don't use this)
363  * @param data : MUST be heraia_struct_t *main_struct main structure
364  */
365 static void a_propos_close(GtkWidget *widget, gpointer data)
366 {
367  heraia_struct_t *main_struct = (heraia_struct_t *) data;
368  record_and_hide_about_box(main_struct);
369 }
370 
371 
372 /**
373  * @fn gboolean a_propos_delete(GtkWidget *widget, GdkEvent *event, gpointer data)
374  * To close the A propos dialog box
375  * @param widget : calling widget (may be NULL as we don't use this)
376  * @param event : event associated (may be NULL as we don't use this)
377  * @param data : MUST be heraia_struct_t *main_struct main structure
378  * @return returns TRUE in order to allow other functions to do something with
379  * that event.
380  */
381 static gboolean a_propos_delete(GtkWidget *widget, GdkEvent *event, gpointer data)
382 {
383  heraia_struct_t *main_struct = (heraia_struct_t *) data;
384  record_and_hide_about_box(main_struct);
385 
386  return TRUE;
387 }
388 
389 
390 /**
391  * Undo, edit menu
392  * @param widget : the widget that issued the signal
393  * @param data : user data MUST be heraia_struct_t *main_struct main structure
394  */
395 void on_undo_activate(GtkWidget *widget, gpointer data)
396 {
397  heraia_struct_t *main_struct = (heraia_struct_t *) data;
398  GtkBuilder *xml = NULL;
399  gboolean result = FALSE;
400 
401  if (main_struct != NULL && main_struct->current_doc != NULL && main_struct->xmls->main != NULL)
402  {
403  result = hex_document_undo(main_struct->current_doc->hex_doc);
404 
405  xml = main_struct->xmls->main;
406 
407  if (result == TRUE)
408  {
409  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), TRUE);
410  }
411 
412  if (main_struct->current_doc->hex_doc->undo_top == NULL)
413  { /* No more undos are possible. The document is as the origin ! */
414  set_notebook_tab_label_color(main_struct, FALSE);
415  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), FALSE);
416  main_struct->current_doc->modified = FALSE;
417  }
418  else
419  {
420  set_notebook_tab_label_color(main_struct, TRUE);
421  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), TRUE);
422  }
423 
424  }
425 
426 }
427 
428 
429 /**
430  * Redo, edit menu
431  * @param widget : the widget that issued the signal
432  * @param data : user data MUST be heraia_struct_t *main_struct main structure
433  */
434 void on_redo_activate(GtkWidget *widget, gpointer data)
435 {
436  heraia_struct_t *main_struct = (heraia_struct_t *) data;
437  GtkBuilder *xml = NULL;
438  gboolean result = FALSE;
439 
440  if (main_struct != NULL && main_struct->current_doc != NULL && main_struct->xmls->main != NULL)
441  {
442  result = hex_document_redo(main_struct->current_doc->hex_doc);
443 
444  xml = main_struct->xmls->main;
445 
446  if (result == TRUE)
447  {
448  set_notebook_tab_label_color(main_struct, TRUE);
449  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), TRUE);
450  main_struct->current_doc->modified = TRUE;
451  }
452 
453  if (main_struct->current_doc->hex_doc->undo_stack == NULL || main_struct->current_doc->hex_doc->undo_stack == main_struct->current_doc->hex_doc->undo_top)
454  {
455  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), FALSE);
456  }
457  else
458  {
459  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), TRUE);
460  }
461  }
462 }
463 
464 
465 /**
466  * Delete, edit menu
467  * @param widget : the widget that issued the signal
468  * @param data : user data MUST be heraia_struct_t *main_struct main structure
469  */
470 void on_delete_activate(GtkWidget *widget, gpointer data)
471 {
472  heraia_struct_t *main_struct = (heraia_struct_t *) data;
473 
474  if (main_struct != NULL && main_struct->current_doc != NULL)
475  {
476  gtk_hex_delete_selection(GTK_HEX(main_struct->current_doc->hex_widget));
477  refresh_event_handler(widget, data);
478  }
479 }
480 
481 
482 /**
483  * Cut, edit menu
484  * @param widget : the widget that issued the signal
485  * @param data : user data MUST be heraia_struct_t *main_struct main structure
486  */
487 void on_cut_activate(GtkWidget *widget, gpointer data)
488 {
489  heraia_struct_t *main_struct = (heraia_struct_t *) data;
490 
491  if (main_struct != NULL && main_struct->current_doc != NULL)
492  {
493  gtk_hex_cut_to_clipboard(GTK_HEX(main_struct->current_doc->hex_widget));
494  refresh_event_handler(widget, data);
495  }
496 }
497 
498 
499 /**
500  * Copy, edit menu
501  * @param widget : the widget that issued the signal
502  * @param data : user data MUST be heraia_struct_t *main_struct main structure
503  */
504 void on_copy_activate(GtkWidget *widget, gpointer data)
505 {
506  heraia_struct_t *main_struct = (heraia_struct_t *) data;
507 
508  if (main_struct != NULL && main_struct->current_doc != NULL)
509  {
510  gtk_hex_copy_to_clipboard(GTK_HEX(main_struct->current_doc->hex_widget));
511  }
512 }
513 
514 
515 /**
516  * Paste, edit menu
517  * @param widget : the widget that issued the signal
518  * @param data : user data MUST be heraia_struct_t *main_struct main structure
519  */
520 void on_paste_activate(GtkWidget *widget, gpointer data)
521 {
522  heraia_struct_t *main_struct = (heraia_struct_t *) data;
523 
524  if (main_struct != NULL && main_struct->current_doc != NULL)
525  {
526  gtk_hex_paste_from_clipboard(GTK_HEX(main_struct->current_doc->hex_widget));
527  refresh_event_handler(widget, data);
528  }
529 }
530 
531 
532 /**
533  * Find, Search menu
534  * @param widget : the widget that issued the signal
535  * @param data : user data MUST be heraia_struct_t *main_struct main structure
536  */
537 void on_find_activate(GtkWidget *widget, gpointer data)
538 {
539  heraia_struct_t *main_struct = (heraia_struct_t *) data;
540 
541  if (main_struct != NULL && main_struct->current_doc != NULL)
542  {
543  find_window_show(widget, main_struct);
544  }
545 }
546 
547 
548 /**
549  * Find and replace, Search menu
550  * @param widget : the widget that issued the signal
551  * @param data : user data MUST be heraia_struct_t *main_struct main structure
552  */
553 void on_fr_activate(GtkWidget *widget, gpointer data)
554 {
555  heraia_struct_t *main_struct = (heraia_struct_t *) data;
556 
557  if (main_struct != NULL && main_struct->current_doc != NULL)
558  {
559  fr_window_show(widget, main_struct);
560  }
561 }
562 
563 
564 /**
565  * Find data from type, Search menu
566  * @param widget : the widget that issued the signal
567  * @param data : user data MUST be heraia_struct_t *main_struct main structure
568  */
569 void on_fdft_activate(GtkWidget *widget, gpointer data)
570 {
571  heraia_struct_t *main_struct = (heraia_struct_t *) data;
572 
573  if (main_struct != NULL && main_struct->current_doc != NULL)
574  {
575  fdft_window_show(widget, main_struct);
576  }
577 }
578 
579 
580 
581 /**
582  * This function is refreshing the labels on the main
583  * window in order to reflect cursor position, selected
584  * positions and total selected size.
585  * It is also used to refresh the file label on the tab.
586  * @param main_struct : main structure
587  */
589 {
590  GtkWidget *position_label = NULL;
591  GtkWidget *file_size_label = NULL;
592  GtkWidget *file_sel_label = NULL;
593  GtkWidget *file_sel_size_label = NULL;
594  guint64 position = 0;
595  guint64 file_size = 0;
596  selection_t *sel = NULL;
597  gchar *position_text = NULL;
598  gchar *file_size_text = NULL;
599  gchar *file_sel_text = NULL;
600  gchar *file_sel_size_text = NULL;
601 
602  if (main_struct != NULL)
603  {
604  position_label = heraia_get_widget(main_struct->xmls->main, "file_position_label");
605  file_size_label = heraia_get_widget(main_struct->xmls->main, "file_size_label");
606  file_sel_label = heraia_get_widget(main_struct->xmls->main, "file_selection_label");
607  file_sel_size_label = heraia_get_widget(main_struct->xmls->main, "file_selection_size_label");
608 
609  if (main_struct->current_doc != NULL && main_struct->current_doc->hex_widget != NULL)
610  {
611  position = ghex_get_cursor_position(main_struct->current_doc->hex_widget);
612  file_size = ghex_file_size((Heraia_Hex *) main_struct->current_doc->hex_widget);
613  sel = ghex_get_selection(main_struct->current_doc->hex_widget);
614 
615  /* position begins at 0 and this is not really human readable */
616  /* it's more confusing than anything so we do + 1 */
617  /* To translators : do not translate <small> and such */
618  if (is_toggle_button_activated(main_struct->xmls->main, "mp_thousand_bt") == TRUE)
619  {
620  position_text = g_strdup_printf("<small>%'lu</small>", (unsigned long int) (position + 1));
621  file_size_text = g_strdup_printf("<small>%'lu</small>", (unsigned long int) file_size);
622  file_sel_text = g_strdup_printf("<small>%'lu -> %'lu</small>", (unsigned long int) (sel->start + 1), (unsigned long int) (sel->end + 1));
623  file_sel_size_text = g_strdup_printf("<small>%'li</small>", (unsigned long int) ((sel->end - sel->start) + 1));
624  }
625  else
626  {
627  position_text = g_strdup_printf("<small>%lu</small>", (unsigned long int) (position + 1));
628  file_size_text = g_strdup_printf("<small>%lu</small>", (unsigned long int) file_size);
629  file_sel_text = g_strdup_printf("<small>%lu -> %lu</small>", (unsigned long int) (sel->start + 1), (unsigned long int) (sel->end + 1));
630  file_sel_size_text = g_strdup_printf("<small>%li</small>", (unsigned long int) ((sel->end - sel->start) + 1));
631  }
632 
633  gtk_label_set_markup(GTK_LABEL(position_label), position_text);
634  gtk_label_set_markup(GTK_LABEL(file_size_label), file_size_text);
635  gtk_label_set_markup(GTK_LABEL(file_sel_label), file_sel_text);
636  gtk_label_set_markup(GTK_LABEL(file_sel_size_label), file_sel_size_text);
637 
638  g_free(position_text);
639  g_free(file_size_text);
640  g_free(file_sel_text);
641  g_free(file_sel_size_text);
642  g_free(sel);
643 
644  /* refreshing the tab filename itself if necessary only ! */
645  if (main_struct->current_doc->modified != main_struct->current_doc->hex_doc->changed)
646  {
647  main_struct->current_doc->modified = main_struct->current_doc->hex_doc->changed;
648  set_notebook_tab_label_color(main_struct, main_struct->current_doc->hex_doc->changed);
649 
650  /* If the document changes, then when might undo things ... */
651  gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_undo"), TRUE);
652 
653  }
654 
655  }
656  else
657  {
658  gtk_label_set_text(GTK_LABEL(position_label), "");
659  gtk_label_set_text(GTK_LABEL(file_size_label), "");
660  gtk_label_set_text(GTK_LABEL(file_sel_label), "");
661  gtk_label_set_text(GTK_LABEL(file_sel_size_label), "");
662  }
663  }
664 }
665 
666 
667 /**
668  * This function is here to ensure that everything will be
669  * refreshed upon a signal event.
670  * @warning This function is not thread safe (do not use in a thread)
671  * @todo try to put some mutexes on main_struct->event to make this
672  * thread safe some way
673  * @param widget : the widget that issued the signal
674  * @param data : user data MUST be heraia_struct_t *main_struct main structure
675  */
676 void refresh_event_handler(GtkWidget *widget, gpointer data)
677 {
678  heraia_struct_t *main_struct = (heraia_struct_t *) data;
679 
680  if (main_struct != NULL)
681  {
682  /* Beware, this mechanism is not thread safe ! */
683  if (main_struct->event == HERAIA_REFRESH_NOTHING)
684  {
685  main_struct->event = HERAIA_REFRESH_CURSOR_MOVE;
686  }
687 
688  refresh_data_interpretor_window(widget, main_struct);
689  refresh_all_plugins(main_struct);
690  refresh_file_labels(main_struct);
691 
692  main_struct->event = HERAIA_REFRESH_NOTHING;
693  }
694 }
695 
696 
697 /**
698  * This handles the menuitem "Ouvrir" to open a file
699  * @warning This function is not thread safe (do not use in a thread)
700  * @todo try to put some mutexes on main_struct->event to make this
701  * thread safe some way
702  * @param widget : the widget that issued the signal
703  * @param data : user data MUST be heraia_struct_t *main_struct main structure
704  */
705 void on_open_activate(GtkWidget *widget, gpointer data)
706 {
707  heraia_struct_t *main_struct = (heraia_struct_t *) data;
708  GSList *list = NULL;
709  GSList *head = NULL;
710  gboolean success = FALSE;
711 
712  list = select_file_to_load(main_struct, TRUE, N_("Select a file to analyse"));
713 
714  if (list != NULL)
715  {
716  head = list;
717  while (list != NULL)
718  {
719  success = load_file_to_analyse(main_struct, list->data);
720  g_free(list->data);
721  list = g_slist_next(list);
722  }
723 
724  g_slist_free(head);
725 
726  if (success == TRUE && main_struct->current_doc != NULL)
727  {
728  /* Not thread safe here ? */
729  main_struct->event = HERAIA_REFRESH_NEW_FILE;
730  refresh_event_handler(main_struct->current_doc->hex_widget, main_struct);
731  }
732  }
733 }
734 
735 
736 /**
737  * Searches in a notebook's tabs for a particular widget and returns the number
738  * of the corresponding tab if it exists, -1 otherwise
739  * @param main_struct : main structure
740  * @param notebbok_name : the name of the notebook in the structure
741  * @param to_find : a GtkWidget that we want to find in the main notebook tabs
742  * @return a gint as the tab number that contains the widget "to_find" or -1 if
743  * not found
744  */
745 gint find_tab_number_from_widget(heraia_struct_t *main_struct, gchar *notebook_name, GtkWidget *to_find)
746 {
747  GtkWidget *notebook = NULL; /** GtkWidget *notebook is the notenook on the main window */
748  GtkWidget *page = NULL; /** GtkWidget *page are the pages on the notebook */
749  GtkWidget *tab_label = NULL; /** GtkWidget *tab_label is the tab label (hbox + others) */
750  gint nb_pages = 0; /** gint nb_pages reflects the number of pages in the notebook */
751  gint i = 0;
752  gboolean found = FALSE; /** gboolean found is True when the widget has been found */
753  GList *children = NULL; /** GList *children a list of the Children from the tab label */
754 
755  notebook = heraia_get_widget(main_struct->xmls->main, notebook_name);
756 
757  nb_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
758 
759  i = 0;
760  found = FALSE;
761  while (i < nb_pages && found == FALSE)
762  {
763  page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
764 
765  if (page != NULL)
766  {
767  tab_label = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
768 
769  if (GTK_IS_BOX(tab_label))
770  {
771  children = gtk_container_get_children(GTK_CONTAINER(tab_label));
772  }
773 
774  while (children != NULL && found == FALSE)
775  {
776  if (children->data == to_find)
777  {
778  found = TRUE;
779  }
780  else
781  {
782  children = g_list_next(children);
783  }
784  }
785  }
786 
787  if (found == FALSE)
788  {
789  i++;
790  }
791  }
792 
793  if (found == TRUE)
794  {
795  return i;
796  }
797  else
798  {
799  return -1;
800  }
801 }
802 
803 
804 /**
805  * Closes an entire project
806  * @param widget : the widget that issued the signal
807  * @param data : user data MUST be heraia_struct_t *main_struct main structure
808  */
809 static void on_projects_close_activate(GtkWidget *widget, gpointer data)
810 {
811  heraia_struct_t *main_struct = (heraia_struct_t *) data;
812 
813  if (main_struct != NULL)
814  {
815  close_a_project(main_struct, N_("Do you want to close the project"));
816  }
817 }
818 
819 
820 /**
821  * Saves a project in a new file (does not close the project itself)
822  * @param widget : the widget that issued the signal
823  * @param data : user data MUST be heraia_struct_t *main_struct main structure
824  */
825 static void on_projects_save_as_activate(GtkWidget *widget, gpointer data)
826 {
827  heraia_struct_t *main_struct = (heraia_struct_t *) data;
828  gchar *filename = NULL; /** gchar *filename is auto malloc'ed, do not free ! */
829 
830  if (main_struct != NULL)
831  {
832  filename = select_a_file_to_save(main_struct);
833 
834  if (filename != NULL)
835  {
836  free_preference_struct(main_struct->prefs);
837  main_struct->prefs = init_preference_struct(g_path_get_dirname(filename),g_path_get_basename(filename));
838  save_preferences(main_struct, main_struct->prefs);
839  }
840  }
841 }
842 
843 
844 /**
845  * Opens a project from a file : closes all documents an imports new ones ...
846  * @param widget : the widget that issued the signal
847  * @param data : user data MUST be heraia_struct_t *main_struct main structure
848  */
849 static void on_projects_open_activate(GtkWidget *widget, gpointer data)
850 {
851  heraia_struct_t *main_struct = (heraia_struct_t *) data;
852  gchar *filename = NULL;
853  GSList *list = NULL;
854 
855  if (main_struct != NULL)
856  {
857  /* We except a list with only one element (no multiple selection allowed) */
858  list = select_file_to_load(main_struct, FALSE, (gchar *) Q_("Select a project to load"));
859 
860  if (list != NULL && list->data != NULL)
861  {
862  /* Closing the projects */
863  on_projects_close_activate(widget, data);
864 
865  /* Opening the new project */
866  filename = list->data;
867  log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Loading project %s"), filename);
868  main_struct->prefs = init_preference_struct(g_path_get_dirname(filename), g_path_get_basename(filename));
869  load_preferences(main_struct, main_struct->prefs);
870 
871  /* . Updating things in the interface */
872  gtk_widget_show_all(heraia_get_widget(main_struct->xmls->main, "file_notebook"));
873  init_window_states(main_struct);
874  g_slist_free(list);
875  }
876  }
877 }
878 
879 
880 /**
881  * Closes one document in heraia. Does not do any updates of the interface.
882  * @param main_struct : main structure
883  * @param closing_doc : the doc_t * document to be closed
884  * @param index : the index in the array of documents of the closing_doc
885  * document
886  */
887 static void close_one_document(heraia_struct_t *main_struct, doc_t *closing_doc, gint index)
888 {
889  GtkWidget *notebook = NULL; /** GtkWidget *notebook is the notenook on the main window */
890 
891  if (main_struct != NULL && main_struct->documents != NULL)
892  {
893  /* Removing the index in the array */
894  g_ptr_array_remove_index(main_struct->documents, index);
895 
896  /* Removes all results beeing associated with this document */
897  rw_remove_all_tabs(main_struct, closing_doc);
898 
899  /* And removing it in the notebook */
900  notebook = heraia_get_widget(main_struct->xmls->main, "file_notebook");
901  gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), index);
902 
903  /* kills the widget and the document */
904  close_doc_t(closing_doc);
905  }
906 }
907 
908 
909 /**
910  * Closes an opened file
911  * @param widget : the widget that issued the signal
912  * @param data : user data MUST be heraia_struct_t *main_struct main structure
913  */
914 void on_close_activate(GtkWidget *widget, gpointer data)
915 {
916  heraia_struct_t *main_struct = (heraia_struct_t *) data;
917  doc_t *closing_doc = NULL; /** doc_t *closing_doc the current document to close in heraia */
918  doc_t *document = NULL; /** doc_t *document to iterate over the array of documents */
919  GtkWidget *notebook = NULL; /** GtkWidget *notebook is the notenook on the main window */
920  GtkWidget *dialog = NULL; /** GtkWidget *dialog is the dialog box */
921  GtkWidget *parent = NULL; /** GtkWidget *parent is the parent widget for the dialog box */
922  gint result = 0; /** gint result the result from the dialog box */
923  gint index = -1;
924  gint i = 0;
925  gint tab_number = 0;
926  gboolean is_current_doc = FALSE; /** gboolean is_current_doc says wheter the document
927  that we are trying to close is the current one or not */
928 
929  if (main_struct != NULL && main_struct->current_doc != NULL)
930  {
931  /* Guessing where the user asked to close the document */
932  if (GTK_IS_BUTTON(widget))
933  { /* From the tab */
934  /* Guessing which document the user has closed */
935  tab_number = find_tab_number_from_widget(main_struct, "file_notebook", widget); /** @todo test the returned value here before doing anything else */
936  closing_doc = g_ptr_array_index(main_struct->documents, tab_number);
937  is_current_doc = (closing_doc == main_struct->current_doc);
938  }
939  else
940  { /* From the menu */
941  closing_doc = main_struct->current_doc;
942  is_current_doc = TRUE;
943  }
944 
945  log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Closing document %s"), doc_t_document_get_filename(closing_doc));
946 
947  if (closing_doc->modified == TRUE)
948  {
949  /* Displays a dialog box that let the user choose what to do */
950  parent = heraia_get_widget(main_struct->xmls->main, "main_window");
951 
952  dialog = gtk_message_dialog_new(GTK_WINDOW(parent), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, Q_("This document has been edited and is not saved !"));
953  gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog), Q_("Do you want to close it without saving it ?"));
954 
955  result = gtk_dialog_run(GTK_DIALOG(dialog));
956 
957  gtk_widget_destroy(dialog);
958 
959  switch (result)
960  {
961  case GTK_RESPONSE_YES: /* Will continue if we say Yes */
962  break;
963 
964  default: /* Stops closing if we say No */
965  return;
966  break;
967  }
968  }
969 
970  /* Try to catch the index of the closing document */
971  i = 0;
972  index = -1;
973  while (i < main_struct->documents->len && index == -1)
974  {
975  document = g_ptr_array_index(main_struct->documents, i);
976  if (document == closing_doc)
977  {
978  index = i;
979  }
980  i++;
981  }
982 
983  if (index >= 0)
984  {
985  close_one_document(main_struct, closing_doc, index);
986 
987  /* Try to find out the new current document */
988  /* We do not need to update if the current doc is not closed ! */
989  if (is_current_doc == TRUE)
990  {
991  if (main_struct->documents->len > 0)
992  {
993  /* there is still some documents opened (at least one) */
994  if (index == 0)
995  {
996  main_struct->current_doc = g_ptr_array_index(main_struct->documents, 0);
997  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
998  }
999  else
1000  {
1001  main_struct->current_doc = g_ptr_array_index(main_struct->documents, index - 1);
1002  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), index - 1);
1003  }
1004  }
1005  else
1006  {
1007  /* No more documents openned */
1008  main_struct->current_doc = NULL;
1009  grey_main_widgets(main_struct->xmls->main, TRUE);
1010  }
1011  }
1012  /* updating things in conformance to the new situation */
1013  refresh_event_handler(notebook, main_struct);
1014  update_main_window_name(main_struct);
1015  }
1016  }
1017 }
1018 
1019 
1020 /**
1021  * Here we attemp to save the edited file
1022  * @todo be more accurate on error (error type, message and filename) returns
1023  * we should return something at least ...
1024  * @param widget : the widget that issued the signal
1025  * @param data : user data MUST be heraia_struct_t *main_struct main structure
1026  */
1027 void on_save_activate(GtkWidget *widget, gpointer data)
1028 {
1029  heraia_struct_t *main_struct = (heraia_struct_t *) data;
1030  HERAIA_ERROR erreur = HERAIA_NOERR;
1031  gchar *filename = NULL;
1032 
1033  if (main_struct != NULL && main_struct->current_doc != NULL)
1034  {
1035  erreur = heraia_hex_document_save(main_struct->current_doc);
1036 
1037  if (erreur != HERAIA_NOERR)
1038  {
1039  filename = doc_t_document_get_filename(main_struct->current_doc);
1040  log_message(main_struct, G_LOG_LEVEL_ERROR, Q_("Error while saving file %s !"), filename);
1041  }
1042  else
1043  {
1044  set_notebook_tab_label_color(main_struct, FALSE);
1045  main_struct->current_doc->modified = FALSE; /* document has just been saved (thus it is not modified !) */
1046  }
1047  }
1048 }
1049 
1050 
1051 /**
1052  * @fn void on_save_as_activate(GtkWidget *widget, gpointer data)
1053  * This handle the save_as menu entry (here the filename changes)
1054  * @param widget : the widget that issued the signal
1055  * @param data : user data MUST be heraia_struct_t *main_struct main structure
1056  */
1057 void on_save_as_activate(GtkWidget *widget, gpointer data)
1058 {
1059  heraia_struct_t *main_struct = (heraia_struct_t *) data;
1060  HERAIA_ERROR erreur = HERAIA_NOERR;
1061  gchar *filename = NULL; /** gchar *filename is auto malloc'ed, do not free */
1062 
1063  if (main_struct != NULL && main_struct->current_doc != NULL)
1064  {
1065  filename = select_a_file_to_save(main_struct);
1066 
1067  if (filename != NULL)
1068  {
1069  erreur = heraia_hex_document_save_as(main_struct->current_doc, filename);
1070  }
1071  else
1072  {
1073  erreur = HERAIA_CANCELLED;
1074  }
1075 
1076  if (erreur != HERAIA_NOERR)
1077  {
1078  if (erreur == HERAIA_CANCELLED)
1079  {
1080  log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Saving file as... : operation cancelled."));
1081  }
1082  else
1083  {
1084  log_message(main_struct, G_LOG_LEVEL_ERROR, Q_("Error while saving file as %s"), doc_t_document_get_filename(main_struct->current_doc));
1085  }
1086  }
1087  else
1088  {
1089  /* updating the window name and tab's name */
1090  update_main_window_name(main_struct);
1091  set_notebook_tab_name(main_struct);
1092  main_struct->current_doc->modified = FALSE; /* document has just been saved (thus it is not modified !) */
1093  log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("File %s saved and now edited."), doc_t_document_get_filename(main_struct->current_doc));
1094  }
1095  }
1096 }
1097 
1098 
1099 /**
1100  * @fn void on_DIMenu_activate(GtkWidget *widget, gpointer data)
1101  * This handles the menuitem "Data Interpretor" that
1102  * shows or hides the data interpretor window
1103  * @param widget : the widget that issued the signal
1104  * @param data : user data MUST be heraia_struct_t *main_struct main structure
1105  */
1106 void on_DIMenu_activate(GtkWidget *widget, gpointer data)
1107 {
1108 
1109  heraia_struct_t *main_struct = (heraia_struct_t *) data;
1110  data_window_t *dw = NULL; /** data_window_t *dw is a structure for the data interpretor */
1111  GtkNotebook *notebook = NULL; /** GtkNotebook *notebook is the data interpretor's notebook */
1112 
1113  if (main_struct != NULL)
1114  {
1115  dw = main_struct->current_DW;
1116 
1117  if (dw != NULL)
1118  {
1119  if (dw->diw == NULL)
1120  {
1121  dw->diw = heraia_get_widget(main_struct->xmls->main, "data_interpretor_window");
1122  }
1123 
1124  if (dw->diw != NULL)
1125  {
1126  notebook = GTK_NOTEBOOK(heraia_get_widget(main_struct->xmls->main, "diw_notebook"));
1127 
1128  if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(heraia_get_widget(main_struct->xmls->main, "DIMenu"))) == TRUE)
1129  {
1130  /* Setting the first page of the notebook as default (Numbers) */
1131  gtk_notebook_set_current_page(notebook, dw->tab_displayed);
1132 
1133  /* moving to the right position */
1135 
1136  refresh_data_interpretor_window(widget, data);
1137  }
1138  else
1139  {
1140  /* recording some prefs from the dialog : position + opened tab */
1141  dw->tab_displayed = gtk_notebook_get_current_page(notebook);
1143  }
1144  }
1145  }
1146  }
1147 }
1148 
1149 
1150 /**
1151  * Called when tests submenu is activated
1152  * @param widget : the widget that issued the signal
1153  * @param data : user data MUST be heraia_struct_t *main_struct main structure
1154  */
1155 void on_tests_menu_activate(GtkWidget *widget, gpointer data)
1156 {
1157  heraia_struct_t *main_struct = (heraia_struct_t *) data;
1158  gboolean result = FALSE;
1159 
1160  if (main_struct != NULL)
1161  {
1162  result = tests_ui(main_struct);
1163 
1164  if (result == TRUE)
1165  {
1166  log_message(main_struct, G_LOG_LEVEL_INFO, Q_("All tests went Ok."));
1167  }
1168  else
1169  {
1170  log_message(main_struct, G_LOG_LEVEL_WARNING, Q_("Some tests failed."));
1171  }
1172  }
1173 }
1174 
1175 
1176 /**
1177  * @fn delete_main_struct_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1178  * When the user destroys or delete the main window
1179  * @param widget : calling widget
1180  * @param event : event associated (may be NULL as we don't use this here)
1181  * @param data : MUST be heraia_struct_t *main_struct main structure
1182  */
1183 gboolean delete_main_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1184 {
1185 
1186  on_quit_activate(widget, data);
1187 
1188  /* If we are leaving heraia, we are not supposed to be here ! */
1189  return TRUE;
1190 }
1191 
1192 
1193 /**
1194  * @fn gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1195  * call back function for the data interpretor window destruction
1196  * @param widget : calling widget (may be NULL as we don't use this here)
1197  * @param event : event associated (may be NULL as we don't use this here)
1198  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
1199  */
1200 gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1201 {
1202  heraia_struct_t *main_struct = (heraia_struct_t *) data;
1203 
1204  g_signal_emit_by_name(heraia_get_widget(main_struct->xmls->main, "DIMenu"), "activate");
1205 
1206  return TRUE;
1207 }
1208 
1209 
1210 /**
1211  * @fn void destroy_dt_window(GtkWidget *widget, GdkEvent *event, gpointer data)
1212  * call back function for the data interpretor window destruction
1213  * @param widget : calling widget (may be NULL as we don't use this here)
1214  * @param event : event associated (may be NULL as we don't use this here)
1215  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
1216  */
1217 void destroy_dt_window(GtkWidget *widget, GdkEvent *event, gpointer data)
1218 {
1219  heraia_struct_t *main_struct = (heraia_struct_t *) data;
1220 
1221  g_signal_emit_by_name(heraia_get_widget(main_struct->xmls->main, "DIMenu"), "activate");
1222 }
1223 
1224 
1225 /**
1226  * What to do when a change occurs in tabs (user selected a particular
1227  * tab)
1228  * @param notebook : the widget that issued this signal
1229  * @param page : the new current page
1230  * @param tab_num : index of this page
1231  * @param data : MUST be heraia_struct_t *main_struct !
1232  */
1233 gboolean file_notebook_tab_changed(GtkNotebook *notebook, GtkWidget *page, gint tab_num, gpointer data)
1234 {
1235  heraia_struct_t *main_struct = (heraia_struct_t *) data;
1236 
1237  if (main_struct != NULL)
1238  {
1239  if (tab_num >= 0 && tab_num <= main_struct->documents->len)
1240  {
1241  /* Current document is now from the selected tab */
1242  main_struct->current_doc = g_ptr_array_index(main_struct->documents, tab_num);
1243 
1244  /* Changing main window's name */
1245  update_main_window_name(main_struct);
1246 
1247  /* Refreshing the view */
1248  main_struct->event = HERAIA_REFRESH_TAB_CHANGED;
1249  refresh_event_handler(GTK_WIDGET(notebook), main_struct);
1250  main_struct->event = HERAIA_REFRESH_NOTHING;
1251  }
1252  }
1253 
1254  return TRUE;
1255 }
1256 
1257 /* End of call back functions that handle the data interpretor window */
1258 
1259 
1260 /**
1261  * @fn static gchar *make_absolute_path(gchar *filename)
1262  * Returns an absolute path to the filename
1263  * the string should be freed when no longer needed
1264  * very UGLy !
1265  * @todo do something without any system calls !!!
1266  * @param filename : relative notation filename from which to extract an
1267  * absolute path
1268  * @return returns a string with the absolute path which should be freed when
1269  * no longer needed
1270  */
1271 static gchar *make_absolute_path(gchar *filename)
1272 {
1273  gchar *current_dir = NULL;
1274  gchar *new_dir = NULL;
1275 
1276  if (g_path_is_absolute(filename) == TRUE)
1277  {
1278  /* if the filename is already in an absolute format */
1279  return g_path_get_dirname(filename);
1280  }
1281  else
1282  {
1283  current_dir = g_get_current_dir();
1284  new_dir = g_path_get_dirname(filename);
1285 
1286  if (g_chdir(new_dir) == 0)
1287  {
1288  g_free(new_dir);
1289  new_dir = g_get_current_dir();
1290  g_chdir(current_dir);
1291  g_free(current_dir);
1292 
1293  return new_dir;
1294  }
1295  else
1296  {
1297  g_free(current_dir);
1298 
1299  return NULL;
1300  }
1301  }
1302 }
1303 
1304 
1305 /**
1306  * Sets the working directory for the file chooser to the directory of the
1307  * filename (even if filename is a relative filename such as ../docs/test_file)
1308  * @param file_chooser : An initialized GtkFileChooser
1309  * @param filename : a filename (one previously openned)
1310  */
1311 void set_the_working_directory(GtkFileChooser *file_chooser, gchar *filename)
1312 {
1313  gchar *dirname = NULL; /** gchar *dirname is the directory where we want to be, at first, in the file chooser */
1314 
1315  dirname = make_absolute_path(filename);
1316 
1317  if (dirname != NULL)
1318  {
1319  gtk_file_chooser_set_current_folder(file_chooser, dirname);
1320  g_free(dirname);
1321  }
1322 }
1323 
1324 
1325 /**
1326  * This function does open a file selector dialog box and returns the selected
1327  * filename.
1328  * @param main_struct : main structure
1329  * @param multiple : to say wether we want multiple selection be possible or not
1330  * @param message : the message to print in the title's dialog box
1331  * @return returns a list of filenames to be loaded (if any)
1332  */
1333 GSList *select_file_to_load(heraia_struct_t *main_struct, gboolean multiple, gchar *message)
1334 {
1335  GtkWidget *parent = NULL; /** GtkWidget *parent is a parent window (we use main_struct) */
1336  GtkFileChooser *file_chooser = NULL;
1337  GSList *list = NULL; /** GSList *list is a list of selected (if any) filenames to be openned */
1338 
1339  parent = heraia_get_widget(main_struct->xmls->main, "main_window");
1340 
1341  file_chooser = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(message,
1342  GTK_WINDOW(parent),
1343  GTK_FILE_CHOOSER_ACTION_OPEN,
1344  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1345  GTK_STOCK_OPEN, GTK_RESPONSE_OK,
1346  NULL));
1347 
1348  gtk_window_set_modal(GTK_WINDOW(file_chooser), TRUE);
1349  gtk_file_chooser_set_select_multiple(file_chooser, multiple);
1350 
1351  /**
1352  * We want the file selection path to be the one of the current
1353  * opened file if any !
1354  */
1355  if (doc_t_document_get_filename(main_struct->current_doc) != NULL)
1356  {
1358  }
1359 
1360  switch (gtk_dialog_run(GTK_DIALOG(file_chooser)))
1361  {
1362  case GTK_RESPONSE_OK:
1363 
1364  list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(file_chooser));
1365  gtk_widget_destroy(GTK_WIDGET(file_chooser));
1366 
1367  return list;
1368  break;
1369 
1370  case GTK_RESPONSE_CANCEL:
1371  default:
1372  gtk_widget_destroy(GTK_WIDGET(file_chooser));
1373 
1374  return NULL;
1375  break;
1376  }
1377 }
1378 
1379 
1380 /**
1381  * This function opens a dialog box that allow one to choose a
1382  * file name to the file which is about to be saved
1383  * @param main_struct : main structure
1384  * @return returns complete filename (path and filename)
1385  */
1387 {
1388  GtkWidget *parent = NULL; /** GtkWidget *parent is a parent window (we use main_struct) */
1389  GtkFileChooser *fcd = NULL;
1390  gchar *filename = NULL;
1391 
1392  parent = heraia_get_widget(main_struct->xmls->main, "main_window");
1393 
1394  /* Selection a name to the file to save */
1395  fcd = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(Q_("Save As..."),
1396  GTK_WINDOW(parent),
1397  GTK_FILE_CHOOSER_ACTION_SAVE,
1398  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1399  GTK_STOCK_SAVE, GTK_RESPONSE_OK,
1400  NULL));
1401 
1402  /* window properties : modal, without multi-selection and with confirmation */
1403  gtk_window_set_modal(GTK_WINDOW(fcd), TRUE);
1404  gtk_file_chooser_set_select_multiple(fcd, FALSE);
1405  gtk_file_chooser_set_do_overwrite_confirmation(fcd, TRUE);
1406 
1407  /* we do want to have the file's directory where to save the new file */
1408  if (doc_t_document_get_filename(main_struct->current_doc) != NULL)
1409  {
1411  }
1412 
1413  switch(gtk_dialog_run(GTK_DIALOG(fcd)))
1414  {
1415  case GTK_RESPONSE_OK:
1416  /* retrieving the filename */
1417  filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fcd));
1418  break;
1419  default:
1420  filename = NULL;
1421  break;
1422  }
1423 
1424  gtk_widget_destroy(GTK_WIDGET(fcd));
1425 
1426  return filename;
1427 }
1428 
1429 
1430 /**
1431  * Update main window heraia's name to reflect the current edited file
1432  * @param main_struct : main structure
1433  */
1435 {
1436  GtkWidget *widget = NULL;
1437  gchar *filename = NULL;
1438  gchar *whole_filename = NULL;
1439 
1440  if (main_struct != NULL && main_struct->current_doc != NULL)
1441  {
1442  widget = heraia_get_widget(main_struct->xmls->main, "main_window");
1443 
1444  whole_filename = doc_t_document_get_filename(main_struct->current_doc);
1445 
1446  filename = g_filename_display_basename(whole_filename);
1447 
1448  gtk_window_set_title(GTK_WINDOW(widget), filename);
1449  }
1450  else if (main_struct != NULL)
1451  {
1452  widget = heraia_get_widget(main_struct->xmls->main, "main_window");
1453  gtk_window_set_title(GTK_WINDOW(widget), "Heraia");
1454  }
1455 }
1456 
1457 
1458 /**
1459  * Tries to find the label contained in the hbox
1460  * @param hbox : the hbox widget containing one GtkLabel
1461  * @return the label or NULL if not found
1462  */
1463 GtkWidget *find_label_from_hbox(GtkWidget *hbox)
1464 {
1465  GList *children = NULL; /** GList *children is the list of children in the hbox widget */
1466  gboolean found = FALSE;
1467 
1468  if (hbox != NULL)
1469  {
1470  children = gtk_container_get_children(GTK_CONTAINER(hbox));
1471  found = FALSE;
1472 
1473  while (children != NULL && found == FALSE)
1474  {
1475  if (GTK_IS_LABEL(children->data))
1476  {
1477  found = TRUE;
1478  }
1479  else
1480  {
1481  children = g_list_next(children);
1482  }
1483  }
1484 
1485  if (found == TRUE)
1486  {
1487  return children->data;
1488  }
1489  else
1490  {
1491  return NULL;
1492  }
1493  }
1494  else
1495  {
1496  return NULL;
1497  }
1498 }
1499 
1500 
1501 /**
1502  * Sets notebook's tab's name. This function should only be called
1503  * when a new filename was set (open and save as functions)
1504  * @param main_struct : main structure
1505  */
1507 {
1508  GtkWidget *notebook = NULL; /**< file notebook in main window */
1509  GtkWidget *page = NULL; /**< Current page for the file notebook */
1510  GtkWidget *hbox = NULL; /**< container that has the label and the button */
1511  GtkWidget *label = NULL; /**< tab's label */
1512  doc_t *doc = NULL; /**< corresponding tab's document */
1513  gchar *filename = NULL;
1514  gchar *whole_filename;
1515  gint current = 0; /**< index of the current tab displayed */
1516  gchar *markup= NULL; /**< markup text */
1517 
1518  if (main_struct != NULL && main_struct->current_doc != NULL)
1519  {
1520  notebook = heraia_get_widget(main_struct->xmls->main, "file_notebook");
1521  current = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
1522  page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), current);
1523  hbox = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
1524  label = find_label_from_hbox(hbox);
1525 
1526  if (label != NULL)
1527  {
1528  doc = g_ptr_array_index(main_struct->documents, current);
1529  whole_filename = doc_t_document_get_filename(doc);
1530 
1531  if (whole_filename != NULL)
1532  {
1533  filename = g_filename_display_basename(whole_filename);
1534  markup = g_markup_printf_escaped("%s", filename);
1535  gtk_label_set_markup(GTK_LABEL(label), markup);
1536  gtk_widget_set_tooltip_text(label, g_filename_display_name(whole_filename));
1537  g_free(markup);
1538  }
1539  }
1540  }
1541 }
1542 
1543 
1544 /**
1545  * Set the style for the label
1546  * @param main_struct : main structure
1547  * @param color : If color is TRUE sets the color for the file tab's label
1548  * If not, then sets it to default
1549  */
1550 void set_notebook_tab_label_color(heraia_struct_t *main_struct, gboolean color)
1551 {
1552  GtkWidget *notebook = NULL; /**< file notebook in main window */
1553  GtkWidget *page = NULL; /**< Current page for the file notebook */
1554  GtkWidget *label = NULL; /**< tab's label */
1555  GtkWidget *menu_label = NULL; /**< menu tab's label */
1556  GtkWidget *hbox = NULL; /**< container that has the label and the button */
1557  gint current = 0; /**< index of the current tab displayed */
1558  gchar *markup= NULL; /**< markup text */
1559  gchar *text = NULL; /**< label's text */
1560 
1561  if (main_struct != NULL && main_struct->current_doc != NULL)
1562  {
1563  notebook = heraia_get_widget(main_struct->xmls->main, "file_notebook");
1564  current = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
1565  page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), current);
1566  hbox = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
1567  label = find_label_from_hbox(hbox);
1568 
1569  if (label != NULL)
1570  {
1571  text = g_strdup(gtk_label_get_text(GTK_LABEL(label)));
1572 
1573  if (color == TRUE)
1574  {
1575  markup = g_markup_printf_escaped("<span foreground=\"blue\">%s</span>", text);
1576  }
1577  else
1578  {
1579  markup = g_markup_printf_escaped("%s", text);
1580  }
1581 
1582  log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Changing color for filename %s in tab : %d"), markup, current);
1583  gtk_label_set_markup(GTK_LABEL(label), markup);
1584  menu_label = gtk_label_new(NULL);
1585  gtk_label_set_markup(GTK_LABEL(menu_label), markup);
1586  gtk_notebook_set_menu_label(GTK_NOTEBOOK(notebook), page, menu_label);
1587 
1588  g_free(markup);
1589  g_free(text);
1590  }
1591  }
1592 }
1593 
1594 
1595 /**
1596  * Hides or grey all widgets that needs an open file when boolean greyed is
1597  * TRUE. Also sets the current page of the notebook to the first one.
1598  * @param xml : GtkBuilder XML main structure
1599  * @param greyed : boolean (TRUE to hide an grey widgets)
1600  */
1601 void grey_main_widgets(GtkBuilder *xml, gboolean greyed)
1602 {
1603  GtkWidget *notebook = NULL; /* file notebook in main window */
1604 
1605  if (xml != NULL)
1606  {
1607  notebook = heraia_get_widget(xml, "file_notebook");
1608 
1609  if (greyed == TRUE)
1610  {
1611  gtk_widget_set_sensitive(heraia_get_widget(xml, "save"), FALSE);
1612  gtk_widget_set_sensitive(heraia_get_widget(xml, "save_as"), FALSE);
1613  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_cut"), FALSE);
1614  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_copy"), FALSE);
1615  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_paste"), FALSE);
1616  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_delete"), FALSE);
1617  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_close"), FALSE);
1618  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_goto"), FALSE);
1619  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_search"), FALSE);
1620  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_projects_close"), FALSE);
1621  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_projects_save_as"), FALSE);
1622  gtk_widget_hide(notebook);
1623  }
1624  else
1625  {
1626  gtk_widget_set_sensitive(heraia_get_widget(xml, "save"), TRUE);
1627  gtk_widget_set_sensitive(heraia_get_widget(xml, "save_as"), TRUE);
1628  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_cut"), TRUE);
1629  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_copy"), TRUE);
1630  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_paste"), TRUE);
1631  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_delete"), TRUE);
1632  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_close"), TRUE);
1633  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_goto"), TRUE);
1634  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_search"), TRUE);
1635  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_projects_close"), TRUE);
1636  gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_projects_save_as"), TRUE);
1637  gtk_widget_show_all(notebook);
1638  }
1639  }
1640 }
1641 
1642 
1643 /**
1644  * Here we might init some call backs and menu options
1645  * and display the interface (main && sub-windows)
1646  * This function should be called only once at main program's
1647  * init time
1648  * @param main_struct : main structure
1649  */
1651 {
1652 
1653  if (main_struct != NULL)
1654  {
1655  /* inits window states (shows or hide windows) */
1656  init_window_states(main_struct);
1657 
1658  /* menus */
1659  gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_redo"), FALSE);
1660  gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_undo"), FALSE);
1661 
1662  if (main_struct->current_doc != NULL)
1663  {
1664  grey_main_widgets(main_struct->xmls->main, FALSE);
1665  }
1666  else
1667  {
1668  grey_main_widgets(main_struct->xmls->main, TRUE);
1669  }
1670 
1671  refresh_file_labels(main_struct);
1672  }
1673 }
1674 
1675 
1676 /**
1677  * Loads the GtkBuilder xml files that describes the heraia project
1678  * tries the following paths in that order :
1679  * - /etc/heraia/heraia.gtkbuilder
1680  * - /home/[user]/.heraia/heraia.gtkbuilder
1681  * - PWD/heraia.gtkbuilder
1682  * @param main_struct : main structure
1683  * @return TRUE if everything went ok, FALSE otherwise
1684  */
1685 static gboolean load_heraia_xml(heraia_struct_t *main_struct)
1686 {
1687  gchar *filename = NULL;
1688 
1689  if (main_struct != NULL && main_struct->xmls != NULL)
1690  {
1691  filename = g_strdup_printf("heraia.gtkbuilder");
1692  main_struct->xmls->main = load_xml_file(main_struct->location_list, filename);
1693  g_free(filename);
1694 
1695  if (main_struct->xmls->main == NULL)
1696  {
1697  return FALSE;
1698  }
1699  else
1700  {
1701  /* log_message(main_struct, G_LOG_LEVEL_DEBUG, "%s", gtk_builder_get_translation_domain(main_struct->xmls->main));
1702  gtk_builder_set_translation_domain(main_struct->xmls->main, GETTEXT_PACKAGE);
1703  log_message(main_struct, G_LOG_LEVEL_DEBUG, "%s", gtk_builder_get_translation_domain(main_struct->xmls->main));
1704  */
1705  return TRUE;
1706  }
1707  }
1708  else
1709  {
1710  return FALSE;
1711  }
1712 }
1713 
1714 
1715 /**
1716  * Connects the signal that the cursor has moved to
1717  * the refreshing function
1718  * @param main_struct : main structure
1719  * @param hex_widget : the hex_widget we want to connect the signal to
1720  */
1721 void connect_cursor_moved_signal(heraia_struct_t *main_struct, GtkWidget *hex_widget)
1722 {
1723  g_signal_connect(G_OBJECT(hex_widget), "cursor_moved",
1724  G_CALLBACK(refresh_event_handler), main_struct);
1725 }
1726 
1727 
1728 /**
1729  * Connect the signals at the interface
1730  * @param main_struct : main structure
1731  */
1733 {
1734 
1735  /*** File Menu ***/
1736  /* Quit, file menu */
1737  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "quit")), "activate",
1738  G_CALLBACK(on_quit_activate), main_struct);
1739 
1740  /* New, file menu */
1741  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "new")), "activate",
1742  G_CALLBACK(on_new_activate), main_struct);
1743 
1744  /* Open, file menu */
1745  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "open")), "activate",
1746  G_CALLBACK(on_open_activate), main_struct);
1747 
1748  /* Close, file menu */
1749  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_close")), "activate",
1750  G_CALLBACK(on_close_activate), main_struct);
1751 
1752  /* Save, file menu */
1753  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "save")), "activate",
1754  G_CALLBACK(on_save_activate), main_struct);
1755 
1756  /* Save As, file menu */
1757  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "save_as")), "activate",
1758  G_CALLBACK(on_save_as_activate), main_struct);
1759 
1760  /**** Projects sub menu ****/
1761  /* Close, projects sub menu, file menu */
1762  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_projects_close")), "activate",
1763  G_CALLBACK(on_projects_close_activate), main_struct);
1764 
1765  /* Save As, projects sub menu, file menu */
1766  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_projects_save_as")), "activate",
1767  G_CALLBACK(on_projects_save_as_activate), main_struct);
1768 
1769  /* Open, projects sub menu, file menu */
1770  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_projects_open")), "activate",
1771  G_CALLBACK(on_projects_open_activate), main_struct);
1772 
1773 
1774  /*** Edit Menu ***/
1775  /* Goto dialog, edit menu */
1776  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_goto")), "activate",
1777  G_CALLBACK(on_goto_activate), main_struct);
1778 
1779  /* Preferences, Edit menu ; See main_pref_window.c for main_pref_window's signals */
1780  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "preferences")), "activate",
1781  G_CALLBACK(on_preferences_activate), main_struct);
1782 
1783  /* Undo, edit menu */
1784  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_undo")), "activate",
1785  G_CALLBACK(on_undo_activate), main_struct);
1786 
1787  /* Redo, edit menu */
1788  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_redo")), "activate",
1789  G_CALLBACK(on_redo_activate), main_struct);
1790 
1791  /* Cut, edit menu */
1792  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_cut")), "activate",
1793  G_CALLBACK(on_cut_activate), main_struct);
1794 
1795  /* Copy, edit menu */
1796  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_copy")), "activate",
1797  G_CALLBACK(on_copy_activate), main_struct);
1798 
1799  /* Paste, edit menu */
1800  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_paste")), "activate",
1801  G_CALLBACK(on_paste_activate), main_struct);
1802 
1803  /* Delete, edit menu */
1804  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_delete")), "activate",
1805  G_CALLBACK(on_delete_activate), main_struct);
1806 
1807 
1808  /*** Search Menu ***/
1809  /* Find, Search menu */
1810  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_find")), "activate",
1811  G_CALLBACK(on_find_activate), main_struct);
1812 
1813  /* Find and replace, Search menu */
1814  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_find_replace")), "activate",
1815  G_CALLBACK(on_fr_activate), main_struct);
1816 
1817  /* Find data from type, Search menu */
1818  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_fdft")), "activate",
1819  G_CALLBACK(on_fdft_activate), main_struct);
1820 
1821 
1822  /*** Display menu ***/
1823  /* the data interpretor menu */
1824  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "DIMenu")), "activate",
1825  G_CALLBACK(on_DIMenu_activate), main_struct);
1826 
1827 
1828  /*** Help Menu ***/
1829  /* Test, Help menu */
1830  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "tests_menu")), "activate",
1831  G_CALLBACK(on_tests_menu_activate), main_struct);
1832 
1833  /* about dialog box */
1834  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "a_propos")), "activate",
1835  G_CALLBACK(a_propos_activate), main_struct);
1836 
1837  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "close",
1838  G_CALLBACK(a_propos_close), main_struct);
1839 
1840  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "response",
1841  G_CALLBACK(a_propos_response), main_struct);
1842 
1843  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "delete-event",
1844  G_CALLBACK(a_propos_delete), main_struct);
1845 
1846 
1847  /* main notebook */
1848  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "file_notebook")),"switch-page",
1849  G_CALLBACK(file_notebook_tab_changed), main_struct);
1850 
1851 
1852  /* main window killed or destroyed */
1853  g_signal_connect(G_OBJECT (heraia_get_widget(main_struct->xmls->main, "main_window")), "delete-event",
1854  G_CALLBACK(delete_main_window_event), main_struct);
1855 }
1856 
1857 
1858 /** @fn int load_heraia_ui(heraia_struct_t *main_struct)
1859  * Loads, if possible, the gtkbuilder xml file and then connects the
1860  * signals and inits the following windows :
1861  * - log window
1862  * - data_interpretor window
1863  * - list data types
1864  * @param main_struct : main structure
1865  * @return TRUE if load_heraia_xml suceeded, FALSE otherwise
1866  * @todo add more return values to init functions to detect any error while
1867  * initializing the ui
1868  */
1870 {
1871  gboolean success = FALSE;
1872 
1873  /* load the XML interfaces (main) */
1874  success = load_heraia_xml(main_struct);
1875 
1876  if (success == TRUE)
1877  {
1878  /* Heraia UI signals */
1879  if (main_struct->debug == TRUE)
1880  {
1881  fprintf(stdout, Q_("Connecting heraia_ui signals "));
1882  }
1883 
1884  heraia_ui_connect_signals(main_struct);
1885 
1886  if (main_struct->debug == TRUE)
1887  {
1888  fprintf(stdout, Q_(" [Done]\n"));
1889  }
1890 
1891 
1892  /* The Log window */
1893  if (main_struct->debug == TRUE)
1894  {
1895  fprintf(stdout, Q_("log window init interface "));
1896  }
1897 
1898  log_window_init_interface(main_struct);
1899 
1900  if (main_struct->debug == TRUE)
1901  {
1902  fprintf(stdout, Q_(" [Done]\n"));
1903  }
1904 
1905 
1906  /* Preferences window */
1907  if (main_struct->debug == TRUE)
1908  {
1909  fprintf(stdout, Q_("preferences window init interface "));
1910  }
1911 
1912  main_pref_window_init_interface(main_struct);
1913 
1914  if (main_struct->debug == TRUE)
1915  {
1916  fprintf(stdout, Q_(" [Done]\n"));
1917  }
1918 
1919 
1920  /* The data interpretor window */
1921  if (main_struct->debug == TRUE)
1922  {
1923  fprintf(stdout, Q_("data interpretor init interface "));
1924  }
1925 
1926  data_interpretor_init_interface(main_struct);
1927 
1928  if (main_struct->debug == TRUE)
1929  {
1930  fprintf(stdout, Q_(" [Done]\n"));
1931  }
1932 
1933 
1934  /* Goto dialog window */
1935  if (main_struct->debug == TRUE)
1936  {
1937  fprintf(stdout, Q_("goto dialog window init interface "));
1938  }
1939 
1940  goto_dialog_init_interface(main_struct);
1941 
1942  if (main_struct->debug == TRUE)
1943  {
1944  fprintf(stdout, Q_(" [Done]\n"));
1945  }
1946 
1947 
1948  /* result window */
1949  if (main_struct->debug == TRUE)
1950  {
1951  fprintf(stdout, Q_("result window init interface "));
1952  }
1953 
1954  result_window_init_interface(main_struct);
1955 
1956  if (main_struct->debug == TRUE)
1957  {
1958  fprintf(stdout, Q_(" [Done]\n"));
1959  }
1960 
1961 
1962  /* find window */
1963  if (main_struct->debug == TRUE)
1964  {
1965  fprintf(stdout, Q_("find window init interface "));
1966  }
1967 
1968  find_window_init_interface(main_struct);
1969 
1970  if (main_struct->debug == TRUE)
1971  {
1972  fprintf(stdout, Q_(" [Done]\n"));
1973  }
1974 
1975 
1976  /* find and replace window */
1977  if (main_struct->debug == TRUE)
1978  {
1979  fprintf(stdout, Q_("find and replace window init interface "));
1980  }
1981 
1982  fr_window_init_interface(main_struct);
1983 
1984  if (main_struct->debug == TRUE)
1985  {
1986  fprintf(stdout, Q_(" [Done]\n"));
1987  }
1988 
1989 
1990  /* find and replace window */
1991  if (main_struct->debug == TRUE)
1992  {
1993  fprintf(stdout, Q_("find data from type window init interface"));
1994  }
1995 
1996  fdft_window_init_interface(main_struct);
1997 
1998  if (main_struct->debug == TRUE)
1999  {
2000  fprintf(stdout, Q_(" [Done]\n"));
2001  }
2002 
2003 
2004  /* preferences file - Setting up preferences */
2005  if (main_struct->debug == TRUE)
2006  {
2007  fprintf(stdout, Q_("Loading heraia preference file\n"));
2008  fprintf(stdout, Q_("Setting up preferences...\n"));
2009  }
2010 
2011  load_preferences(main_struct, main_struct->prefs);
2012  }
2013 
2014  return success;
2015 }
2016 
2017 
2018 /**
2019  * @fn void add_text_to_textview(GtkTextView *textview, const char *format, ...)
2020  * adds a text to a textview
2021  * @param textview : the textview where to add text
2022  * @param format : printf style format
2023  * @param ... : a va_list arguments to fit format (as with printf)
2024  */
2025 void add_text_to_textview(GtkTextView *textview, const char *format, ...)
2026 {
2027  va_list args;
2028  GtkTextBuffer *tb = NULL;
2029  GtkTextIter iEnd;
2030  gchar *display = NULL;
2031  GError *err = NULL;
2032 
2033  va_start(args, format);
2034  display = g_locale_to_utf8(g_strdup_vprintf(format, args), -1, NULL, NULL, &err);
2035  va_end(args);
2036 
2037  tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)));
2038  gtk_text_buffer_get_end_iter(tb, &iEnd);
2039  gtk_text_buffer_insert(tb, &iEnd, display, -1);
2040  g_free(display);
2041 }
2042 
2043 
2044 /**
2045  * @fn kill_text_from_textview(GtkTextView *textview)
2046  * Kills the text from a textview
2047  * @param textview : the textview to kill the text from
2048  */
2049 void kill_text_from_textview(GtkTextView *textview)
2050 {
2051  GtkTextBuffer *tb = NULL;
2052  GtkTextIter iStart;
2053  GtkTextIter iEnd;
2054 
2055  tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)));
2056  gtk_text_buffer_get_start_iter(tb, &iStart);
2057  gtk_text_buffer_get_end_iter(tb, &iEnd);
2058  gtk_text_buffer_delete (tb, &iStart, &iEnd);
2059 }
2060 
2061 
2062 /**
2063  * @fn GtkWidget *gtk_radio_button_get_active(GSList *group)
2064  * Try to find the active radio button widget in a group
2065  * This does not take into account inconsistant states
2066  * returns the first active radio button otherwise NULL
2067  * @param group : A group of GtkRadioButtons
2068  * @return returns the active widget if any (NULL if none)
2069  */
2070 GtkWidget *gtk_radio_button_get_active(GSList *group)
2071 {
2072  GSList *tmp_slist = group;
2073  GtkToggleButton *toggle_button = NULL;
2074 
2075  while (tmp_slist)
2076  {
2077  toggle_button = tmp_slist->data;
2078 
2079  if (gtk_toggle_button_get_active(toggle_button))
2080  {
2081  return GTK_WIDGET(toggle_button);
2082  }
2083 
2084  tmp_slist = g_slist_next(tmp_slist);
2085  }
2086 
2087  return NULL;
2088 }
2089 
2090 
2091 /**
2092  * @fn GtkWidget *gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_group_member)
2093  * gets the active radio button from a radio group
2094  * @param radio_button : GtkRadioButton to get radio group from
2095  * @returns the active GtkRadioButton within the group from
2096  * radio_button
2097  **/
2098 GtkWidget *gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_button)
2099 {
2100  if (radio_button != NULL)
2101  {
2102  return gtk_radio_button_get_active(gtk_radio_button_get_group(radio_button));
2103  }
2104  else
2105  {
2106  return NULL;
2107  }
2108 }
2109 
2110 
2111 /**
2112  * Sets the radio button active
2113  * @param radio_button : The GtkRadioButton to be active within it's group
2114  */
2115 void gtk_radio_button_set_active(GtkRadioButton *radio_button)
2116 {
2117  GSList *group = NULL;
2118  GtkToggleButton *toggle_button = NULL;
2119 
2120  group = gtk_radio_button_get_group(radio_button);
2121 
2122  while (group)
2123  {
2124  toggle_button = group->data;
2125 
2126  if (toggle_button == GTK_TOGGLE_BUTTON(radio_button))
2127  {
2128  gtk_toggle_button_set_active(toggle_button, TRUE);
2129  }
2130  else
2131  {
2132  gtk_toggle_button_set_active(toggle_button, FALSE);
2133  }
2134 
2135  group = g_slist_next(group);
2136  }
2137 }
2138 
2139 
2140 /**
2141  * @fn gboolean is_cmi_checked(GtkWidget *check_menu_item)
2142  * Tells whether a GtkCheckMenuItem is Checked or not
2143  * @param check_menu_item : a GtkCheckMenuItem to verify
2144  * @return returns TRUE if the Check Manu Item is checked, FALSE otherwise
2145  */
2146 gboolean is_cmi_checked(GtkWidget *check_menu_item)
2147 {
2148  return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(check_menu_item));
2149 }
2150 
2151 
2152 /**
2153  * @fn gboolean is_toggle_button_activated(GtkBuilder *main_xml, gchar *check_button)
2154  * returns the state of a named check button contained
2155  * in the GtkBuilder XML description
2156  * @param main_xml : a GtkBuilder XML definition
2157  * @param check_button : the name of an existing check_button within the GtkBuilder
2158  * definition
2159  * @return TRUE if the button is activated / toggled , FALSE otherwise
2160  */
2161 gboolean is_toggle_button_activated(GtkBuilder *main_xml, gchar *check_button)
2162 {
2163  gboolean activated = FALSE;
2164 
2165  if (main_xml != NULL)
2166  {
2167  activated = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(heraia_get_widget(main_xml, check_button)));
2168  }
2169 
2170  return activated;
2171 }
2172 
2173 
2174 /**
2175  * This is a wrapper to the GtkBuilder xml get widget. It is intended
2176  * to simplify the developpers lives if they have to choose or
2177  * propose other means to do the same thing than libglade (say,
2178  * for example, GtkBuilder ;-)
2179  * @param xml : A GtkBuilder XML definition
2180  * @param widget_name : an existing widget name in the GtkBuilder definition
2181  * @return returns the widget itself if it exists in the definition file (NULL
2182  * otherwise)
2183  */
2184 GtkWidget *heraia_get_widget(GtkBuilder *xml, gchar *widget_name)
2185 {
2186  /**
2187  * For debug purposes only (very verbose as this function is the main used)
2188  * fprintf(stdout, "Getting Widget named %s\n", widget_name);
2189  */
2190 
2191  if (xml != NULL && widget_name != NULL)
2192  {
2193  return GTK_WIDGET(gtk_builder_get_object(xml, widget_name));
2194  }
2195  else
2196  {
2197  return NULL;
2198  }
2199 }
2200 
2201 
2202 /**
2203  * @fn void destroy_a_single_widget(GtkWidget *widget)
2204  * Destroys a single widget if it exists
2205  * @param widget : the widget to destroy
2206  */
2207 void destroy_a_single_widget(GtkWidget *widget)
2208 {
2209  if (widget != NULL)
2210  {
2211  gtk_widget_destroy(widget);
2212  }
2213 }
2214 
2215 
2216 /**
2217  * Verify if we can safely close everything
2218  * @param main_struct : main structure
2219  * @return a boolean which is TRUE if unsaved documents still exists and FALSE
2220  * otherwise
2221  */
2222 static gboolean unsaved_documents(heraia_struct_t *main_struct)
2223 {
2224  doc_t *current_doc = NULL;
2225  gboolean result = FALSE;
2226  guint i = 0;
2227 
2228  if (main_struct != NULL && main_struct->documents != NULL)
2229  {
2230  for(i = 0; i < main_struct->documents->len; i++)
2231  {
2232  current_doc = g_ptr_array_index(main_struct->documents, i);
2233  result = result | current_doc->modified;
2234  }
2235 
2236  return result;
2237  }
2238 
2239  return result;
2240 }
2241 
2242 
2243 /**
2244  * Closes all documents and saves preferences if the users wants to close
2245  * the documents.
2246  * @param main_struct : main_struct
2247  * @param question a const gchar * string to be displayed when an unsaved
2248  * document is found. This should ask the user what to do.
2249  * @return the user anwser if an unsaved document is found and TRUE if not
2250  */
2251 static gboolean close_a_project(heraia_struct_t *main_struct, const gchar *question)
2252 {
2253  gboolean unsaved = FALSE; /**< if there is any unsaved documents */
2254  gboolean quit_heraia = TRUE; /**< By default we want to quit */
2255  GtkWidget *dialog = NULL; /**< The dialog box */
2256  GtkWidget *parent = NULL; /**< parent widget for the dialog box */
2257  gint result = 0; /**< result from the dialog box */
2258  doc_t *closing_doc = NULL; /**< The document to be closed */
2259 
2260  unsaved = unsaved_documents(main_struct);
2261 
2262  if (unsaved == TRUE)
2263  {
2264  /* Displays a dialog box that let the user choose what to do */
2265  parent = heraia_get_widget(main_struct->xmls->main, "main_window");
2266 
2267  dialog = gtk_message_dialog_new(GTK_WINDOW(parent), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, Q_("Unsaved document(s) remains."));
2268  gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog), "%s", question);
2269 
2270 
2271  result = gtk_dialog_run(GTK_DIALOG(dialog));
2272 
2273  switch (result)
2274  {
2275  case GTK_RESPONSE_YES:
2276  quit_heraia = TRUE;
2277  break;
2278 
2279  default:
2280  quit_heraia = FALSE;
2281  break;
2282  }
2283 
2284  gtk_widget_destroy(dialog);
2285  }
2286 
2287  if (quit_heraia == TRUE)
2288  {
2289  /* . Recording window's position */
2290  record_all_dialog_box_positions(main_struct);
2291 
2292  /* . Saving preferences */
2293  save_preferences(main_struct, main_struct->prefs);
2294 
2295  /* . Closing the documents */
2296  while (main_struct->documents->len > 0)
2297  {
2298  closing_doc = g_ptr_array_index(main_struct->documents, 0);
2299  close_one_document(main_struct, closing_doc, 0);
2300  }
2301  main_struct->current_doc = NULL;
2302 
2303  /* . Updating things in the interface */
2304  refresh_event_handler(parent, main_struct);
2305  update_main_window_name(main_struct);
2306  grey_main_widgets(main_struct->xmls->main, TRUE);
2307 
2308  /* . Destroying preferences structure */
2309  free_preference_struct(main_struct->prefs);
2310  main_struct->prefs = NULL;
2311  }
2312 
2313  return quit_heraia;
2314 }
2315 
2316 
2317 /**
2318  * @fn void close_heraia(heraia_struct_t *main_struct)
2319  * Before closing heraia we need to do few things
2320  * @param main_struct : main_struct
2321  * @return TRUE if we can safely quit heraia, FALSE otherwise
2322  */
2323 static gboolean close_heraia(heraia_struct_t *main_struct)
2324 {
2325  return close_a_project(main_struct, Q_("Do you want to quit without saving ?"));
2326 }
2327 
2328 
2329 /**
2330  * @fn void init_one_cmi_window_state(GtkWidget *dialog_box, GtkWidget *cmi, window_prop_t *dialog_prop)
2331  * init one cmi window based state
2332  * @param dialog_box : the window or dialog box we want to init its state
2333  * @param cmi : corresponding check menu item
2334  * @param dialog_prop : corresponding window properties (should be initialized and not NULL)
2335  */
2336 static void init_one_cmi_window_state(GtkWidget *dialog_box, GtkWidget *cmi, window_prop_t *dialog_prop)
2337 {
2338  gboolean activated = FALSE;
2339 
2340  if (dialog_box != NULL && cmi != NULL && dialog_prop != NULL)
2341  {
2342  activated = dialog_prop->displayed;
2343  gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(cmi), activated);
2344  if (activated == TRUE)
2345  {
2346  gtk_window_move(GTK_WINDOW(dialog_box), dialog_prop->x, dialog_prop->y);
2347  gtk_window_resize(GTK_WINDOW(dialog_box), dialog_prop->width, dialog_prop->height);
2348  gtk_widget_show_all(dialog_box);
2349  }
2350  }
2351 }
2352 
2353 
2354 /**
2355  * @fn init_window_states(heraia_struct_t *main_struct)
2356  * Inits all windows states (positions, displayed, and so on...)
2357  * @param main_struct : main structure
2358  */
2360 {
2361  GtkWidget *cmi = NULL;
2362  GtkWidget *dialog_box = NULL;
2363 
2364  if (main_struct != NULL && main_struct->xmls != NULL && main_struct->xmls->main != NULL)
2365  {
2366  if (main_struct->win_prop)
2367  {
2368  /* Main window (always the first one) */
2369  dialog_box = heraia_get_widget(main_struct->xmls->main, "main_window");
2370  if (main_struct->win_prop->main_dialog->displayed == TRUE)
2371  {
2372  gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->main_dialog->x, main_struct->win_prop->main_dialog->y);
2373  gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->main_dialog->width, main_struct->win_prop->main_dialog->height);
2374  gtk_widget_show(dialog_box);
2375  }
2376 
2377  /* Log Window Interface */
2378  cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw");
2379  dialog_box = heraia_get_widget(main_struct->xmls->main, "log_window");
2380  init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->log_box);
2381 
2382  /* Data Interpretor Interface */
2383  cmi = heraia_get_widget(main_struct->xmls->main, "DIMenu");
2384  dialog_box = heraia_get_widget(main_struct->xmls->main, "data_interpretor_window");
2385  init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->data_interpretor);
2386  on_DIMenu_activate(cmi, main_struct);
2387 
2388  /* List Data type Interface */
2389  /*
2390  * cmi = heraia_get_widget(main_struct->xmls->main, "ldt_menu");
2391  * dialog_box = heraia_get_widget(main_struct->xmls->main, "list_data_types_window");
2392  * init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->ldt);
2393  */
2394 
2395  /* Plugin List Interface */
2396  cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_plugin_list");
2397  dialog_box = heraia_get_widget(main_struct->xmls->main, "plugin_list_window");
2398  init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->plugin_list);
2399 
2400  /* Preferences window */
2401  dialog_box = heraia_get_widget(main_struct->xmls->main, "main_preferences_window");
2402  if (main_struct->win_prop->main_pref_window->displayed == TRUE)
2403  {
2404  gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->main_pref_window->x, main_struct->win_prop->main_pref_window->y);
2405  gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->main_pref_window->width, main_struct->win_prop->main_pref_window->height);
2406  gtk_widget_show_all(dialog_box);
2407  }
2408 
2409  /* Goto dialog window */
2410  dialog_box = heraia_get_widget(main_struct->xmls->main, "goto_dialog");
2411  if (main_struct->win_prop->goto_window->displayed == TRUE && main_struct->current_doc != NULL)
2412  {
2413  gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->goto_window->x, main_struct->win_prop->goto_window->y);
2414  gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->goto_window->width, main_struct->win_prop->goto_window->height);
2415  gtk_widget_show_all(dialog_box);
2416  }
2417  else
2418  {
2419  /* if the window is not displayed modifies it's properties accordingly */
2420  main_struct->win_prop->goto_window->displayed = FALSE;
2421  }
2422 
2423  /* result window */
2424  dialog_box = heraia_get_widget(main_struct->xmls->main, "result_window");
2425  cmi = heraia_get_widget(main_struct->xmls->main, "menu_result");
2426  if (main_struct->win_prop->result_window->displayed == TRUE && main_struct->current_doc != NULL)
2427  {
2428  gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->result_window->x, main_struct->win_prop->result_window->y);
2429  gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->result_window->width, main_struct->win_prop->result_window->height);
2430  gtk_widget_show_all(dialog_box);
2431  }
2432  else
2433  {
2434  main_struct->win_prop->result_window->displayed = FALSE;
2435  }
2436  init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->result_window);
2437 
2438  /* find window */
2439  dialog_box = heraia_get_widget(main_struct->xmls->main, "find_window");
2440  if (main_struct->win_prop->find_window->displayed == TRUE && main_struct->current_doc != NULL)
2441  {
2442  gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->find_window->x, main_struct->win_prop->find_window->y);
2443  gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->find_window->width, main_struct->win_prop->find_window->height);
2444  gtk_widget_show_all(dialog_box);
2445  }
2446  else
2447  {
2448  /* if the window is not displayed modifies it's properties accordingly */
2449  main_struct->win_prop->find_window->displayed = FALSE;
2450  }
2451 
2452  /* find and replace window */
2453  dialog_box = heraia_get_widget(main_struct->xmls->main, "fr_window");
2454  if (main_struct->win_prop->fr_window->displayed == TRUE && main_struct->current_doc != NULL)
2455  {
2456  gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->fr_window->x, main_struct->win_prop->fr_window->y);
2457  gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->fr_window->width, main_struct->win_prop->fr_window->height);
2458  gtk_widget_show_all(dialog_box);
2459  }
2460  else
2461  {
2462  /* if the window is not displayed modifies it's properties accordingly */
2463  main_struct->win_prop->fr_window->displayed = FALSE;
2464  }
2465 
2466  /* find data from type window */
2467  dialog_box = heraia_get_widget(main_struct->xmls->main, "fdft_window");
2468  if (main_struct->win_prop->fdft_window->displayed == TRUE && main_struct->current_doc != NULL)
2469  {
2470  gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->fdft_window->x, main_struct->win_prop->fdft_window->y);
2471  gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->fdft_window->width, main_struct->win_prop->fdft_window->height);
2472  gtk_widget_show_all(dialog_box);
2473  }
2474  else
2475  {
2476  /* if the window is not displayed modifies it's properties accordingly */
2477  main_struct->win_prop->fdft_window->displayed = FALSE;
2478  }
2479 
2480 
2481  /* About Box */
2482  dialog_box = heraia_get_widget(main_struct->xmls->main, "about_dialog");
2483  if (main_struct->win_prop->about_box->displayed == TRUE)
2484  {
2485  gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->about_box->x, main_struct->win_prop->about_box->y);
2486  gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->about_box->width, main_struct->win_prop->about_box->height);
2487  set_a_propos_properties(dialog_box);
2488  gtk_widget_show_all(dialog_box);
2489  }
2490  }
2491  }
2492 }
2493 
2494 
2495 /**
2496  * Creates an hbox containning a cross button (in order to close the tab) and
2497  * a label (from tab_label).
2498  * Creates a label an a button to add into a tab from main window's notebook
2499  * @param main_struct : main structure
2500  * @param tab_label : a GtkWidget that is the label we want to add to the tab
2501  * @param signal_handler : the signal to connect to when the close button is
2502  * clicked.
2503  * @return a newly created GtkWidget which contains the label and a close button
2504  */
2505 GtkWidget *create_tab_close_button(heraia_struct_t *main_struct, GtkWidget *tab_label, void *signal_handler)
2506 {
2507  GtkWidget *hbox = NULL; /**< used for hbox creation in the tabs */
2508  GtkWidget *button = NULL; /**< Closing button */
2509 
2510  /* Close button in tabs */
2511  #if GTK_MAJOR_VERSION < 3
2512  /* valid in GTK+ 2.x */
2513  hbox = gtk_hbox_new(FALSE, 0);
2514  #endif
2515  #if GTK_MAJOR_VERSION >= 3
2516  #if GTK_MINOR_VERSION <= 1
2517  /* valid in GTK+ 3.0 and 3.1 */
2518  hbox = gtk_hbox_new(FALSE, 0);
2519  #endif
2520  #if GTK_MINOR_VERSION >= 2
2521  /* only valid from GTK 3.2 */
2522  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
2523  #endif
2524  #endif
2525 
2526 
2527  button = gtk_button_new_with_label("x");
2528  gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
2529  gtk_widget_set_size_request(button, 18, 17);
2530  gtk_widget_set_tooltip_text(button, Q_("Close button"));
2531  g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(signal_handler), main_struct);
2532 
2533  /* Packing label and button all together in order to display everything in the tab */
2534  gtk_box_pack_start(GTK_BOX(hbox), tab_label, FALSE, FALSE, 0);
2535  gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 2);
2536  gtk_widget_show_all(hbox);
2537 
2538  return hbox;
2539 }
2540 
2541 
2542 /**
2543  * Adds a new tab to the main window in file's notebook
2544  * @param main_struct : main structure
2545  * @param doc : the new document that will be related to the tab
2546  */
2548 {
2549  GtkWidget *vbox = NULL; /**< used for vbox creation */
2550  GtkNotebook *notebook = NULL; /**< file_notebook from heraia.gtkbuilder */
2551  GtkWidget *tab_label = NULL; /**< tab's label */
2552  GtkWidget *menu_label = NULL; /**<menu's label */
2553  gint tab_num = -1; /**< new tab's index */
2554  gchar *filename = NULL;
2555  gchar *whole_filename = NULL;
2556  gchar *markup = NULL; /**< markup text */
2557  gchar *menu_markup = NULL; /**< menu markup text */
2558  GtkWidget *hbox = NULL; /**< used for hbox creation in the tabs */
2559 
2560  notebook = GTK_NOTEBOOK(heraia_get_widget(main_struct->xmls->main, "file_notebook"));
2561 
2562  #if GTK_MAJOR_VERSION < 3
2563  /* valid in GTK+ 2.x */
2564  vbox = gtk_vbox_new(FALSE, 2);
2565  #endif
2566  #if GTK_MAJOR_VERSION >= 3
2567  #if GTK_MINOR_VERSION <= 1
2568  /* valid in GTK+ 3.0 and 3.1 */
2569  vbox = gtk_vbox_new(FALSE, 2);
2570  #endif
2571  #if GTK_MINOR_VERSION >= 2
2572  /* only valid from GTK 3.2 */
2573  vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 2);
2574  #endif
2575  #endif
2576 
2577  gtk_box_pack_start(GTK_BOX(vbox), doc->hex_widget, TRUE, TRUE, 3);
2578 
2579  /* tab's label and menu label */
2580  tab_label = gtk_label_new(NULL);
2581  menu_label = gtk_label_new(NULL);
2582  whole_filename = doc_t_document_get_filename(doc);
2583 
2584  if (whole_filename != NULL)
2585  {
2586  filename = g_filename_display_basename(whole_filename);
2587  markup = g_markup_printf_escaped("%s", filename);
2588  menu_markup = g_markup_printf_escaped("%s", filename);
2589  gtk_label_set_markup(GTK_LABEL(tab_label), markup);
2590  gtk_label_set_markup(GTK_LABEL(menu_label), menu_markup);
2591  gtk_label_set_justify(GTK_LABEL(menu_label), GTK_JUSTIFY_LEFT);
2592  gtk_widget_set_tooltip_text(tab_label, g_filename_display_name(whole_filename));
2593  g_free(markup);
2594  g_free(menu_markup);
2595  }
2596 
2597  hbox = create_tab_close_button(main_struct, tab_label, on_close_activate);
2598 
2599  gtk_widget_show_all(vbox);
2600  tab_num = gtk_notebook_append_page_menu(notebook, vbox, hbox, menu_label);
2601 
2602  main_struct->current_doc = doc;
2603  gtk_notebook_set_current_page(notebook, tab_num);
2604 }
2605 
2606 
2607 /**
2608  * To help plugins to deal with widgets, shows or hide a specific widget
2609  * @param widget : the widget to show or hide
2610  * @param show : what to do : TRUE to show the widget, FALSE to hide it
2611  * @param win_prop : window properties.
2612  */
2613 void show_hide_widget(GtkWidget *widget, gboolean show, window_prop_t *win_prop)
2614 {
2615  if (widget != NULL)
2616  {
2617  if (win_prop != NULL)
2618  {
2619  if (show)
2620  {
2621  move_and_show_dialog_box(widget, win_prop);
2622  }
2623  else
2624  {
2625  record_and_hide_dialog_box(widget, win_prop);
2626  }
2627  }
2628  else
2629  {
2630  if (show)
2631  {
2632  gtk_widget_show(widget);
2633  }
2634  else
2635  {
2636  gtk_widget_hide(widget);
2637  }
2638  }
2639  }
2640 }
static void close_one_document(heraia_struct_t *main_struct, doc_t *closing_doc, gint index)
Closes one document in heraia.
Definition: heraia_ui.c:887
void kill_text_from_textview(GtkTextView *textview)
Kills the text from a textview.
Definition: heraia_ui.c:2049
window_prop_t * find_window
find window
Definition: libheraia.h:270
This is the main structure.
Definition: libheraia.h:332
static gboolean a_propos_delete(GtkWidget *widget, GdkEvent *event, gpointer data)
To close the A propos dialog box.
Definition: heraia_ui.c:381
Window properties.
Definition: libheraia.h:243
void find_window_init_interface(heraia_struct_t *main_struct)
Inits all the things in the find window (signal and such)
window_prop_t * data_interpretor
data interpretor window
Definition: libheraia.h:262
static void on_projects_open_activate(GtkWidget *widget, gpointer data)
Opens a project from a file : closes all documents an imports new ones ...
Definition: heraia_ui.c:849
GtkWidget * find_label_from_hbox(GtkWidget *hbox)
Tries to find the label contained in the hbox.
Definition: heraia_ui.c:1463
static gchar * make_absolute_path(gchar *filename)
Returns an absolute path to the filename the string should be freed when no longer needed very UGLy !...
Definition: heraia_ui.c:1271
void init_heraia_interface(heraia_struct_t *main_struct)
Here we might init some call backs and menu options and display the interface (main && sub-windows) This ...
Definition: heraia_ui.c:1650
gint x
x position (upper left corner)
Definition: libheraia.h:245
static void on_projects_save_as_activate(GtkWidget *widget, gpointer data)
Saves a project in a new file (does not close the project itself)
Definition: heraia_ui.c:825
void on_save_activate(GtkWidget *widget, gpointer data)
Here we attemp to save the edited file.
Definition: heraia_ui.c:1027
void on_DIMenu_activate(GtkWidget *widget, gpointer data)
This handles the menuitem "Data Interpretor" that shows or hides the data interpretor window...
Definition: heraia_ui.c:1106
void add_text_to_textview(GtkTextView *textview, const char *format,...)
adds a text to a textview
Definition: heraia_ui.c:2025
void set_notebook_tab_name(heraia_struct_t *main_struct)
Sets notebook's tab's name.
Definition: heraia_ui.c:1506
void add_new_tab_in_main_window(heraia_struct_t *main_struct, doc_t *doc)
Adds a new tab to the main window in file's notebook.
Definition: heraia_ui.c:2547
GtkWidget * create_tab_close_button(heraia_struct_t *main_struct, GtkWidget *tab_label, void *signal_handler)
Creates an hbox containning a cross button (in order to close the tab) and a label (from tab_label)...
Definition: heraia_ui.c:2505
window_prop_t * result_window
result window properties
Definition: libheraia.h:269
gint tab_displayed
keeps the last displayed tab's number before closing
Definition: libheraia.h:209
void on_preferences_activate(GtkWidget *widget, gpointer data)
Preferences, file menu : Displays the preference window (as a modal window)
Definition: heraia_ui.c:135
void set_notebook_tab_label_color(heraia_struct_t *main_struct, gboolean color)
Set the style for the label.
Definition: heraia_ui.c:1550
GSList * select_file_to_load(heraia_struct_t *main_struct, gboolean multiple, gchar *message)
This function does open a file selector dialog box and returns the selected filename.
Definition: heraia_ui.c:1333
static void record_and_hide_about_box(heraia_struct_t *main_struct)
Record position and hide about dialog box.
Definition: heraia_ui.c:332
gchar * doc_t_document_get_filename(doc_t *doc)
Retrieves from a doc_t * document it's filename, which ever it is.
prefs_t * init_preference_struct(gchar *pathname, gchar *filename)
Look out if the preference structure exists or not.
Definition: user_prefs.c:130
window_prop_t * fr_window
find and replace window
Definition: libheraia.h:271
#define WPT_DEFAULT_HEIGHT
Defines the default height for a window (set in window_prop_t)
Definition: libheraia.h:233
void log_message(heraia_struct_t *main_struct, GLogLevelFlags log_level, const char *format,...)
A function that helps logging a message a the specified level.
Definition: log.c:195
static void init_one_cmi_window_state(GtkWidget *dialog_box, GtkWidget *cmi, window_prop_t *dialog_prop)
init one cmi window based state
Definition: heraia_ui.c:2336
RefreshType event
Tells what is happening.
Definition: libheraia.h:341
void gtk_radio_button_set_active(GtkRadioButton *radio_button)
Sets the radio button active.
Definition: heraia_ui.c:2115
void on_redo_activate(GtkWidget *widget, gpointer data)
Redo, edit menu.
Definition: heraia_ui.c:434
gboolean delete_main_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
Definition: heraia_ui.c:1183
window_prop_t * main_dialog
heraia's main window
Definition: libheraia.h:264
GtkBuilder * load_xml_file(GList *location_list, gchar *filename)
loads the GtkBuilder xml file ('filename') that describes an interface, tries all the paths defined i...
Definition: heraia_io.c:145
gboolean displayed
TRUE if displayed, FALSE otherwise.
Definition: libheraia.h:249
window_prop_t * plugin_list
plugin description window
Definition: libheraia.h:265
void fdft_window_init_interface(heraia_struct_t *main_struct)
Inits all the things in the find data from type window (signal and such)
void on_find_activate(GtkWidget *widget, gpointer data)
Find, Search menu.
Definition: heraia_ui.c:537
void record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
Record position and hide a dialog box.
Definition: heraia_ui.c:314
void on_save_as_activate(GtkWidget *widget, gpointer data)
This handle the save_as menu entry (here the filename changes)
Definition: heraia_ui.c:1057
gboolean file_notebook_tab_changed(GtkNotebook *notebook, GtkWidget *page, gint tab_num, gpointer data)
What to do when a change occurs in tabs (user selected a particular tab)
Definition: heraia_ui.c:1233
void show_hide_widget(GtkWidget *widget, gboolean show, window_prop_t *win_prop)
To help plugins to deal with widgets, shows or hide a specific widget.
Definition: heraia_ui.c:2613
gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
call back function for the data interpretor window destruction
Definition: heraia_ui.c:1200
void on_fdft_activate(GtkWidget *widget, gpointer data)
Find data from type, Search menu.
Definition: heraia_ui.c:569
void refresh_file_labels(heraia_struct_t *main_struct)
This function is refreshing the labels on the main window in order to reflect cursor position...
Definition: heraia_ui.c:588
all_window_prop_t * win_prop
Keeps window properties.
Definition: libheraia.h:342
void rw_remove_all_tabs(heraia_struct_t *main_struct, doc_t *doc)
Remove all tabs from the result window that correspond to the specified document. ...
guint64 ghex_file_size(Heraia_Hex *gh)
Returns the file size of an opened Heraia_Hex document.
window_prop_t * main_pref_window
main preference window
Definition: libheraia.h:267
window_prop_t * fdft_window
find data from type window
Definition: libheraia.h:272
#define WPT_DEFAULT_WIDTH
Defines the default width for a window (set in window_prop_t)
Definition: libheraia.h:234
Data interpretor window structure.
Definition: libheraia.h:206
Proposal for a structure that will group all informations about a single document.
Definition: libheraia.h:293
#define HERAIA_REFRESH_NEW_FILE
When a new file has been loaded.
Definition: libheraia.h:101
guint64 start
Starting position of the selection.
Definition: libheraia.h:309
GtkHex Heraia_Hex
Abstract layer this may be usefull if we decide to leave Heraia_Hex and use something else ! ...
Definition: libheraia.h:77
gchar * select_a_file_to_save(heraia_struct_t *main_struct)
This function opens a dialog box that allow one to choose a file name to the file which is about to b...
Definition: heraia_ui.c:1386
void fdft_window_show(GtkWidget *widget, gpointer data)
Show find data from type window.
Heraia_Document * hex_doc
Document definition related to Heraia_Hex (GtkHex)
Definition: libheraia.h:295
void on_tests_menu_activate(GtkWidget *widget, gpointer data)
Called when tests submenu is activated.
Definition: heraia_ui.c:1155
A structure to manage a single selection.
Definition: libheraia.h:307
guint64 end
Ending position of the selection.
Definition: libheraia.h:310
void grey_main_widgets(GtkBuilder *xml, gboolean greyed)
Hides or grey all widgets that needs an open file when boolean greyed is TRUE.
Definition: heraia_ui.c:1601
xml_t * xmls
All the xmls used in the program, loaded at running time.
Definition: libheraia.h:337
#define PACKAGE_NAME
Definition: config.h:96
void fr_window_init_interface(heraia_struct_t *main_struct)
Inits all the things in the find and replace window (signal and such)
void on_cut_activate(GtkWidget *widget, gpointer data)
Cut, edit menu.
Definition: heraia_ui.c:487
void on_copy_activate(GtkWidget *widget, gpointer data)
Copy, edit menu.
Definition: heraia_ui.c:504
gboolean debug
Used to tell the program wether we want to display debug messages or not.
Definition: libheraia.h:334
void record_all_dialog_box_positions(heraia_struct_t *main_struct)
Records all the positions of the displayed windows.
Definition: heraia_ui.c:250
static gboolean unsaved_documents(heraia_struct_t *main_struct)
Verify if we can safely close everything.
Definition: heraia_ui.c:2222
static void a_propos_response(GtkWidget *widget, gint response, gpointer data)
To close the A propos dialog box (with the "close" button)
Definition: heraia_ui.c:352
void free_preference_struct(prefs_t *prefs)
Destroys a preference structure.
Definition: user_prefs.c:148
void goto_dialog_init_interface(heraia_struct_t *main_struct)
Inits all the things in the goto dialog window (signal and such)
Definition: goto_dialog.c:59
void refresh_all_plugins(heraia_struct_t *main_struct)
To help the main program to send events to the plugins.
Definition: plugin.c:378
void find_window_show(GtkWidget *widget, gpointer data)
Show find window.
static gboolean load_heraia_xml(heraia_struct_t *main_struct)
Loads the GtkBuilder xml files that describes the heraia project tries the following paths in that or...
Definition: heraia_ui.c:1685
void refresh_data_interpretor_window(GtkWidget *widget, gpointer data)
Refreshes the data interpretor window with the new values.
void record_dialog_box_position(GtkWidget *dialog_box, window_prop_t *dialog_prop)
Records one dialog position.
Definition: heraia_ui.c:223
#define HERAIA_REFRESH_CURSOR_MOVE
When the cursor is moving.
Definition: libheraia.h:102
void on_quit_activate(GtkWidget *widget, gpointer data)
Quit, file menu.
Definition: heraia_ui.c:57
void on_open_activate(GtkWidget *widget, gpointer data)
This handles the menuitem "Ouvrir" to open a file.
Definition: heraia_ui.c:705
window_prop_t * about_box
Definition: libheraia.h:261
void fr_window_show(GtkWidget *widget, gpointer data)
Show find and replace window.
prefs_t * prefs
All datas related to main preferences.
Definition: libheraia.h:343
GtkWidget * gtk_radio_button_get_active(GSList *group)
Try to find the active radio button widget in a group This does not take into account inconsistant st...
Definition: heraia_ui.c:2070
void destroy_a_single_widget(GtkWidget *widget)
Destroys a single widget if it exists.
Definition: heraia_ui.c:2207
GtkWidget * hex_widget
hexwidget corresponding to the document
Definition: libheraia.h:296
gint y
y position (upper left corner)
Definition: libheraia.h:246
void log_window_init_interface(heraia_struct_t *main_struct)
Inits the log window interface Called once at init time.
Definition: log.c:376
void update_main_window_name(heraia_struct_t *main_struct)
Update main window heraia's name to reflect the current edited file.
Definition: heraia_ui.c:1434
GtkBuilder * main
the main interface xml description
Definition: libheraia.h:222
void move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
Move the dialog box to the wanted position, shows it and says it in the displayed prop...
Definition: heraia_ui.c:193
#define HERAIA_REFRESH_NOTHING
When nothing is refreshed.
Definition: libheraia.h:100
#define HERAIA_NOERR
No error occured, everything is fine.
Definition: heraia_errors.h:47
gint HERAIA_ERROR
Defines heraia error type (this should be used !)
Definition: libheraia.h:78
void on_undo_activate(GtkWidget *widget, gpointer data)
Undo, edit menu.
Definition: heraia_ui.c:395
void a_propos_activate(GtkWidget *widget, gpointer data)
Shows apropos's dialog box.
Definition: heraia_ui.c:172
guint64 ghex_get_cursor_position(GtkWidget *hex_widget)
Retrieves the cursor's position from the current hexwidget.
data_window_t * current_DW
data_interpretor pointer
Definition: libheraia.h:338
static void heraia_ui_connect_signals(heraia_struct_t *main_struct)
Connect the signals at the interface.
Definition: heraia_ui.c:1732
gboolean is_cmi_checked(GtkWidget *check_menu_item)
Tells whether a GtkCheckMenuItem is Checked or not.
Definition: heraia_ui.c:2146
HexDocument Heraia_Document
Abstract layer this may be usefull if we decide to leave Heraia_Hex and use something else ! ...
Definition: libheraia.h:76
static void set_a_propos_properties(GtkWidget *about_dialog)
Sets name and version in the dialog box.
Definition: heraia_ui.c:155
window_prop_t * log_box
log window
Definition: libheraia.h:263
static void a_propos_close(GtkWidget *widget, gpointer data)
To close the A propos dialog box.
Definition: heraia_ui.c:365
#define HERAIA_CANCELLED
an operation has been cancelled
Definition: heraia_errors.h:51
void on_close_activate(GtkWidget *widget, gpointer data)
Closes an opened file.
Definition: heraia_ui.c:914
This file contains all the definitions and includes all other .h files.
guint height
y+height (bottom right corner)
Definition: libheraia.h:247
void result_window_init_interface(heraia_struct_t *main_struct)
Inits all the things in the result window (signal and such)
Definition: result_window.c:70
void on_goto_activate(GtkWidget *widget, gpointer data)
Go to..., edit menu.
Definition: goto_dialog.c:42
gboolean tests_ui(heraia_struct_t *main_struct)
functions to tests heraia's UI
Definition: tests.c:97
HERAIA_ERROR heraia_hex_document_save(doc_t *current_doc)
GtkWidget * diw
data interpretor window
Definition: libheraia.h:208
static gboolean close_a_project(heraia_struct_t *main_struct, const gchar *question)
Closes all documents and saves preferences if the users wants to close the documents.
Definition: heraia_ui.c:2251
doc_t * current_doc
This is a pointer to the current edited document.
Definition: libheraia.h:335
void on_delete_activate(GtkWidget *widget, gpointer data)
Delete, edit menu.
Definition: heraia_ui.c:470
GtkWidget * heraia_get_widget(GtkBuilder *xml, gchar *widget_name)
This is a wrapper to the GtkBuilder xml get widget.
Definition: heraia_ui.c:2184
void set_the_working_directory(GtkFileChooser *file_chooser, gchar *filename)
Sets the working directory for the file chooser to the directory of the filename (even if filename is...
Definition: heraia_ui.c:1311
window_prop_t * goto_window
goto dialog window
Definition: libheraia.h:268
#define PACKAGE_VERSION
Definition: config.h:105
#define HERAIA_REFRESH_TAB_CHANGED
When user selects another tab in main notebook.
Definition: libheraia.h:103
void data_interpretor_init_interface(heraia_struct_t *main_struct)
Inits the data interpretor structure and window with default values.
static void on_projects_close_activate(GtkWidget *widget, gpointer data)
Closes an entire project.
Definition: heraia_ui.c:809
void main_pref_window_init_interface(heraia_struct_t *main_struct)
Inits the main preferences window interface.
void save_preferences(heraia_struct_t *main_struct, prefs_t *prefs)
Save all preferences to the user preference file.
Definition: user_prefs.c:376
gboolean is_toggle_button_activated(GtkBuilder *main_xml, gchar *check_button)
returns the state of a named check button contained in the GtkBuilder XML description ...
Definition: heraia_ui.c:2161
void refresh_event_handler(GtkWidget *widget, gpointer data)
This function is here to ensure that everything will be refreshed upon a signal event.
Definition: heraia_ui.c:676
guint width
x+width (bottom right corner)
Definition: libheraia.h:248
void close_doc_t(doc_t *current_doc)
Closes a previously malloced doc_t structure.
GPtrArray * documents
An array of doc_t in order to be able to open more than one doc.
Definition: libheraia.h:336
gboolean modified
If hex_doc->changed <> modified then the document has something changed that may need an upate...
Definition: libheraia.h:297
gint find_tab_number_from_widget(heraia_struct_t *main_struct, gchar *notebook_name, GtkWidget *to_find)
Searches in a notebook's tabs for a particular widget and returns the number of the corresponding tab...
Definition: heraia_ui.c:745
GtkWidget * gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_button)
gets the active radio button from a radio group
Definition: heraia_ui.c:2098
selection_t * ghex_get_selection(GtkWidget *hex_widget)
Retrieves the selection made (if any) in the hex widget.
HERAIA_ERROR heraia_hex_document_save_as(doc_t *current_doc, gchar *filename)
Saves an opened and edited document to a new file.
void on_fr_activate(GtkWidget *widget, gpointer data)
Find and replace, Search menu.
Definition: heraia_ui.c:553
doc_t * new_doc_t(Heraia_Document *hex_doc, GtkWidget *hex_widget)
Inits a doc_t structure.
GList * location_list
this is the location list where we store some paths
Definition: libheraia.h:339
void on_new_activate(GtkWidget *widget, gpointer data)
New, file menu.
Definition: heraia_ui.c:77
void destroy_dt_window(GtkWidget *widget, GdkEvent *event, gpointer data)
call back function for the data interpretor window destruction
Definition: heraia_ui.c:1217
void on_paste_activate(GtkWidget *widget, gpointer data)
Paste, edit menu.
Definition: heraia_ui.c:520
void init_window_states(heraia_struct_t *main_struct)
Inits all windows states (positions, displayed, and so on...)
Definition: heraia_ui.c:2359
void load_preferences(heraia_struct_t *main_struct, prefs_t *prefs)
Sets up the preferences as loaded in the preference file.
Definition: user_prefs.c:620
gboolean load_file_to_analyse(heraia_struct_t *main_struct, gchar *filename)
Loads the file 'filename' to analyse and populates the corresponfing structure 'main_struct' as neede...
Definition: heraia_io.c:40
int load_heraia_ui(heraia_struct_t *main_struct)
Loads, if possible, the gtkbuilder xml file and then connects the signals and inits the following win...
Definition: heraia_ui.c:1869
static gboolean close_heraia(heraia_struct_t *main_struct)
Before closing heraia we need to do few things.
Definition: heraia_ui.c:2323
void connect_cursor_moved_signal(heraia_struct_t *main_struct, GtkWidget *hex_widget)
Connects the signal that the cursor has moved to the refreshing function.
Definition: heraia_ui.c:1721