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