heraia_ui.c

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 /*
00003   heraia_ui.c
00004   main menus, callback and utility functions
00005 
00006   (C) Copyright 2005 - 2011 Olivier Delhomme
00007   e-mail : heraia@delhomme.org
00008   URL    : http://heraia.tuxfamily.org
00009 
00010   This program is free software; you can redistribute it and/or modify
00011   it under the terms of the GNU General Public License as published by
00012   the Free Software Foundation; either version 2, or  (at your option)
00013   any later version.
00014 
00015   This program is distributed in the hope that it will be useful,
00016   but WITHOUT ANY WARRANTY;  without even the implied warranty of
00017   MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the
00018   GNU General Public License for more details.
00019 
00020   You should have received a copy of the GNU General Public License
00021   along with this program; if not, write to the Free Software
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023 */
00024 /** @file heraia_ui.c
00025  * This file has all the functions to manage heraia's ui
00026  * - signals definitions and functions
00027  * - widgets activations
00028  * - closing / openning windows
00029  */
00030 
00031 #include <libheraia.h>
00032 
00033 static void set_a_propos_properties(GtkWidget *about_dialog);
00034 
00035 static gboolean load_heraia_xml(heraia_struct_t *main_struct);
00036 
00037 static void heraia_ui_connect_signals(heraia_struct_t *main_struct);
00038 
00039 static void record_and_hide_about_box(heraia_struct_t *main_struct);
00040 
00041 static gboolean unsaved_documents(heraia_struct_t *main_struct);
00042 
00043 static void close_one_document(heraia_struct_t *main_struct, doc_t *closing_doc, gint index);
00044 static gboolean close_a_project(heraia_struct_t *main_struct, gchar *question);
00045 static gboolean close_heraia(heraia_struct_t *main_struct);
00046 
00047 static void on_projects_close_activate(GtkWidget *widget, gpointer data);
00048 static void on_projects_open_activate(GtkWidget *widget, gpointer data);
00049 static void on_projects_save_as_activate(GtkWidget *widget, gpointer data);
00050 
00051 /**
00052  * @fn void on_quit_activate(GtkWidget *widget, gpointer data)
00053  *  Quit, file menu
00054  * @param widget : the widget that issued the signal
00055  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00056  */
00057 void on_quit_activate(GtkWidget *widget, gpointer data)
00058 {
00059     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00060     gboolean quit_heraia = FALSE;
00061 
00062     quit_heraia = close_heraia(main_struct);
00063 
00064     if (quit_heraia == TRUE)
00065         {
00066             gtk_main_quit();
00067         }
00068 }
00069 
00070 
00071 /**
00072  * @fn void on_new_activate(GtkWidget *widget, gpointer data)
00073  *  New, file menu
00074  * @param widget : the widget that issued the signal
00075  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00076  */
00077 void on_new_activate(GtkWidget *widget, gpointer data)
00078 {
00079     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00080     Heraia_Document *new_hex_doc = NULL;
00081     GtkWidget *new_hex_widget = NULL;
00082     doc_t *doc = NULL;
00083 
00084     new_hex_doc = hex_document_new();
00085 
00086     if (new_hex_doc != NULL)
00087         {
00088             new_hex_doc->file_name = g_strdup_printf(Q_("No name"));
00089             new_hex_doc->changed = TRUE;
00090 
00091             /* creating a new view to this new document */
00092             new_hex_widget = hex_document_add_view(new_hex_doc);
00093 
00094             /* Sets some option : insert mode */
00095             gtk_hex_set_insert_mode(GTK_HEX(new_hex_widget), TRUE);
00096             gtk_hex_show_offsets(GTK_HEX(new_hex_widget), is_toggle_button_activated(main_struct->xmls->main, "mp_display_offset_bt"));
00097 
00098             /* signal connection on cursor moves */
00099             connect_cursor_moved_signal(main_struct, new_hex_widget);
00100 
00101             /* joining those two new structures in one */
00102             doc = new_doc_t(new_hex_doc, new_hex_widget);
00103 
00104             /* Adding this new doc to the list of docs (here a GPtrArray) */
00105             g_ptr_array_add(main_struct->documents, doc);
00106 
00107             add_new_tab_in_main_window(main_struct, doc);
00108             set_notebook_tab_label_color(main_struct, TRUE);
00109 
00110             grey_main_widgets(main_struct->xmls->main, FALSE);
00111 
00112             log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Hexwidget : %p"), doc->hex_widget);
00113 
00114             /* updating the window name */
00115             update_main_window_name(main_struct);
00116 
00117             if (main_struct->current_doc != NULL)
00118                 {
00119                     /* Not thread safe here ? */
00120                     main_struct->event = HERAIA_REFRESH_NEW_FILE;
00121                     refresh_event_handler(main_struct->current_doc->hex_widget, main_struct);
00122                 }
00123 
00124         }
00125 }
00126 
00127 
00128 /**
00129  * @fn void on_preferences_activate(GtkWidget *widget, gpointer data)
00130  *  Preferences, file menu :
00131  *  Displays the preference window (as a modal window)
00132  * @param widget : the widget that issued the signal
00133  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00134  */
00135 void on_preferences_activate(GtkWidget *widget, gpointer data)
00136 {
00137     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00138     GtkWidget *pref_window = NULL;
00139 
00140     pref_window = heraia_get_widget(main_struct->xmls->main, "main_preferences_window");
00141 
00142     if (pref_window != NULL)
00143         {
00144             move_and_show_dialog_box(pref_window, main_struct->win_prop->main_pref_window);
00145         }
00146 
00147 }
00148 
00149 
00150 /**
00151  * @fn void set_a_propos_properties(GtkWidget *about_dialog)
00152  * Sets name and version in the dialog box
00153  * @param about_dialog the widget that contain all the about box
00154  */
00155 static void set_a_propos_properties(GtkWidget *about_dialog)
00156 {
00157 
00158     if (about_dialog != NULL)
00159         {
00160            gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about_dialog), PACKAGE_NAME);
00161            gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about_dialog), PACKAGE_VERSION);
00162         }
00163 }
00164 
00165 
00166 /**
00167  * @fn void a_propos_activate(GtkWidget *widget, gpointer data)
00168  *  Shows apropos's dialog box
00169  * @param widget : the widget that issued the signal
00170  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00171  */
00172 void a_propos_activate(GtkWidget *widget, gpointer data)
00173 {
00174     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00175     GtkWidget *about_dialog = NULL;
00176 
00177     about_dialog = heraia_get_widget(main_struct->xmls->main, "about_dialog");
00178 
00179     if (about_dialog != NULL)
00180         {
00181             set_a_propos_properties(about_dialog);
00182             move_and_show_dialog_box(about_dialog, main_struct->win_prop->about_box);
00183         }
00184 }
00185 
00186 
00187 /**
00188  * @fn void move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00189  *  Move the dialog box to the wanted position, shows it and says it in the displayed prop
00190  * @param dialog_box : the dialog box we want to move and show
00191  * @param dialog_prop : window_prop_t properties structure corresponding to the dialog box
00192  */
00193 void move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00194 {
00195     if (dialog_prop != NULL)
00196         {
00197 
00198             if (dialog_prop->displayed == FALSE)
00199                 {
00200                     if (dialog_prop->x > 0 && dialog_prop->y > 0)
00201                         {
00202                             gtk_window_move(GTK_WINDOW(dialog_box), dialog_prop->x, dialog_prop->y);
00203                         }
00204 
00205                     if (dialog_prop->width > 0 && dialog_prop->height > 0)
00206                         {
00207                             gtk_window_resize(GTK_WINDOW(dialog_box), dialog_prop->width, dialog_prop->height);
00208                         }
00209 
00210                     gtk_widget_show_all(dialog_box);
00211                     dialog_prop->displayed = TRUE;
00212                 }
00213         }
00214 }
00215 
00216 
00217 /**
00218  * @fn void record_dialog_box_position(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00219  * Records one dialog position
00220  * @param dialog_box : a dialog box from which we want to record the position
00221  * @param[in,out] dialog_prop : window_prop_t properties structure corresponding to the dialog box
00222  */
00223 void record_dialog_box_position(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00224 {
00225     gint x = 0;
00226     gint y = 0;
00227     gint width = WPT_DEFAULT_WIDTH;
00228     gint height = WPT_DEFAULT_HEIGHT;
00229 
00230     if (dialog_prop != NULL && dialog_prop->displayed == TRUE)
00231         {
00232             if (dialog_box != NULL)
00233                 {
00234                     gtk_window_get_position(GTK_WINDOW(dialog_box), &x, &y);
00235                     gtk_window_get_size(GTK_WINDOW(dialog_box), &width, &height);
00236                     dialog_prop->x = x;
00237                     dialog_prop->y = y;
00238                     dialog_prop->width = width;
00239                     dialog_prop->height = height;
00240                 }
00241         }
00242 }
00243 
00244 
00245 /**
00246  * @fn void record_all_dialog_box_positions(heraia_struct_t *main_struct)
00247  * Records all the positions of the displayed windows
00248  * @param[in,out] main_struct : main structure
00249  */
00250 void record_all_dialog_box_positions(heraia_struct_t *main_struct)
00251 {
00252     GtkWidget *dialog_box = NULL;
00253 
00254     if (main_struct != NULL &&
00255         main_struct->xmls != NULL &&
00256         main_struct->xmls->main != NULL &&
00257         main_struct->win_prop != NULL &&
00258         main_struct->current_DW != NULL)
00259         {
00260             /* data interpretor */
00261             dialog_box = main_struct->current_DW->diw;
00262             record_dialog_box_position(dialog_box, main_struct->win_prop->data_interpretor);
00263 
00264             /* About box */
00265             dialog_box = heraia_get_widget (main_struct->xmls->main, "about_dialog");
00266             record_dialog_box_position(dialog_box, main_struct->win_prop->about_box);
00267 
00268             /* Log window */
00269             dialog_box = heraia_get_widget (main_struct->xmls->main, "log_window");
00270             record_dialog_box_position(dialog_box, main_struct->win_prop->log_box);
00271 
00272             /* main_dialog */
00273             dialog_box = heraia_get_widget (main_struct->xmls->main, "main_window");
00274             record_dialog_box_position(dialog_box, main_struct->win_prop->main_dialog);
00275 
00276             /* plugin_list */
00277             dialog_box = heraia_get_widget (main_struct->xmls->main, "plugin_list_window");
00278             record_dialog_box_position(dialog_box, main_struct->win_prop->plugin_list);
00279 
00280             /* list data types */
00281             dialog_box = heraia_get_widget (main_struct->xmls->main, "list_data_types_window");
00282             record_dialog_box_position(dialog_box, main_struct->win_prop->ldt);
00283 
00284             /* main_preferences */
00285             dialog_box = heraia_get_widget (main_struct->xmls->main, "main_preferences_window");
00286             record_dialog_box_position(dialog_box, main_struct->win_prop->main_pref_window);
00287 
00288             /* goto dialog box */
00289             dialog_box = heraia_get_widget (main_struct->xmls->main, "goto_dialog");
00290             record_dialog_box_position(dialog_box, main_struct->win_prop->goto_window);
00291 
00292             /* result window */
00293             dialog_box = heraia_get_widget (main_struct->xmls->main, "result_window");
00294             record_dialog_box_position(dialog_box, main_struct->win_prop->result_window);
00295 
00296             /* find window */
00297             dialog_box = heraia_get_widget (main_struct->xmls->main, "find_window");
00298             record_dialog_box_position(dialog_box, main_struct->win_prop->find_window);
00299 
00300             /* find and replace window */
00301             dialog_box = heraia_get_widget (main_struct->xmls->main, "fr_window");
00302             record_dialog_box_position(dialog_box, main_struct->win_prop->fr_window);
00303         }
00304 }
00305 
00306 
00307 /**
00308  * @fn void record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00309  *  Record position and hide a dialog box
00310  * @param dialog_box : the dialog box we want to record its position and then hide
00311  * @param dialog_prop : window_prop_t properties structure corresponding to the dialog box
00312  */
00313 void record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00314 {
00315 
00316     if (dialog_prop->displayed == TRUE)
00317         {
00318             record_dialog_box_position(dialog_box, dialog_prop);
00319 
00320             gtk_widget_hide(dialog_box);
00321             dialog_prop->displayed = FALSE;
00322         }
00323 }
00324 
00325 
00326 /**
00327  * @fn static void record_and_hide_about_box(heraia_struct_t *main_struct)
00328  *  Record position and hide about dialog box
00329  * @param [in,out] main_struct : main structure
00330  */
00331 static void record_and_hide_about_box(heraia_struct_t *main_struct)
00332 {
00333     GtkWidget *about_dialog = NULL;
00334 
00335     about_dialog = heraia_get_widget(main_struct->xmls->main, "about_dialog");
00336 
00337     if (about_dialog != NULL)
00338         {
00339             record_and_hide_dialog_box(about_dialog, main_struct->win_prop->about_box);
00340         }
00341 }
00342 
00343 
00344 /**
00345  * @fn void a_propos_response(GtkWidget *widget, gint response, gpointer data)
00346  *  To close the A propos dialog box (with the "close" button)
00347  * @param widget : calling widget (may be NULL as we don't use this)
00348  * @param response : may be whatever you want as we neither use this !
00349  * @param data : MUST be heraia_struct_t *main_struct main structure
00350  */
00351 static void a_propos_response(GtkWidget *widget, gint response, gpointer data)
00352 {
00353     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00354     record_and_hide_about_box(main_struct);
00355 }
00356 
00357 
00358 /**
00359  * @fn void a_propos_close(GtkWidget *widget, gpointer data)
00360  *  To close the A propos dialog box
00361  * @param widget : calling widget (may be NULL as we don't use this)
00362  * @param data : MUST be heraia_struct_t *main_struct main structure
00363  */
00364 static void a_propos_close(GtkWidget *widget, gpointer data)
00365 {
00366     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00367     record_and_hide_about_box(main_struct);
00368 }
00369 
00370 
00371 /**
00372  * @fn gboolean a_propos_delete(GtkWidget *widget, GdkEvent  *event, gpointer data)
00373  *  To close the A propos dialog box
00374  * @param widget : calling widget (may be NULL as we don't use this)
00375  * @param event : event associated (may be NULL as we don't use this)
00376  * @param data : MUST be heraia_struct_t *main_struct main structure
00377  * @return returns TRUE in order to allow other functions to do something with
00378  *         that event.
00379  */
00380 static gboolean a_propos_delete(GtkWidget *widget, GdkEvent  *event, gpointer data)
00381 {
00382     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00383     record_and_hide_about_box(main_struct);
00384 
00385     return TRUE;
00386 }
00387 
00388 
00389 /**
00390  *  Undo, edit menu
00391  * @param widget : the widget that issued the signal
00392  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00393  */
00394 void on_undo_activate(GtkWidget *widget, gpointer data)
00395 {
00396     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00397     GtkBuilder *xml = NULL;
00398     gboolean result = FALSE;
00399 
00400     if (main_struct != NULL && main_struct->current_doc != NULL && main_struct->xmls->main != NULL)
00401         {
00402             result = hex_document_undo(main_struct->current_doc->hex_doc);
00403 
00404             xml = main_struct->xmls->main;
00405 
00406             if (result == TRUE)
00407                 {
00408                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), TRUE);
00409                 }
00410 
00411             if (main_struct->current_doc->hex_doc->undo_top == NULL)
00412                 {   /* No more undos are possible. The document is as the origin ! */
00413                     set_notebook_tab_label_color(main_struct, FALSE);
00414                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), FALSE);
00415                     main_struct->current_doc->modified = FALSE;
00416                 }
00417             else
00418                 {
00419                     set_notebook_tab_label_color(main_struct, TRUE);
00420                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), TRUE);
00421                 }
00422 
00423         }
00424 
00425 }
00426 
00427 
00428 /**
00429  *  Redo, edit menu
00430  * @param widget : the widget that issued the signal
00431  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00432  */
00433 void on_redo_activate(GtkWidget *widget, gpointer data)
00434 {
00435     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00436     GtkBuilder *xml = NULL;
00437     gboolean result = FALSE;
00438 
00439     if (main_struct != NULL && main_struct->current_doc != NULL && main_struct->xmls->main != NULL)
00440         {
00441             result = hex_document_redo(main_struct->current_doc->hex_doc);
00442 
00443             xml = main_struct->xmls->main;
00444 
00445             if (result == TRUE)
00446                 {
00447                     set_notebook_tab_label_color(main_struct, TRUE);
00448                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), TRUE);
00449                     main_struct->current_doc->modified = TRUE;
00450                 }
00451 
00452             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)
00453                 {
00454                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), FALSE);
00455                 }
00456             else
00457                 {
00458                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), TRUE);
00459                 }
00460         }
00461 }
00462 
00463 
00464 /**
00465  *  Delete, edit menu
00466  * @param widget : the widget that issued the signal
00467  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00468  */
00469 void on_delete_activate(GtkWidget *widget, gpointer data)
00470 {
00471     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00472 
00473     if (main_struct != NULL && main_struct->current_doc != NULL)
00474         {
00475             gtk_hex_delete_selection(GTK_HEX(main_struct->current_doc->hex_widget));
00476             refresh_event_handler(widget, data);
00477         }
00478 }
00479 
00480 
00481 /**
00482  *  Cut, edit menu
00483  * @param widget : the widget that issued the signal
00484  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00485  */
00486 void on_cut_activate(GtkWidget *widget, gpointer data)
00487 {
00488     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00489 
00490     if (main_struct != NULL && main_struct->current_doc != NULL)
00491         {
00492             gtk_hex_cut_to_clipboard(GTK_HEX(main_struct->current_doc->hex_widget));
00493             refresh_event_handler(widget, data);
00494         }
00495 }
00496 
00497 
00498 /**
00499  *  Copy, edit menu
00500  * @param widget : the widget that issued the signal
00501  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00502  */
00503 void on_copy_activate(GtkWidget *widget, gpointer data)
00504 {
00505     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00506 
00507     if (main_struct != NULL && main_struct->current_doc != NULL)
00508         {
00509             gtk_hex_copy_to_clipboard(GTK_HEX(main_struct->current_doc->hex_widget));
00510         }
00511 }
00512 
00513 
00514 /**
00515  *  Paste, edit menu
00516  * @param widget : the widget that issued the signal
00517  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00518  */
00519 void on_paste_activate(GtkWidget *widget, gpointer data)
00520 {
00521     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00522 
00523     if (main_struct != NULL && main_struct->current_doc != NULL)
00524         {
00525             gtk_hex_paste_from_clipboard(GTK_HEX(main_struct->current_doc->hex_widget));
00526             refresh_event_handler(widget, data);
00527         }
00528 }
00529 
00530 
00531 /**
00532  * Find, Search menu
00533  * @param widget : the widget that issued the signal
00534  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00535  */
00536 void on_find_activate(GtkWidget *widget, gpointer data)
00537 {
00538     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00539 
00540     if (main_struct != NULL && main_struct->current_doc != NULL)
00541         {
00542             find_window_show(widget, main_struct);
00543         }
00544 }
00545 
00546 
00547 /**
00548  * Find and replace, Search menu
00549  * @param widget : the widget that issued the signal
00550  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00551  */
00552 void on_fr_activate(GtkWidget *widget, gpointer data)
00553 {
00554     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00555 
00556     if (main_struct != NULL && main_struct->current_doc != NULL)
00557         {
00558             fr_window_show(widget, main_struct);
00559         }
00560 }
00561 
00562 
00563 /**
00564  * Find data from type, Search menu
00565  * @param widget : the widget that issued the signal
00566  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00567  */
00568 void on_fdft_activate(GtkWidget *widget, gpointer data)
00569 {
00570     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00571 
00572     if (main_struct != NULL && main_struct->current_doc != NULL)
00573         {
00574             fdft_window_show(widget, main_struct);
00575         }
00576 }
00577 
00578 
00579 
00580 /**
00581  *  This function is refreshing the labels on the main
00582  *  window in order to reflect cursor position, selected
00583  *  positions and total selected size.
00584  *  It is also used to refresh the file label on the tab.
00585  * @param main_struct : main structure
00586  */
00587 void refresh_file_labels(heraia_struct_t *main_struct)
00588 {
00589     GtkWidget *position_label = NULL;
00590     GtkWidget *file_size_label = NULL;
00591     GtkWidget *file_sel_label = NULL;
00592     GtkWidget *file_sel_size_label = NULL;
00593     guint64 position = 0;
00594     guint64 file_size = 0;
00595     selection_t *sel = NULL;
00596     gchar *position_text = NULL;
00597     gchar *file_size_text = NULL;
00598     gchar *file_sel_text = NULL;
00599     gchar *file_sel_size_text = NULL;
00600 
00601     if (main_struct != NULL)
00602         {
00603             position_label = heraia_get_widget(main_struct->xmls->main, "file_position_label");
00604             file_size_label = heraia_get_widget(main_struct->xmls->main, "file_size_label");
00605             file_sel_label = heraia_get_widget(main_struct->xmls->main, "file_selection_label");
00606             file_sel_size_label = heraia_get_widget(main_struct->xmls->main, "file_selection_size_label");
00607 
00608             if (main_struct->current_doc != NULL && main_struct->current_doc->hex_widget != NULL)
00609                 {
00610                     position = ghex_get_cursor_position(main_struct->current_doc->hex_widget);
00611                     file_size = ghex_file_size((Heraia_Hex *) main_struct->current_doc->hex_widget);
00612                     sel = ghex_get_selection(main_struct->current_doc->hex_widget);
00613 
00614                     /* position begins at 0 and this is not really human readable */
00615                     /* it's more confusing than anything so we do + 1             */
00616                     /* To translators : do not translate <small> and such         */
00617                     if (is_toggle_button_activated(main_struct->xmls->main, "mp_thousand_bt") == TRUE)
00618                         {
00619                             position_text = g_strdup_printf("<small>%'lu</small>", (unsigned long int) (position + 1));
00620                             file_size_text = g_strdup_printf("<small>%'lu</small>", (unsigned long int) file_size);
00621                             file_sel_text = g_strdup_printf("<small>%'lu -> %'lu</small>", (unsigned long int) (sel->start + 1), (unsigned long int) (sel->end + 1));
00622                             file_sel_size_text = g_strdup_printf("<small>%'li</small>", (unsigned long int) ((sel->end - sel->start) + 1));
00623                         }
00624                     else
00625                         {
00626                             position_text = g_strdup_printf("<small>%lu</small>", (unsigned long int) (position + 1));
00627                             file_size_text = g_strdup_printf("<small>%lu</small>", (unsigned long int) file_size);
00628                             file_sel_text = g_strdup_printf("<small>%lu -> %lu</small>", (unsigned long int) (sel->start + 1), (unsigned long int) (sel->end + 1));
00629                             file_sel_size_text = g_strdup_printf("<small>%li</small>", (unsigned long int) ((sel->end - sel->start) + 1));
00630                         }
00631 
00632                     gtk_label_set_markup(GTK_LABEL(position_label), position_text);
00633                     gtk_label_set_markup(GTK_LABEL(file_size_label), file_size_text);
00634                     gtk_label_set_markup(GTK_LABEL(file_sel_label), file_sel_text);
00635                     gtk_label_set_markup(GTK_LABEL(file_sel_size_label), file_sel_size_text);
00636 
00637                     g_free(position_text);
00638                     g_free(file_size_text);
00639                     g_free(file_sel_text);
00640                     g_free(file_sel_size_text);
00641                     g_free(sel);
00642 
00643                     /* refreshing the tab filename itself if necessary only ! */
00644                     if (main_struct->current_doc->modified != main_struct->current_doc->hex_doc->changed)
00645                         {
00646                             main_struct->current_doc->modified = main_struct->current_doc->hex_doc->changed;
00647                             set_notebook_tab_label_color(main_struct, main_struct->current_doc->hex_doc->changed);
00648 
00649                             /* If the document changes, then when might undo things ... */
00650                             gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_undo"), TRUE);
00651 
00652                         }
00653 
00654                 }
00655             else
00656                 {
00657                     gtk_label_set_text(GTK_LABEL(position_label), "");
00658                     gtk_label_set_text(GTK_LABEL(file_size_label), "");
00659                     gtk_label_set_text(GTK_LABEL(file_sel_label), "");
00660                     gtk_label_set_text(GTK_LABEL(file_sel_size_label), "");
00661                 }
00662         }
00663 }
00664 
00665 
00666 /**
00667  *  This function is here to ensure that everything will be
00668  *  refreshed upon a signal event.
00669  * @warning This function is not thread safe (do not use in a thread)
00670  * @todo try to put some mutexes on main_struct->event to make this
00671  *       thread safe some way
00672  * @param widget : the widget that issued the signal
00673  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00674  */
00675 void refresh_event_handler(GtkWidget *widget, gpointer data)
00676 {
00677     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00678 
00679     if (main_struct != NULL)
00680         {
00681             /* Beware, this mechanism is not thread safe ! */
00682             if (main_struct->event == HERAIA_REFRESH_NOTHING)
00683                 {
00684                     main_struct->event = HERAIA_REFRESH_CURSOR_MOVE;
00685                 }
00686 
00687             refresh_data_interpretor_window(widget, main_struct);
00688             refresh_all_plugins(main_struct);
00689             refresh_file_labels(main_struct);
00690 
00691             main_struct->event = HERAIA_REFRESH_NOTHING;
00692         }
00693 }
00694 
00695 
00696 /**
00697  *  This handles the menuitem "Ouvrir" to open a file
00698  * @warning This function is not thread safe (do not use in a thread)
00699  * @todo try to put some mutexes on main_struct->event to make this
00700  *       thread safe some way
00701  * @param widget : the widget that issued the signal
00702  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00703  */
00704 void on_open_activate(GtkWidget *widget, gpointer data)
00705 {
00706     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00707     GSList *list = NULL;
00708     GSList *head = NULL;
00709     gboolean success = FALSE;
00710 
00711     list = select_file_to_load(main_struct, TRUE, N_("Select a file to analyse"));
00712 
00713     if (list != NULL)
00714         {
00715             head = list;
00716             while (list != NULL)
00717                 {
00718                     success = load_file_to_analyse(main_struct, list->data);
00719                     g_free(list->data);
00720                     list = g_slist_next(list);
00721                 }
00722 
00723             g_slist_free(head);
00724 
00725             if (success == TRUE && main_struct->current_doc != NULL)
00726                  {
00727                     /* Not thread safe here ? */
00728                     main_struct->event = HERAIA_REFRESH_NEW_FILE;
00729                     refresh_event_handler(main_struct->current_doc->hex_widget, main_struct);
00730                  }
00731         }
00732 }
00733 
00734 
00735 /**
00736  * Searches in a notebook's tabs for a particular widget and returns the number
00737  * of the corresponding tab if it exists, -1 otherwise
00738  * @param main_struct : main structure
00739  * @param notebbok_name : the name of the notebook in the structure
00740  * @param to_find : a GtkWidget that we want to find in the main notebook tabs
00741  * @return a gint as tha tab number that contains the widget "to_find" or -1 if
00742  *         not found
00743  */
00744 gint find_tab_number_from_widget(heraia_struct_t *main_struct, gchar *notebook_name, GtkWidget *to_find)
00745 {
00746     GtkWidget *notebook = NULL;  /**< Notenook on the main window         */
00747     GtkWidget *page = NULL;      /**< pages on the notebook               */
00748     GtkWidget *tab_label = NULL; /**< tab label GtkWidget (hbox + others) */
00749     gint nb_pages = 0;           /**< Number of pages in the notebook     */
00750     gint i = 0;
00751     gboolean found = FALSE;      /**< True when the widget has been found */
00752     GList *children = NULL;      /**< Children from the tab label         */
00753 
00754     notebook = heraia_get_widget(main_struct->xmls->main, notebook_name);
00755 
00756     nb_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
00757 
00758     i = 0;
00759     found = FALSE;
00760     while (i < nb_pages && found == FALSE)
00761         {
00762             page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
00763 
00764             if (page != NULL)
00765                 {
00766                     tab_label = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
00767 
00768                     if (GTK_IS_HBOX(tab_label))
00769                         {
00770                             children = gtk_container_get_children(GTK_CONTAINER(tab_label));
00771                         }
00772 
00773                     while (children != NULL && found == FALSE)
00774                         {
00775                             if (children->data == to_find)
00776                                 {
00777                                     found = TRUE;
00778                                 }
00779                             else
00780                                 {
00781                                     children = g_list_next(children);
00782                                 }
00783                         }
00784                 }
00785 
00786             if (found == FALSE)
00787                 {
00788                     i++;
00789                 }
00790         }
00791 
00792     if (found == TRUE)
00793         {
00794             return i;
00795         }
00796     else
00797         {
00798             return -1;
00799         }
00800 }
00801 
00802 
00803 /**
00804  * Closes an entire project
00805  * @param widget : the widget that issued the signal
00806  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00807  */
00808 static void on_projects_close_activate(GtkWidget *widget, gpointer data)
00809 {
00810     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00811 
00812     if (main_struct != NULL)
00813         {
00814             close_a_project(main_struct, N_("Do you want to close the project"));
00815         }
00816 }
00817 
00818 
00819 /**
00820  * Saves a project in a new file (does not close the project itself)
00821  * @param widget : the widget that issued the signal
00822  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00823  */
00824 static void on_projects_save_as_activate(GtkWidget *widget, gpointer data)
00825 {
00826     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00827     gchar *filename = NULL;  /**< Auto malloc'ed, do not free */
00828 
00829     if (main_struct != NULL)
00830         {
00831             filename = select_a_file_to_save(main_struct);
00832 
00833             if (filename != NULL)
00834                 {
00835                     free_preference_struct(main_struct->prefs);
00836                     main_struct->prefs = init_preference_struct(g_path_get_dirname(filename),g_path_get_basename(filename));
00837                     save_preferences(main_struct, main_struct->prefs);
00838                 }
00839         }
00840 }
00841 
00842 
00843 /**
00844  * Opens a project from a file : closes all documents an imports new ones ...
00845  * @param widget : the widget that issued the signal
00846  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00847  */
00848 static void on_projects_open_activate(GtkWidget *widget, gpointer data)
00849 {
00850     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00851     gchar *filename = NULL;
00852     GSList *list = NULL;
00853 
00854     if (main_struct != NULL)
00855         {
00856             /* We except a list with only one element (no multiple selection allowed) */
00857             list = select_file_to_load(main_struct, FALSE, (gchar *) Q_("Select a project to load"));
00858 
00859             if (list != NULL && list->data != NULL)
00860                 {
00861                     /* Closing the projects */
00862                     on_projects_close_activate(widget, data);
00863 
00864                     /* Opening the new project */
00865                     filename = list->data;
00866                     log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Loading project %s"), filename);
00867                     main_struct->prefs = init_preference_struct(g_path_get_dirname(filename), g_path_get_basename(filename));
00868                     load_preferences(main_struct, main_struct->prefs);
00869 
00870                     /* . Updating things in the interface */
00871                     gtk_widget_show_all(heraia_get_widget(main_struct->xmls->main, "file_notebook"));
00872                     init_window_states(main_struct);
00873                     g_slist_free(list);
00874                 }
00875         }
00876 }
00877 
00878 
00879 /**
00880  * Closes one document in heraia. Does not do any updates of the interface.
00881  * @param main_struct : main structure
00882  * @param closing_doc : the doc_t * document to be closed
00883  * @param index : the index in the array of documents of the closing_doc
00884  *                document
00885  */
00886 static void close_one_document(heraia_struct_t *main_struct, doc_t *closing_doc, gint index)
00887 {
00888     GtkWidget *notebook = NULL;  /**< Notenook on the main window            */
00889 
00890     if (main_struct != NULL && main_struct->documents != NULL)
00891         {
00892             /* Removing the index in the array */
00893             g_ptr_array_remove_index(main_struct->documents, index);
00894 
00895             /* Removes all results beeing associated with this document */
00896             rw_remove_all_tabs(main_struct, closing_doc);
00897 
00898             /* And removing it in the notebook */
00899             notebook = heraia_get_widget(main_struct->xmls->main, "file_notebook");
00900             gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), index);
00901 
00902             /* kills the widget and the document */
00903             close_doc_t(closing_doc);
00904         }
00905 }
00906 
00907 
00908 /**
00909  * Closes an opened file
00910  * @param widget : the widget that issued the signal
00911  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00912  */
00913 void on_close_activate(GtkWidget *widget, gpointer data)
00914 {
00915     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00916     doc_t *closing_doc = NULL;   /**< Current document to close in heraia    */
00917     doc_t *document = NULL;      /**< To iterate over the array of documents */
00918     GtkWidget *notebook = NULL;  /**< Notenook on the main window            */
00919     GtkWidget *dialog = NULL;    /**< The dialog box                         */
00920     GtkWidget *parent = NULL;    /**< parent widget for the dialog box       */
00921     gint result = 0;             /**< result from the dialog box             */
00922     gint index = -1;
00923     gint i = 0;
00924     gint tab_number = 0;
00925     gboolean is_current_doc = FALSE; /**< Says wheter the document that we are
00926                                           trying to close is the current one or
00927                                           not                                 */
00928 
00929     if (main_struct != NULL && main_struct->current_doc != NULL)
00930         {
00931             /* Guessing where the user asked to close the document */
00932             if (GTK_IS_BUTTON(widget))
00933                 {   /* From the tab */
00934                     /* Guessing which document the user has closed */
00935                     tab_number = find_tab_number_from_widget(main_struct, "file_notebook", widget);
00936                     closing_doc = g_ptr_array_index(main_struct->documents, tab_number);
00937                     is_current_doc = (closing_doc == main_struct->current_doc);
00938                 }
00939             else
00940                 {   /* From the menu */
00941                     closing_doc = main_struct->current_doc;
00942                     is_current_doc = TRUE;
00943                 }
00944 
00945             log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Closing document %s"), doc_t_document_get_filename(closing_doc));
00946 
00947             if (closing_doc->modified == TRUE)
00948                 {
00949                     /* Displays a dialog box that let the user choose what to do */
00950                     parent = heraia_get_widget(main_struct->xmls->main, "main_window");
00951 
00952                     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 !"));
00953                     gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog), Q_("Do you want to close it without saving it ?"));
00954 
00955                     result = gtk_dialog_run(GTK_DIALOG(dialog));
00956 
00957                     gtk_widget_destroy(dialog);
00958 
00959                     switch (result)
00960                         {
00961                             case GTK_RESPONSE_YES: /* Will continue if we say Yes */
00962                             break;
00963 
00964                             default:  /* Stops closing if we say No */
00965                                 return;
00966                             break;
00967                         }
00968                 }
00969 
00970             /* Try to catch the index of the closing document */
00971             i = 0;
00972             index = -1;
00973             while (i < main_struct->documents->len && index == -1)
00974                 {
00975                     document = g_ptr_array_index(main_struct->documents, i);
00976                     if (document == closing_doc)
00977                         {
00978                             index = i;
00979                         }
00980                     i++;
00981                 }
00982 
00983             if (index >= 0)
00984                 {
00985                     close_one_document(main_struct, closing_doc, index);
00986 
00987                     /* Try to find out the new current document */
00988                     /* We do not need to update if the current doc is not closed ! */
00989                     if (is_current_doc == TRUE)
00990                         {
00991                             if (main_struct->documents->len > 0)
00992                                 {
00993                                     /* there is still some documents opened (at least one) */
00994                                     if (index == 0)
00995                                         {
00996                                             main_struct->current_doc = g_ptr_array_index(main_struct->documents, 0);
00997                                             gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
00998                                         }
00999                                     else
01000                                         {
01001                                             main_struct->current_doc = g_ptr_array_index(main_struct->documents, index - 1);
01002                                             gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), index - 1);
01003                                         }
01004                                 }
01005                             else
01006                                 {
01007                                     /* No more documents openned */
01008                                     main_struct->current_doc = NULL;
01009                                     grey_main_widgets(main_struct->xmls->main, TRUE);
01010                                 }
01011                         }
01012                     /* updating things in conformance to the new situation */
01013                     refresh_event_handler(notebook, main_struct);
01014                     update_main_window_name(main_struct);
01015                 }
01016         }
01017 }
01018 
01019 
01020 /**
01021  *  Here we attemp to save the edited file
01022  *  @todo be more accurate on error (error type, message and filename) returns
01023  *        we should return something at least ...
01024  * @param widget : the widget that issued the signal
01025  * @param data : user data MUST be heraia_struct_t *main_struct main structure
01026  */
01027 void on_save_activate(GtkWidget *widget, gpointer data)
01028 {
01029     heraia_struct_t *main_struct = (heraia_struct_t *) data;
01030     HERAIA_ERROR erreur = HERAIA_NOERR;
01031     gchar *filename = NULL;
01032 
01033     if (main_struct != NULL && main_struct->current_doc != NULL)
01034         {
01035             erreur = heraia_hex_document_save(main_struct->current_doc);
01036 
01037             if (erreur != HERAIA_NOERR)
01038                 {
01039                     filename = doc_t_document_get_filename(main_struct->current_doc);
01040                     log_message(main_struct, G_LOG_LEVEL_ERROR, Q_("Error while saving file %s !"), filename);
01041                 }
01042             else
01043                 {
01044                     set_notebook_tab_label_color(main_struct, FALSE);
01045                     main_struct->current_doc->modified = FALSE; /* document has just been saved (thus it is not modified !) */
01046                 }
01047         }
01048 }
01049 
01050 
01051 /**
01052  * @fn void on_save_as_activate(GtkWidget *widget, gpointer data)
01053  *  This handle the save_as menu entry (here the filename changes)
01054  * @param widget : the widget that issued the signal
01055  * @param data : user data MUST be heraia_struct_t *main_struct main structure
01056  */
01057 void on_save_as_activate(GtkWidget *widget, gpointer data)
01058 {
01059     heraia_struct_t *main_struct = (heraia_struct_t *) data;
01060     HERAIA_ERROR erreur = HERAIA_NOERR;
01061     gchar *filename = NULL;  /**< Auto malloc'ed, do not free */
01062 
01063     if (main_struct != NULL && main_struct->current_doc != NULL)
01064         {
01065             filename = select_a_file_to_save(main_struct);
01066 
01067             if (filename != NULL)
01068                 {
01069                     erreur = heraia_hex_document_save_as(main_struct->current_doc, filename);
01070                 }
01071             else
01072                 {
01073                     erreur = HERAIA_CANCELLED;
01074                 }
01075 
01076             if (erreur != HERAIA_NOERR)
01077                 {
01078                     if (erreur == HERAIA_CANCELLED)
01079                         {
01080                             log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Saving file as... : operation cancelled."));
01081                         }
01082                     else
01083                         {
01084                             log_message(main_struct, G_LOG_LEVEL_ERROR, Q_("Error while saving file as %s"), doc_t_document_get_filename(main_struct->current_doc));
01085                         }
01086                 }
01087             else
01088                 {
01089                     /* updating the window name and tab's name */
01090                     update_main_window_name(main_struct);
01091                     set_notebook_tab_name(main_struct);
01092                     main_struct->current_doc->modified = FALSE; /* document has just been saved (thus it is not modified !) */
01093                     log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("File %s saved and now edited."), doc_t_document_get_filename(main_struct->current_doc));
01094                 }
01095         }
01096 }
01097 
01098 
01099 /**
01100  * @fn void on_DIMenu_activate(GtkWidget *widget, gpointer data)
01101  *  This handles the menuitem "Data Interpretor" that
01102  *  shows or hides the data interpretor window
01103  * @param widget : the widget that issued the signal
01104  * @param data : user data MUST be heraia_struct_t *main_struct main structure
01105  */
01106 void on_DIMenu_activate(GtkWidget *widget, gpointer data)
01107 {
01108 
01109     heraia_struct_t *main_struct = (heraia_struct_t *) data;
01110     data_window_t *dw = NULL;      /**< data_window structure for data interpretor */
01111     GtkNotebook *notebook = NULL;  /**< data interpretor's notebook                */
01112 
01113     if (main_struct != NULL)
01114         {
01115             dw = main_struct->current_DW;
01116 
01117             if (dw != NULL)
01118                 {
01119                     if (dw->diw == NULL)
01120                         {
01121                             dw->diw = heraia_get_widget(main_struct->xmls->main, "data_interpretor_window");
01122                         }
01123 
01124                     if (dw->diw != NULL)
01125                         {
01126                             notebook = GTK_NOTEBOOK(heraia_get_widget(main_struct->xmls->main, "diw_notebook"));
01127 
01128                             if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(heraia_get_widget(main_struct->xmls->main, "DIMenu"))) == TRUE)
01129                                 {
01130                                     /* Setting the first page of the notebook as default (Numbers) */
01131                                     gtk_notebook_set_current_page(notebook, dw->tab_displayed);
01132 
01133                                     /* moving to the right position */
01134                                     move_and_show_dialog_box(dw->diw, main_struct->win_prop->data_interpretor);
01135 
01136                                     refresh_data_interpretor_window(widget, data);
01137                                 }
01138                             else
01139                                 {
01140                                     /* recording some prefs from the dialog : position + opened tab */
01141                                     dw->tab_displayed = gtk_notebook_get_current_page(notebook);
01142                                     record_and_hide_dialog_box(dw->diw, main_struct->win_prop->data_interpretor);
01143                                 }
01144                         }
01145                 }
01146         }
01147 }
01148 
01149 
01150 /**
01151  * Called when tests submenu is activated
01152  * @param widget : the widget that issued the signal
01153  * @param data : user data MUST be heraia_struct_t *main_struct main structure
01154  */
01155 void on_tests_menu_activate(GtkWidget *widget, gpointer data)
01156 {
01157     heraia_struct_t *main_struct = (heraia_struct_t *) data;
01158     gboolean result = FALSE;
01159 
01160     if (main_struct != NULL)
01161         {
01162             result = tests_ui(main_struct);
01163 
01164             if (result == TRUE)
01165                 {
01166                     log_message(main_struct, G_LOG_LEVEL_INFO, Q_("All tests went Ok."));
01167                 }
01168             else
01169                 {
01170                     log_message(main_struct, G_LOG_LEVEL_WARNING, Q_("Some tests failed."));
01171                 }
01172         }
01173 }
01174 
01175 
01176 /**
01177  * @fn delete_main_struct_event(GtkWidget *widget, GdkEvent  *event, gpointer data)
01178  *  When the user destroys or delete the main window
01179  * @param widget : calling widget
01180  * @param event : event associated (may be NULL as we don't use this here)
01181  * @param data : MUST be heraia_struct_t *main_struct main structure
01182  */
01183 gboolean delete_main_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data)
01184 {
01185 
01186     on_quit_activate(widget, data);
01187 
01188     /* If we are leaving heraia, we are not supposed to be here ! */
01189     return TRUE;
01190 }
01191 
01192 
01193 /**
01194  * @fn gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data)
01195  *  call back function for the data interpretor window destruction
01196  * @param widget : calling widget (may be NULL as we don't use this here)
01197  * @param event : event associated (may be NULL as we don't use this here)
01198  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
01199  */
01200 gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data)
01201 {
01202     heraia_struct_t *main_struct = (heraia_struct_t *) data;
01203 
01204     g_signal_emit_by_name(heraia_get_widget(main_struct->xmls->main, "DIMenu"), "activate");
01205 
01206     return TRUE;
01207 }
01208 
01209 
01210 /**
01211  * @fn void destroy_dt_window(GtkWidget *widget, GdkEvent  *event, gpointer data)
01212  *  call back function for the data interpretor window destruction
01213  * @param widget : calling widget (may be NULL as we don't use this here)
01214  * @param event : event associated (may be NULL as we don't use this here)
01215  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
01216  */
01217 void destroy_dt_window(GtkWidget *widget, GdkEvent  *event, gpointer data)
01218 {
01219     heraia_struct_t *main_struct = (heraia_struct_t *) data;
01220 
01221     g_signal_emit_by_name(heraia_get_widget(main_struct->xmls->main, "DIMenu"), "activate");
01222 }
01223 
01224 
01225 /**
01226  * What to do when a change occurs in tabs (user selected a particular
01227  * tab)
01228  * @param notebook : the widget that issued this signal
01229  * @param page : the new current page
01230  * @param tab_num : index of this page
01231  * @param data : MUST be heraia_struct_t *main_struct !
01232  */
01233 gboolean file_notebook_tab_changed(GtkNotebook *notebook, GtkNotebookPage *page, gint tab_num, gpointer data)
01234 {
01235     heraia_struct_t *main_struct = (heraia_struct_t *) data;
01236 
01237     if (main_struct != NULL)
01238         {
01239             if (tab_num >= 0 && tab_num <= main_struct->documents->len)
01240                 {
01241                     /* Current document is now from the selected tab */
01242                     main_struct->current_doc = g_ptr_array_index(main_struct->documents, tab_num);
01243 
01244                     /* Changing main window's name */
01245                     update_main_window_name(main_struct);
01246 
01247                     /* Refreshing the view */
01248                     main_struct->event = HERAIA_REFRESH_TAB_CHANGED;
01249                     refresh_event_handler(GTK_WIDGET(notebook), main_struct);
01250                     main_struct->event = HERAIA_REFRESH_NOTHING;
01251                 }
01252         }
01253 
01254     return TRUE;
01255 }
01256 
01257 /* End of call back functions that handle the data interpretor window */
01258 
01259 
01260 /**
01261  * @fn static gchar *make_absolute_path(gchar *filename)
01262  *  Returns an absolute path to the filename
01263  *  the string should be freed when no longer needed
01264  *  very UGLy !
01265  * @todo do something without any system calls !!!
01266  * @param filename : relative notation filename from which to extract an
01267  *        absolute path
01268  * @return returns a string with the absolute path which should be freed when
01269  *         no longer needed
01270  */
01271 static gchar *make_absolute_path(gchar *filename)
01272 {
01273     gchar *current_dir = NULL;
01274     gchar *new_dir = NULL;
01275 
01276     if (g_path_is_absolute(filename) == TRUE)
01277         {
01278             /* if the filename is already in an absolute format */
01279             return  g_path_get_dirname(filename);
01280         }
01281     else
01282         {
01283             current_dir = g_get_current_dir();
01284             new_dir = g_path_get_dirname(filename);
01285 
01286             if (g_chdir(new_dir) == 0)
01287                 {
01288                     g_free(new_dir);
01289                     new_dir = g_get_current_dir();
01290                     g_chdir(current_dir);
01291                     g_free(current_dir);
01292 
01293                     return new_dir;
01294                 }
01295             else
01296                 {
01297                     g_free(current_dir);
01298 
01299                     return NULL;
01300                 }
01301         }
01302 }
01303 
01304 
01305 /**
01306  *  Sets the working directory for the file chooser to the directory of the
01307  *  filename (even if filename is a relative filename such as ../docs/test_file)
01308  * @param file_chooser : An initialized GtkFileChooser
01309  * @param filename : a filename (one previously openned)
01310  */
01311 void set_the_working_directory(GtkFileChooser *file_chooser, gchar *filename)
01312 {
01313     gchar *dirname = NULL;    /**< directory where we want to be, at first, in the file chooser */
01314 
01315     dirname = make_absolute_path(filename);
01316 
01317     if (dirname != NULL)
01318         {
01319             gtk_file_chooser_set_current_folder(file_chooser, dirname);
01320             g_free(dirname);
01321         }
01322 }
01323 
01324 
01325 /**
01326  *  This function does open a file selector dialog box and returns the selected
01327  *  filename.
01328  * @param main_struct : main structure
01329  * @param multiple : to say wether we want multiple selection be possible or not
01330  * @param message : the message to print in the title's dialog box
01331  * @return returns a list of filenames to be loaded (if any)
01332  */
01333 GSList *select_file_to_load(heraia_struct_t *main_struct, gboolean multiple, gchar *message)
01334 {
01335     GtkWidget *parent = NULL; /**< A parent window (we use main_struct)            */
01336     GtkFileChooser *file_chooser = NULL;
01337     GSList *list = NULL;   /**< list of selected (if any) filenames to be openned  */
01338 
01339     parent = heraia_get_widget(main_struct->xmls->main, "main_window");
01340 
01341     file_chooser = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(message,
01342                                                                 GTK_WINDOW(parent),
01343                                                                 GTK_FILE_CHOOSER_ACTION_OPEN,
01344                                                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
01345                                                                 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
01346                                                                 NULL));
01347 
01348     gtk_window_set_modal(GTK_WINDOW(file_chooser), TRUE);
01349     gtk_file_chooser_set_select_multiple(file_chooser, multiple);
01350 
01351     /**
01352      *  We want the file selection path to be the one of the current
01353      *  opened file if any !
01354      */
01355     if (doc_t_document_get_filename(main_struct->current_doc) != NULL)
01356        {
01357             set_the_working_directory(file_chooser, doc_t_document_get_filename(main_struct->current_doc));
01358        }
01359 
01360     switch (gtk_dialog_run(GTK_DIALOG(file_chooser)))
01361         {
01362             case GTK_RESPONSE_OK:
01363 
01364                 list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(file_chooser));
01365                 gtk_widget_destroy(GTK_WIDGET(file_chooser));
01366 
01367                 return list;
01368              break;
01369 
01370             case GTK_RESPONSE_CANCEL:
01371             default:
01372                 gtk_widget_destroy(GTK_WIDGET(file_chooser));
01373 
01374                 return NULL;
01375              break;
01376         }
01377 }
01378 
01379 
01380 /**
01381  *  This function opens a dialog box that allow one to choose a
01382  *  file name to the file which is about to be saved
01383  * @param main_struct : main structure
01384  * @return returns complete filename (path and filename)
01385  */
01386 gchar *select_a_file_to_save(heraia_struct_t *main_struct)
01387 {
01388     GtkWidget *parent = NULL;     /**< A parent window (we use main_struct) */
01389     GtkFileChooser *fcd = NULL;
01390     gchar *filename = NULL;
01391 
01392     parent = heraia_get_widget(main_struct->xmls->main, "main_window");
01393 
01394     /* Selection a name to the file to save */
01395     fcd = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(Q_("Save As..."),
01396                                                        GTK_WINDOW(parent),
01397                                                        GTK_FILE_CHOOSER_ACTION_SAVE,
01398                                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
01399                                                        GTK_STOCK_SAVE, GTK_RESPONSE_OK,
01400                                                        NULL));
01401 
01402     /* window properties : modal, without multi-selection and with confirmation */
01403     gtk_window_set_modal(GTK_WINDOW(fcd), TRUE);
01404     gtk_file_chooser_set_select_multiple(fcd, FALSE);
01405     gtk_file_chooser_set_do_overwrite_confirmation(fcd, TRUE);
01406 
01407     /* we do want to have the file's directory where to save the new file */
01408     if (doc_t_document_get_filename(main_struct->current_doc) != NULL)
01409        {
01410             set_the_working_directory(fcd, doc_t_document_get_filename(main_struct->current_doc));
01411        }
01412 
01413     switch(gtk_dialog_run(GTK_DIALOG(fcd)))
01414         {
01415             case GTK_RESPONSE_OK:
01416                 /* retrieving the filename */
01417                 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fcd));
01418                 break;
01419             default:
01420                 filename = NULL;
01421                 break;
01422         }
01423 
01424     gtk_widget_destroy(GTK_WIDGET(fcd));
01425 
01426     return filename;
01427 }
01428 
01429 
01430 /**
01431  *  Update main window heraia's name to reflect the current edited file
01432  * @param main_struct : main structure
01433  */
01434 void update_main_window_name(heraia_struct_t *main_struct)
01435 {
01436     GtkWidget *widget = NULL;
01437     gchar *filename = NULL;
01438     gchar *whole_filename = NULL;
01439 
01440     if (main_struct != NULL && main_struct->current_doc != NULL)
01441         {
01442             widget = heraia_get_widget(main_struct->xmls->main, "main_window");
01443 
01444             whole_filename = doc_t_document_get_filename(main_struct->current_doc);
01445 
01446             filename = g_filename_display_basename(whole_filename);
01447 
01448             gtk_window_set_title(GTK_WINDOW(widget), filename);
01449         }
01450     else if (main_struct != NULL)
01451         {
01452             widget = heraia_get_widget(main_struct->xmls->main, "main_window");
01453             gtk_window_set_title(GTK_WINDOW(widget), "Heraia");
01454         }
01455 }
01456 
01457 
01458 /**
01459  * Tries to find the label contained in the hbox
01460  * @param hbox : the hbox widget containing one GtkLabel
01461  * @return the label or NULL if not found
01462  */
01463 GtkWidget *find_label_from_hbox(GtkWidget *hbox)
01464 {
01465     GList *children = NULL;     /**< List of children in hbox widget */
01466     gboolean found = FALSE;
01467 
01468     if (hbox != NULL)
01469         {
01470             children = gtk_container_get_children(GTK_CONTAINER(hbox));
01471             found = FALSE;
01472 
01473             while (children != NULL && found == FALSE)
01474                 {
01475                     if (GTK_IS_LABEL(children->data))
01476                         {
01477                             found = TRUE;
01478                         }
01479                     else
01480                         {
01481                             children = g_list_next(children);
01482                         }
01483                 }
01484 
01485             if (found == TRUE)
01486                 {
01487                     return children->data;
01488                 }
01489             else
01490                 {
01491                     return NULL;
01492                 }
01493         }
01494     else
01495         {
01496             return NULL;
01497         }
01498 }
01499 
01500 
01501 /**
01502  *  Sets notebook's tab's name. This function should only be called
01503  *  when a new filename was set (open and save as functions)
01504  * @param main_struct : main structure
01505  */
01506 void set_notebook_tab_name(heraia_struct_t *main_struct)
01507 {
01508     GtkWidget *notebook = NULL; /**< file notebook in main window                */
01509     GtkWidget *page = NULL;     /**< Current page for the file notebook          */
01510     GtkWidget *hbox = NULL;     /**< container that has the label and the button */
01511     GtkWidget *label = NULL;    /**< tab's label                                 */
01512     doc_t *doc = NULL;          /**< corresponding tab's document                */
01513     gchar *filename = NULL;
01514     gchar *whole_filename;
01515     gint current = 0;           /**< index of the current tab displayed          */
01516     gchar *markup= NULL;        /**< markup text                                 */
01517 
01518     if (main_struct != NULL && main_struct->current_doc != NULL)
01519         {
01520             notebook = heraia_get_widget(main_struct->xmls->main, "file_notebook");
01521             current = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
01522             page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), current);
01523             hbox = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
01524             label = find_label_from_hbox(hbox);
01525 
01526             if (label != NULL)
01527                 {
01528                     doc = g_ptr_array_index(main_struct->documents, current);
01529                     whole_filename = doc_t_document_get_filename(doc);
01530 
01531                     if (whole_filename != NULL)
01532                         {
01533                             filename = g_filename_display_basename(whole_filename);
01534                             markup =  g_markup_printf_escaped("%s", filename);
01535                             gtk_label_set_markup(GTK_LABEL(label), markup);
01536                             gtk_widget_set_tooltip_text(label, g_filename_display_name(whole_filename));
01537                             g_free(markup);
01538                         }
01539                 }
01540         }
01541 }
01542 
01543 
01544 /**
01545  * Set the style for the label
01546  * @param main_struct : main structure
01547  * @param color : If color is TRUE sets the color for the file tab's label
01548  *                If not, then sets it to default
01549  */
01550 void set_notebook_tab_label_color(heraia_struct_t *main_struct, gboolean color)
01551 {
01552     GtkWidget *notebook = NULL;   /**< file notebook in main window                */
01553     GtkWidget *page = NULL;       /**< Current page for the file notebook          */
01554     GtkWidget *label = NULL;      /**< tab's label                                 */
01555     GtkWidget *menu_label = NULL; /**< menu tab's label                            */
01556     GtkWidget *hbox = NULL;       /**< container that has the label and the button */
01557     gint current = 0;             /**< index of the current tab displayed          */
01558     gchar *markup= NULL;          /**< markup text                                 */
01559     gchar *text = NULL;           /**< label's text                                */
01560 
01561     if (main_struct != NULL && main_struct->current_doc != NULL)
01562         {
01563             notebook = heraia_get_widget(main_struct->xmls->main, "file_notebook");
01564             current = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
01565             page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), current);
01566             hbox = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
01567             label = find_label_from_hbox(hbox);
01568 
01569             if (label != NULL)
01570                 {
01571                     text = g_strdup(gtk_label_get_text(GTK_LABEL(label)));
01572 
01573                     if (color == TRUE)
01574                         {
01575                             markup = g_markup_printf_escaped("<span foreground=\"blue\">%s</span>", text);
01576                         }
01577                     else
01578                         {
01579                             markup = g_markup_printf_escaped("%s", text);
01580                         }
01581 
01582                     log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Changing color for filename %s in tab : %d"), markup, current);
01583                     gtk_label_set_markup(GTK_LABEL(label), markup);
01584                     menu_label = gtk_label_new(NULL);
01585                     gtk_label_set_markup(GTK_LABEL(menu_label), markup);
01586                     gtk_notebook_set_menu_label(GTK_NOTEBOOK(notebook), page, menu_label);
01587 
01588                     g_free(markup);
01589                     g_free(text);
01590                 }
01591         }
01592 }
01593 
01594 
01595 /**
01596  * Hides or grey all widgets that needs an open file when boolean greyed is
01597  * TRUE. Also sets the current page of the notebook to the first one.
01598  * @param xml : GtkBuilder XML main structure
01599  * @param greyed : boolean (TRUE to hide an grey widgets)
01600  */
01601 void grey_main_widgets(GtkBuilder *xml, gboolean greyed)
01602 {
01603     GtkWidget *notebook = NULL;  /* file notebook in main window */
01604 
01605     if (xml != NULL)
01606         {
01607             notebook = heraia_get_widget(xml, "file_notebook");
01608 
01609             if (greyed == TRUE)
01610                 {
01611                     gtk_widget_set_sensitive(heraia_get_widget(xml, "save"), FALSE);
01612                     gtk_widget_set_sensitive(heraia_get_widget(xml, "save_as"), FALSE);
01613                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_cut"), FALSE);
01614                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_copy"), FALSE);
01615                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_paste"), FALSE);
01616                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_delete"), FALSE);
01617                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_close"), FALSE);
01618                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_goto"), FALSE);
01619                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_search"), FALSE);
01620                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_projects_close"), FALSE);
01621                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_projects_save_as"), FALSE);
01622                     gtk_widget_hide(notebook);
01623                 }
01624             else
01625                 {
01626                     gtk_widget_set_sensitive(heraia_get_widget(xml, "save"), TRUE);
01627                     gtk_widget_set_sensitive(heraia_get_widget(xml, "save_as"), TRUE);
01628                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_cut"), TRUE);
01629                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_copy"), TRUE);
01630                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_paste"), TRUE);
01631                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_delete"), TRUE);
01632                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_close"), TRUE);
01633                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_goto"), TRUE);
01634                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_search"), TRUE);
01635                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_projects_close"), TRUE);
01636                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_projects_save_as"), TRUE);
01637                     gtk_widget_show_all(notebook);
01638                 }
01639         }
01640 }
01641 
01642 
01643 /**
01644  *  Here we might init some call backs and menu options
01645  *  and display the interface (main && sub-windows)
01646  *  This function should be called only once at main program's
01647  *  init time
01648  * @param main_struct : main structure
01649  */
01650 void init_heraia_interface(heraia_struct_t *main_struct)
01651 {
01652 
01653     if (main_struct != NULL)
01654         {
01655             /* inits window states (shows or hide windows) */
01656             init_window_states(main_struct);
01657 
01658             /* menus */
01659             gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_redo"), FALSE);
01660             gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_undo"), FALSE);
01661 
01662             if (main_struct->current_doc != NULL)
01663                 {
01664                     grey_main_widgets(main_struct->xmls->main, FALSE);
01665                 }
01666             else
01667                 {
01668                     grey_main_widgets(main_struct->xmls->main, TRUE);
01669                 }
01670 
01671             refresh_file_labels(main_struct);
01672         }
01673 }
01674 
01675 
01676 /**
01677  *  Loads the GtkBuilder xml files that describes the heraia project
01678  *  tries the following paths in that order :
01679  *  - /etc/heraia/heraia.gtkbuilder
01680  *  - /home/[user]/.heraia/heraia.gtkbuilder
01681  *  - PWD/heraia.gtkbuilder
01682  * @param main_struct : main structure
01683  * @return TRUE if everything went ok, FALSE otherwise
01684  */
01685 static gboolean load_heraia_xml(heraia_struct_t *main_struct)
01686 {
01687     gchar *filename = NULL;
01688 
01689     if (main_struct != NULL && main_struct->xmls != NULL)
01690         {
01691             filename = g_strdup_printf("heraia.gtkbuilder");
01692             main_struct->xmls->main = load_xml_file(main_struct->location_list, filename);
01693             g_free(filename);
01694 
01695             if (main_struct->xmls->main == NULL)
01696                 {
01697                     return FALSE;
01698                 }
01699             else
01700                 {
01701                     /* log_message(main_struct, G_LOG_LEVEL_DEBUG, "%s", gtk_builder_get_translation_domain(main_struct->xmls->main));
01702                        gtk_builder_set_translation_domain(main_struct->xmls->main, GETTEXT_PACKAGE);
01703                        log_message(main_struct, G_LOG_LEVEL_DEBUG, "%s", gtk_builder_get_translation_domain(main_struct->xmls->main));
01704                     */
01705                     return TRUE;
01706                 }
01707         }
01708     else
01709         {
01710             return FALSE;
01711         }
01712 }
01713 
01714 
01715 /**
01716  *  Connects the signal that the cursor has moved to
01717  *  the refreshing function
01718  * @param main_struct : main structure
01719  * @param hex_widget : the hex_widget we want to connect the signal to
01720  */
01721 void connect_cursor_moved_signal(heraia_struct_t *main_struct, GtkWidget *hex_widget)
01722 {
01723     g_signal_connect(G_OBJECT(hex_widget), "cursor_moved",
01724                      G_CALLBACK(refresh_event_handler), main_struct);
01725 }
01726 
01727 
01728 /**
01729  *  Connect the signals at the interface
01730  * @param main_struct : main structure
01731  */
01732 static void heraia_ui_connect_signals(heraia_struct_t *main_struct)
01733 {
01734 
01735     /*** File Menu ***/
01736     /* Quit, file menu */
01737     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "quit")), "activate",
01738                      G_CALLBACK(on_quit_activate), main_struct);
01739 
01740     /* New, file menu */
01741     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "new")), "activate",
01742                      G_CALLBACK(on_new_activate), main_struct);
01743 
01744     /* Open, file menu */
01745     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "open")), "activate",
01746                      G_CALLBACK(on_open_activate), main_struct);
01747 
01748     /* Close, file menu */
01749     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_close")), "activate",
01750                      G_CALLBACK(on_close_activate), main_struct);
01751 
01752     /* Save, file menu */
01753     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "save")), "activate",
01754                      G_CALLBACK(on_save_activate), main_struct);
01755 
01756     /* Save As, file menu */
01757     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "save_as")), "activate",
01758                      G_CALLBACK(on_save_as_activate), main_struct);
01759 
01760     /**** Projects sub menu ****/
01761     /* Close, projects sub menu, file menu */
01762     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_projects_close")), "activate",
01763                      G_CALLBACK(on_projects_close_activate), main_struct);
01764 
01765     /* Save As, projects sub menu, file menu */
01766     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_projects_save_as")), "activate",
01767                      G_CALLBACK(on_projects_save_as_activate), main_struct);
01768 
01769     /* Open, projects sub menu, file menu */
01770     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_projects_open")), "activate",
01771                      G_CALLBACK(on_projects_open_activate), main_struct);
01772 
01773 
01774     /*** Edit Menu ***/
01775     /* Goto dialog, edit menu */
01776     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_goto")), "activate",
01777                      G_CALLBACK(on_goto_activate), main_struct);
01778 
01779     /* Preferences, Edit menu ; See main_pref_window.c for main_pref_window's signals */
01780     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "preferences")), "activate",
01781                      G_CALLBACK(on_preferences_activate), main_struct);
01782 
01783    /* Undo, edit menu */
01784     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_undo")), "activate",
01785                      G_CALLBACK(on_undo_activate), main_struct);
01786 
01787    /* Redo, edit menu */
01788     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_redo")), "activate",
01789                      G_CALLBACK(on_redo_activate), main_struct);
01790 
01791     /* Cut, edit menu */
01792     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_cut")), "activate",
01793                      G_CALLBACK(on_cut_activate), main_struct);
01794 
01795     /* Copy, edit menu */
01796     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_copy")), "activate",
01797                      G_CALLBACK(on_copy_activate), main_struct);
01798 
01799     /* Paste, edit menu */
01800     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_paste")), "activate",
01801                      G_CALLBACK(on_paste_activate), main_struct);
01802 
01803     /* Delete, edit menu */
01804     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_delete")), "activate",
01805                      G_CALLBACK(on_delete_activate), main_struct);
01806 
01807 
01808      /*** Search Menu ***/
01809     /* Find, Search menu */
01810     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_find")), "activate",
01811                      G_CALLBACK(on_find_activate), main_struct);
01812 
01813     /* Find and replace, Search menu */
01814     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_find_replace")), "activate",
01815                      G_CALLBACK(on_fr_activate), main_struct);
01816 
01817     /* Find data from type, Search menu */
01818     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_fdft")), "activate",
01819                      G_CALLBACK(on_fdft_activate), main_struct);
01820 
01821 
01822     /*** Display menu ***/
01823     /* the data interpretor menu */
01824     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "DIMenu")), "activate",
01825                      G_CALLBACK(on_DIMenu_activate), main_struct);
01826 
01827 
01828     /*** Help Menu ***/
01829     /* Test, Help menu */
01830     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "tests_menu")), "activate",
01831                      G_CALLBACK(on_tests_menu_activate), main_struct);
01832 
01833     /* about dialog box */
01834     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "a_propos")), "activate",
01835                      G_CALLBACK(a_propos_activate), main_struct);
01836 
01837     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "close",
01838                      G_CALLBACK(a_propos_close), main_struct);
01839 
01840     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "response",
01841                      G_CALLBACK(a_propos_response), main_struct);
01842 
01843     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "delete-event",
01844                      G_CALLBACK(a_propos_delete), main_struct);
01845 
01846 
01847     /* main notebook */
01848     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "file_notebook")),"switch-page",
01849                      G_CALLBACK(file_notebook_tab_changed), main_struct);
01850 
01851 
01852     /* main window killed or destroyed */
01853     g_signal_connect(G_OBJECT (heraia_get_widget(main_struct->xmls->main, "main_window")), "delete-event",
01854                      G_CALLBACK(delete_main_window_event), main_struct);
01855 }
01856 
01857 
01858 /** @fn int load_heraia_ui(heraia_struct_t *main_struct)
01859  *  Loads, if possible, the gtkbuilder xml file and then connects the
01860  *  signals and inits the following windows :
01861  *  - log window
01862  *  - data_interpretor window
01863  *  - list data types
01864  * @param main_struct : main structure
01865  * @return TRUE if load_heraia_xml suceeded, FALSE otherwise
01866  * @todo add more return values to init functions to detect any error while
01867  *       initializing the ui
01868  */
01869 int load_heraia_ui(heraia_struct_t *main_struct)
01870 {
01871     gboolean success = FALSE;
01872 
01873     /* load the XML interfaces (main & treatment) */
01874     success = load_heraia_xml(main_struct);
01875 
01876     if (success == TRUE)
01877         {
01878             /* Heraia UI signals */
01879             if (main_struct->debug == TRUE)
01880                 {
01881                     fprintf(stdout, Q_("Connecting heraia_ui signals             "));
01882                 }
01883 
01884             heraia_ui_connect_signals(main_struct);
01885 
01886             if (main_struct->debug == TRUE)
01887                 {
01888                     fprintf(stdout, Q_(" [Done]\n"));
01889                 }
01890 
01891             /* The Log window */
01892             if (main_struct->debug == TRUE)
01893                 {
01894                     fprintf(stdout, Q_("log window init interface                "));
01895                 }
01896 
01897             log_window_init_interface(main_struct);
01898 
01899             if (main_struct->debug == TRUE)
01900                 {
01901                     fprintf(stdout, Q_(" [Done]\n"));
01902                 }
01903 
01904             /* Preferences window */
01905             if (main_struct->debug == TRUE)
01906                 {
01907                     fprintf(stdout, Q_("preferences window init interface        "));
01908                 }
01909 
01910             main_pref_window_init_interface(main_struct);
01911 
01912             if (main_struct->debug == TRUE)
01913                 {
01914                     fprintf(stdout, Q_(" [Done]\n"));
01915                 }
01916 
01917 
01918             /* The data interpretor window */
01919             if (main_struct->debug == TRUE)
01920                 {
01921                     fprintf(stdout, Q_("data interpretor init interface          "));
01922                 }
01923 
01924             data_interpretor_init_interface(main_struct);
01925 
01926             if (main_struct->debug == TRUE)
01927                 {
01928                     fprintf(stdout, Q_(" [Done]\n"));
01929                 }
01930 
01931 
01932             /* Goto dialog window */
01933             if (main_struct->debug == TRUE)
01934                 {
01935                     fprintf(stdout, Q_("goto dialog window init interface        "));
01936                 }
01937 
01938             goto_dialog_init_interface(main_struct);
01939 
01940             if (main_struct->debug == TRUE)
01941                 {
01942                     fprintf(stdout, Q_(" [Done]\n"));
01943                 }
01944 
01945 
01946             /* result window */
01947             if (main_struct->debug == TRUE)
01948                 {
01949                     fprintf(stdout, Q_("result window init interface             "));
01950                 }
01951 
01952             result_window_init_interface(main_struct);
01953 
01954             if (main_struct->debug == TRUE)
01955                 {
01956                     fprintf(stdout, Q_(" [Done]\n"));
01957                 }
01958 
01959             /* find window */
01960             if (main_struct->debug == TRUE)
01961                 {
01962                     fprintf(stdout, Q_("find window init interface               "));
01963                 }
01964 
01965             find_window_init_interface(main_struct);
01966 
01967             if (main_struct->debug == TRUE)
01968                 {
01969                     fprintf(stdout, Q_(" [Done]\n"));
01970                 }
01971 
01972             /* find and replace window */
01973             if (main_struct->debug == TRUE)
01974                 {
01975                     fprintf(stdout, Q_("find and replace window init interface   "));
01976                 }
01977 
01978             fr_window_init_interface(main_struct);
01979 
01980             if (main_struct->debug == TRUE)
01981                 {
01982                     fprintf(stdout, Q_(" [Done]\n"));
01983                 }
01984             /* find and replace window */
01985             if (main_struct->debug == TRUE)
01986                 {
01987                     fprintf(stdout, Q_("find data from type window init interface"));
01988                 }
01989 
01990             fdft_window_init_interface(main_struct);
01991 
01992             if (main_struct->debug == TRUE)
01993                 {
01994                     fprintf(stdout, Q_(" [Done]\n"));
01995                 }
01996 
01997             /* preferences file - Setting up preferences */
01998             fprintf(stdout, Q_("Loading heraia preference file"));
01999             fprintf(stdout, Q_("Setting up preferences...\n"));
02000             load_preferences(main_struct, main_struct->prefs);
02001             fprintf(stdout, Q_("[Done]\n"));
02002         }
02003 
02004     return success;
02005 }
02006 
02007 
02008 /**
02009  * @fn void add_text_to_textview(GtkTextView *textview, const char *format, ...)
02010  *  adds a text to a textview
02011  * @param textview : the textview where to add text
02012  * @param format : printf style format
02013  * @param ... : a va_list arguments to fit format (as with printf)
02014  */
02015 void add_text_to_textview(GtkTextView *textview, const char *format, ...)
02016 {
02017     va_list args;
02018     GtkTextBuffer *tb = NULL;
02019     GtkTextIter iEnd;
02020     gchar *display = NULL;
02021     GError *err = NULL;
02022 
02023     va_start(args, format);
02024     display = g_locale_to_utf8(g_strdup_vprintf(format, args), -1, NULL, NULL, &err);
02025     va_end(args);
02026 
02027     tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)));
02028     gtk_text_buffer_get_end_iter(tb, &iEnd);
02029     gtk_text_buffer_insert(tb, &iEnd, display, -1);
02030     g_free(display);
02031 }
02032 
02033 
02034 /**
02035  * @fn kill_text_from_textview(GtkTextView *textview)
02036  *  Kills the text from a textview
02037  * @param textview : the textview to kill the text from
02038  */
02039 void kill_text_from_textview(GtkTextView *textview)
02040 {
02041     GtkTextBuffer *tb = NULL;
02042     GtkTextIter iStart;
02043     GtkTextIter iEnd;
02044 
02045     tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)));
02046     gtk_text_buffer_get_start_iter(tb, &iStart);
02047     gtk_text_buffer_get_end_iter(tb, &iEnd);
02048     gtk_text_buffer_delete (tb, &iStart, &iEnd);
02049 }
02050 
02051 
02052 /**
02053  * @fn GtkWidget *gtk_radio_button_get_active(GSList *group)
02054  *  Try to find the active radio button widget in a group
02055  *  This does not take into account inconsistant states
02056  *  returns the first active radio button otherwise NULL
02057  * @param group : A group of GtkRadioButtons
02058  * @return returns the active widget if any (NULL if none)
02059  */
02060 GtkWidget *gtk_radio_button_get_active(GSList *group)
02061 {
02062     GSList *tmp_slist = group;
02063     GtkToggleButton *toggle_button = NULL;
02064 
02065     while (tmp_slist)
02066         {
02067             toggle_button = tmp_slist->data;
02068 
02069             if (gtk_toggle_button_get_active(toggle_button))
02070                 {
02071                     return GTK_WIDGET(toggle_button);
02072                 }
02073 
02074             tmp_slist = g_slist_next(tmp_slist);
02075         }
02076 
02077     return NULL;
02078 }
02079 
02080 
02081 /**
02082  * @fn GtkWidget *gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_group_member)
02083  * gets the active radio button from a radio group
02084  * @param radio_button : GtkRadioButton to get radio group from
02085  * @returns the active GtkRadioButton within the group from
02086  *          radio_button
02087  **/
02088 GtkWidget *gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_button)
02089 {
02090     if (radio_button != NULL)
02091         {
02092             return gtk_radio_button_get_active(gtk_radio_button_get_group(radio_button));
02093         }
02094     else
02095         {
02096             return NULL;
02097         }
02098 }
02099 
02100 
02101 /**
02102  * Sets the radio button active
02103  * @param radio_button : The GtkRadioButton to be active within it's group
02104  */
02105 void gtk_radio_button_set_active(GtkRadioButton *radio_button)
02106 {
02107     GSList *group = NULL;
02108     GtkToggleButton *toggle_button = NULL;
02109 
02110     group = gtk_radio_button_get_group(radio_button);
02111 
02112     while (group)
02113         {
02114             toggle_button = group->data;
02115 
02116             if (toggle_button == GTK_TOGGLE_BUTTON(radio_button))
02117                 {
02118                    gtk_toggle_button_set_active(toggle_button, TRUE);
02119                 }
02120             else
02121                 {
02122                     gtk_toggle_button_set_active(toggle_button, FALSE);
02123                 }
02124 
02125             group = g_slist_next(group);
02126         }
02127 }
02128 
02129 
02130 /**
02131  * @fn gboolean is_cmi_checked(GtkWidget *check_menu_item)
02132  *  Tells whether a GtkCheckMenuItem is Checked or not
02133  * @param check_menu_item : a GtkCheckMenuItem to verify
02134  * @return returns TRUE if the Check Manu Item is checked, FALSE otherwise
02135  */
02136 gboolean is_cmi_checked(GtkWidget *check_menu_item)
02137 {
02138     return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(check_menu_item));
02139 }
02140 
02141 
02142 /**
02143  * @fn gboolean is_toggle_button_activated(GtkBuilder *main_xml, gchar *check_button)
02144  *  returns the state of a named check button contained
02145  *  in the GtkBuilder XML description
02146  * @param main_xml : a GtkBuilder XML definition
02147  * @param check_button : the name of an existing check_button within the GtkBuilder
02148  *        definition
02149  * @return TRUE if the button is activated / toggled , FALSE otherwise
02150  */
02151 gboolean is_toggle_button_activated(GtkBuilder *main_xml, gchar *check_button)
02152 {
02153     gboolean activated = FALSE;
02154 
02155     if (main_xml != NULL)
02156         {
02157             activated = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(heraia_get_widget(main_xml, check_button)));
02158         }
02159 
02160     return activated;
02161 }
02162 
02163 
02164 /**
02165  *  This is a wrapper to the GtkBuilder xml get widget. It is intended
02166  *  to simplify the developpers lives if they have to choose or
02167  *  propose other means to do the same thing than libglade (say,
02168  *  for example, GtkBuilder ;-)
02169  * @param xml : A GtkBuilder XML definition
02170  * @param widget_name : an existing widget name in the GtkBuilder definition
02171  * @return returns the widget itself if it exists in the definition file (NULL
02172  *         otherwise)
02173  */
02174 GtkWidget *heraia_get_widget(GtkBuilder *xml, gchar *widget_name)
02175 {
02176    /**
02177     * For debug purposes only (very verbose as this function is the main used)
02178     * fprintf(stdout, "Getting Widget named %s\n", widget_name);
02179     */
02180 
02181     if (xml != NULL && widget_name != NULL)
02182         {
02183             return GTK_WIDGET(gtk_builder_get_object(xml, widget_name));
02184         }
02185     else
02186         {
02187             return NULL;
02188         }
02189 }
02190 
02191 
02192 /**
02193  * @fn void destroy_a_single_widget(GtkWidget *widget)
02194  *  Destroys a single widget if it exists
02195  * @param widget : the widget to destroy
02196  */
02197 void destroy_a_single_widget(GtkWidget *widget)
02198 {
02199     if (widget != NULL)
02200         {
02201             gtk_widget_destroy(widget);
02202         }
02203 }
02204 
02205 
02206 /**
02207  * Verify if we can safely close everything
02208  * @param main_struct : main structure
02209  * @return a boolean which is TRUE if unsaved documents still exists and FALSE
02210  *         otherwise
02211  */
02212 static gboolean unsaved_documents(heraia_struct_t *main_struct)
02213 {
02214     doc_t *current_doc = NULL;
02215     gboolean result = FALSE;
02216     guint i = 0;
02217 
02218     if (main_struct != NULL && main_struct->documents != NULL)
02219         {
02220             for(i = 0; i < main_struct->documents->len; i++)
02221                 {
02222                     current_doc =  g_ptr_array_index(main_struct->documents, i);
02223                     result = result | current_doc->modified;
02224                 }
02225 
02226             return result;
02227         }
02228 
02229     return result;
02230 }
02231 
02232 
02233 /**
02234  * Closes all documents and saves preferences if the users wants to close
02235  * the documents.
02236  * @param main_struct : main_struct
02237  * @param question a const gchar * string to be displayed when an unsaved
02238  *        document is found. This should ask the user what to do.
02239  * @return the user anwser if an unsaved document is found and TRUE if not
02240  */
02241 static gboolean close_a_project(heraia_struct_t *main_struct, gchar *question)
02242 {
02243     gboolean unsaved = FALSE;    /**< if there is any unsaved documents */
02244     gboolean quit_heraia = TRUE; /**< By default we want to quit        */
02245     GtkWidget *dialog = NULL;    /**< The dialog box                    */
02246     GtkWidget *parent = NULL;    /**< parent widget for the dialog box  */
02247     gint result = 0;             /**< result from the dialog box        */
02248     doc_t *closing_doc = NULL;   /**< The document to be closed         */
02249 
02250     unsaved = unsaved_documents(main_struct);
02251 
02252     if (unsaved == TRUE)
02253         {
02254             /* Displays a dialog box that let the user choose what to do */
02255             parent = heraia_get_widget(main_struct->xmls->main, "main_window");
02256 
02257             dialog = gtk_message_dialog_new(GTK_WINDOW(parent), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, Q_("Unsaved document(s) remains."));
02258             gtk_message_dialog_format_secondary_markup(GTK_MESSAGE_DIALOG(dialog), "%s", question);
02259 
02260 
02261             result = gtk_dialog_run(GTK_DIALOG(dialog));
02262 
02263             switch (result)
02264                 {
02265                     case GTK_RESPONSE_YES:
02266                         quit_heraia = TRUE;
02267                     break;
02268 
02269                     default:
02270                         quit_heraia = FALSE;
02271                     break;
02272                 }
02273 
02274             gtk_widget_destroy(dialog);
02275         }
02276 
02277     if (quit_heraia == TRUE)
02278         {
02279             /* . Recording window's position       */
02280             record_all_dialog_box_positions(main_struct);
02281 
02282             /* . Saving preferences                */
02283             save_preferences(main_struct, main_struct->prefs);
02284 
02285             /* . Closing the documents             */
02286             while (main_struct->documents->len > 0)
02287                 {
02288                     closing_doc = g_ptr_array_index(main_struct->documents, 0);
02289                     close_one_document(main_struct, closing_doc, 0);
02290                 }
02291             main_struct->current_doc = NULL;
02292 
02293              /* . Updating things in the interface */
02294             refresh_event_handler(parent, main_struct);
02295             update_main_window_name(main_struct);
02296             grey_main_widgets(main_struct->xmls->main, TRUE);
02297 
02298             /* . Destroying preferences structure  */
02299             free_preference_struct(main_struct->prefs);
02300             main_struct->prefs = NULL;
02301         }
02302 
02303     return quit_heraia;
02304 }
02305 
02306 
02307 /**
02308  * @fn void close_heraia(heraia_struct_t *main_struct)
02309  * Before closing heraia we need to do few things
02310  * @param main_struct : main_struct
02311  * @return TRUE if we can safely quit heraia, FALSE otherwise
02312  */
02313 static gboolean close_heraia(heraia_struct_t *main_struct)
02314 {
02315    return close_a_project(main_struct, N_("Do you want to quit without saving ?"));
02316 }
02317 
02318 
02319 /**
02320  * @fn void init_one_cmi_window_state(GtkWidget *dialog_box, GtkWidget *cmi, window_prop_t *dialog_prop)
02321  * init one cmi window based state
02322  * @param dialog_box : the window or dialog box we want to init its state
02323  * @param cmi : corresponding check menu item
02324  * @param dialog_prop : corresponding window properties (should be initialized and not NULL)
02325  */
02326 static void init_one_cmi_window_state(GtkWidget *dialog_box, GtkWidget *cmi, window_prop_t *dialog_prop)
02327 {
02328     gboolean activated = FALSE;
02329 
02330     if (dialog_box != NULL && cmi != NULL && dialog_prop != NULL)
02331         {
02332             activated = dialog_prop->displayed;
02333             gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(cmi), activated);
02334             if (activated == TRUE)
02335                 {
02336                     gtk_window_move(GTK_WINDOW(dialog_box), dialog_prop->x, dialog_prop->y);
02337                     gtk_window_resize(GTK_WINDOW(dialog_box), dialog_prop->width, dialog_prop->height);
02338                     gtk_widget_show_all(dialog_box);
02339                 }
02340         }
02341 }
02342 
02343 
02344 /**
02345  * @fn init_window_states(heraia_struct_t *main_struct)
02346  *  Inits all windows states (positions, displayed, and so on...)
02347  * @param main_struct : main structure
02348  */
02349 void init_window_states(heraia_struct_t *main_struct)
02350 {
02351     GtkWidget *cmi = NULL;
02352     GtkWidget *dialog_box = NULL;
02353 
02354     if (main_struct != NULL && main_struct->xmls != NULL  && main_struct->xmls->main != NULL)
02355         {
02356             if (main_struct->win_prop)
02357                 {
02358                     /* Main window (always the first one) */
02359                     dialog_box = heraia_get_widget(main_struct->xmls->main, "main_window");
02360                     if (main_struct->win_prop->main_dialog->displayed == TRUE)
02361                         {
02362                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->main_dialog->x, main_struct->win_prop->main_dialog->y);
02363                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->main_dialog->width, main_struct->win_prop->main_dialog->height);
02364                             gtk_widget_show(dialog_box);
02365                         }
02366 
02367                     /* Log Window Interface */
02368                     cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw");
02369                     dialog_box = heraia_get_widget(main_struct->xmls->main, "log_window");
02370                     init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->log_box);
02371 
02372                     /* Data Interpretor Interface */
02373                     cmi = heraia_get_widget(main_struct->xmls->main, "DIMenu");
02374                     dialog_box = heraia_get_widget(main_struct->xmls->main, "data_interpretor_window");
02375                     init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->data_interpretor);
02376                     on_DIMenu_activate(cmi, main_struct);
02377 
02378                     /* List Data type Interface */
02379                     /*
02380                      * cmi = heraia_get_widget(main_struct->xmls->main, "ldt_menu");
02381                      * dialog_box = heraia_get_widget(main_struct->xmls->main, "list_data_types_window");
02382                      * init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->ldt);
02383                      */
02384 
02385                     /* Plugin List Interface */
02386                     cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_plugin_list");
02387                     dialog_box = heraia_get_widget(main_struct->xmls->main, "plugin_list_window");
02388                     init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->plugin_list);
02389 
02390                     /* Preferences window */
02391                     dialog_box = heraia_get_widget(main_struct->xmls->main, "main_preferences_window");
02392                     if (main_struct->win_prop->main_pref_window->displayed == TRUE)
02393                         {
02394                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->main_pref_window->x, main_struct->win_prop->main_pref_window->y);
02395                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->main_pref_window->width, main_struct->win_prop->main_pref_window->height);
02396                             gtk_widget_show_all(dialog_box);
02397                         }
02398 
02399                     /* Goto dialog window */
02400                     dialog_box = heraia_get_widget(main_struct->xmls->main, "goto_dialog");
02401                     if (main_struct->win_prop->goto_window->displayed == TRUE && main_struct->current_doc != NULL)
02402                         {
02403                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->goto_window->x, main_struct->win_prop->goto_window->y);
02404                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->goto_window->width, main_struct->win_prop->goto_window->height);
02405                             gtk_widget_show_all(dialog_box);
02406                         }
02407                     else
02408                         {
02409                             /* if the window is not displayed modifies it's properties accordingly */
02410                             main_struct->win_prop->goto_window->displayed = FALSE;
02411                         }
02412 
02413                     /* result window */
02414                     dialog_box = heraia_get_widget(main_struct->xmls->main, "result_window");
02415                     cmi = heraia_get_widget(main_struct->xmls->main, "menu_result");
02416                     if (main_struct->win_prop->result_window->displayed == TRUE && main_struct->current_doc != NULL)
02417                         {
02418                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->result_window->x, main_struct->win_prop->result_window->y);
02419                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->result_window->width, main_struct->win_prop->result_window->height);
02420                             gtk_widget_show_all(dialog_box);
02421                         }
02422                     else
02423                         {
02424                             main_struct->win_prop->result_window->displayed = FALSE;
02425                         }
02426                     init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->result_window);
02427 
02428                     /* find window */
02429                     dialog_box = heraia_get_widget(main_struct->xmls->main, "find_window");
02430                     if (main_struct->win_prop->find_window->displayed == TRUE && main_struct->current_doc != NULL)
02431                         {
02432                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->find_window->x, main_struct->win_prop->find_window->y);
02433                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->find_window->width, main_struct->win_prop->find_window->height);
02434                             gtk_widget_show_all(dialog_box);
02435                         }
02436                     else
02437                         {
02438                             /* if the window is not displayed modifies it's properties accordingly */
02439                             main_struct->win_prop->find_window->displayed = FALSE;
02440                         }
02441 
02442                     /* find and replace window */
02443                     dialog_box = heraia_get_widget(main_struct->xmls->main, "fr_window");
02444                     if (main_struct->win_prop->fr_window->displayed == TRUE && main_struct->current_doc != NULL)
02445                         {
02446                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->fr_window->x, main_struct->win_prop->fr_window->y);
02447                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->fr_window->width, main_struct->win_prop->fr_window->height);
02448                             gtk_widget_show_all(dialog_box);
02449                         }
02450                     else
02451                         {
02452                             /* if the window is not displayed modifies it's properties accordingly */
02453                             main_struct->win_prop->fr_window->displayed = FALSE;
02454                         }
02455 
02456                     /* find data from type window */
02457                     dialog_box = heraia_get_widget(main_struct->xmls->main, "fdft_window");
02458                     if (main_struct->win_prop->fdft_window->displayed == TRUE && main_struct->current_doc != NULL)
02459                         {
02460                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->fdft_window->x, main_struct->win_prop->fdft_window->y);
02461                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->fdft_window->width, main_struct->win_prop->fdft_window->height);
02462                             gtk_widget_show_all(dialog_box);
02463                         }
02464                     else
02465                         {
02466                             /* if the window is not displayed modifies it's properties accordingly */
02467                             main_struct->win_prop->fdft_window->displayed = FALSE;
02468                         }
02469 
02470 
02471                     /* About Box */
02472                     dialog_box = heraia_get_widget(main_struct->xmls->main, "about_dialog");
02473                     if (main_struct->win_prop->about_box->displayed == TRUE)
02474                         {
02475                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->about_box->x, main_struct->win_prop->about_box->y);
02476                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->about_box->width, main_struct->win_prop->about_box->height);
02477                             set_a_propos_properties(dialog_box);
02478                             gtk_widget_show_all(dialog_box);
02479                         }
02480                 }
02481         }
02482 }
02483 
02484 
02485 /**
02486  * Creates an hbox containning a cross button (in order to close the tab) and
02487  * a label (from tab_label).
02488  * Creates a label an a button to add into a tab from main window's notebook
02489  * @param main_struct : main structure
02490  * @param tab_label : a GtkWidget that is the label we want to add to the tab
02491  * @param signal_handler : the signal to connect to when the close button is
02492  *                         clicked.
02493  * @return a newly created GtkWidget which contains the label and a close button
02494  */
02495 GtkWidget *create_tab_close_button(heraia_struct_t *main_struct, GtkWidget *tab_label, void *signal_handler)
02496 {
02497     GtkWidget *hbox = NULL;    /**< used for hbox creation in the tabs */
02498     GtkWidget *button = NULL;  /**< Closing button                     */
02499 
02500     /* Close button in tabs */
02501     hbox = gtk_hbox_new(FALSE, 0);
02502 
02503     button = gtk_button_new_with_label("x");
02504     gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
02505     gtk_widget_set_size_request(button, 18, 17);
02506     gtk_widget_set_tooltip_text(button, Q_("Close button"));
02507     g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(signal_handler), main_struct);
02508 
02509     /* Packing label and button all together in order to display everything in the tab */
02510     gtk_box_pack_start(GTK_BOX(hbox), tab_label, FALSE, FALSE, 0);
02511     gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 2);
02512     gtk_widget_show_all(hbox);
02513 
02514     return hbox;
02515 }
02516 
02517 
02518 /**
02519  * Adds a new tab to the main window in file's notebook
02520  * @param main_struct : main structure
02521  * @param doc : the new document that will be related to the tab
02522  */
02523 void add_new_tab_in_main_window(heraia_struct_t *main_struct, doc_t *doc)
02524 {
02525     GtkWidget *vbox = NULL;       /**< used for vbox creation               */
02526     GtkNotebook *notebook = NULL; /**< file_notebook from heraia.gtkbuilder */
02527     GtkWidget *tab_label = NULL;  /**< tab's label                          */
02528     GtkWidget *menu_label = NULL; /**<menu's label                          */
02529     gint tab_num = -1;            /**< new tab's index                      */
02530     gchar *filename = NULL;
02531     gchar *whole_filename = NULL;
02532     gchar *markup = NULL;         /**< markup text                          */
02533     gchar *menu_markup = NULL;    /**< menu markup text                     */
02534     GtkWidget *hbox = NULL;       /**< used for hbox creation in the tabs   */
02535 
02536     notebook = GTK_NOTEBOOK(heraia_get_widget(main_struct->xmls->main, "file_notebook"));
02537     vbox = gtk_vbox_new(FALSE, 2);
02538     gtk_box_pack_start(GTK_BOX(vbox), doc->hex_widget, TRUE, TRUE, 3);
02539 
02540     /* tab's label and menu label */
02541     tab_label = gtk_label_new(NULL);
02542     menu_label = gtk_label_new(NULL);
02543     whole_filename = doc_t_document_get_filename(doc);
02544 
02545     if (whole_filename != NULL)
02546         {
02547             filename = g_filename_display_basename(whole_filename);
02548             markup = g_markup_printf_escaped("%s", filename);
02549             menu_markup = g_markup_printf_escaped("%s", filename);
02550             gtk_label_set_markup(GTK_LABEL(tab_label), markup);
02551             gtk_label_set_markup(GTK_LABEL(menu_label), menu_markup);
02552             gtk_label_set_justify(GTK_LABEL(menu_label), GTK_JUSTIFY_LEFT);
02553             gtk_widget_set_tooltip_text(tab_label, g_filename_display_name(whole_filename));
02554             g_free(markup);
02555             g_free(menu_markup);
02556         }
02557 
02558     hbox = create_tab_close_button(main_struct, tab_label, on_close_activate);
02559 
02560     gtk_widget_show_all(vbox);
02561     tab_num = gtk_notebook_append_page_menu(notebook, vbox, hbox, menu_label);
02562 
02563     main_struct->current_doc = doc;
02564     gtk_notebook_set_current_page(notebook, tab_num);
02565 }
02566 
02567 
02568 /**
02569  *  To help plugins to deal with widgets, shows or hide a specific widget
02570  * @param widget : the widget to show or hide
02571  * @param show : what to do : TRUE to show the widget, FALSE to hide it
02572  * @param win_prop : window properties.
02573  */
02574 void show_hide_widget(GtkWidget *widget, gboolean show, window_prop_t *win_prop)
02575 {
02576     if (widget != NULL)
02577         {
02578             if (win_prop != NULL)
02579                     {
02580                         if (show)
02581                             {
02582                                 move_and_show_dialog_box(widget, win_prop);
02583                             }
02584                         else
02585                             {
02586                                 record_and_hide_dialog_box(widget, win_prop);
02587                             }
02588                     }
02589                 else
02590                     {
02591                         if (show)
02592                             {
02593                                 gtk_widget_show(widget);
02594                             }
02595                         else
02596                             {
02597                                 gtk_widget_hide(widget);
02598                             }
02599                     }
02600         }
02601 }
Generated on Mon May 2 21:04:49 2011 for Heraia by  doxygen 1.6.3