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 /**
00042  * @fn void on_quit_activate(GtkWidget *widget, gpointer data)
00043  *  Quit, file menu
00044  * @param widget : the widget that issued the signal
00045  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00046  */
00047 void on_quit_activate(GtkWidget *widget, gpointer data)
00048 {
00049     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00050     gboolean quit_heraia = FALSE;
00051 
00052     quit_heraia = close_heraia(main_struct);
00053 
00054     if (quit_heraia == TRUE)
00055         {
00056             gtk_main_quit();
00057         }
00058 }
00059 
00060 
00061 /**
00062  * @fn void on_new_activate(GtkWidget *widget, gpointer data)
00063  *  New, file menu
00064  * @param widget : the widget that issued the signal
00065  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00066  */
00067 void on_new_activate(GtkWidget *widget, gpointer data)
00068 {
00069     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00070 
00071     log_message(main_struct, G_LOG_LEVEL_WARNING, Q_("Not implemented Yet (Please contribute !)"));
00072 }
00073 
00074 
00075 /**
00076  * @fn void on_preferences_activate(GtkWidget *widget, gpointer data)
00077  *  Preferences, file menu :
00078  *  Displays the preference window (as a modal window)
00079  * @param widget : the widget that issued the signal
00080  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00081  */
00082 void on_preferences_activate(GtkWidget *widget, gpointer data)
00083 {
00084     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00085     GtkWidget *pref_window = NULL;
00086 
00087     pref_window = heraia_get_widget(main_struct->xmls->main, "main_preferences_window");
00088 
00089     if (pref_window != NULL)
00090         {
00091             move_and_show_dialog_box(pref_window, main_struct->win_prop->main_pref_window);
00092         }
00093 
00094 }
00095 
00096 
00097 /**
00098  * @fn void set_a_propos_properties(GtkWidget *about_dialog)
00099  * Sets name and version in the dialog box
00100  * @param about_dialog the widget that contain all the about box
00101  */
00102 static void set_a_propos_properties(GtkWidget *about_dialog)
00103 {
00104 
00105     if (about_dialog != NULL)
00106         {
00107             if (GTK_MINOR_VERSION >= 12)
00108                 {
00109                     gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(about_dialog), PACKAGE_NAME);
00110                 }
00111             if (GTK_MINOR_VERSION >= 6)
00112                 {
00113                     gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about_dialog), PACKAGE_VERSION);
00114                 }
00115         }
00116 }
00117 
00118 
00119 /**
00120  * @fn void a_propos_activate(GtkWidget *widget, gpointer data)
00121  *  Shows apropos's dialog box
00122  * @param widget : the widget that issued the signal
00123  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00124  */
00125 void a_propos_activate(GtkWidget *widget, gpointer data)
00126 {
00127     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00128     GtkWidget *about_dialog = NULL;
00129 
00130     about_dialog = heraia_get_widget(main_struct->xmls->main, "about_dialog");
00131 
00132     if (about_dialog != NULL)
00133         {
00134             set_a_propos_properties(about_dialog);
00135             move_and_show_dialog_box(about_dialog, main_struct->win_prop->about_box);
00136         }
00137 }
00138 
00139 
00140 /**
00141  * @fn void move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00142  *  Move the dialog box to the wanted position, shows it and says it in the displayed prop
00143  * @param dialog_box : the dialog box we want to move and show
00144  * @param dialog_prop : window_prop_t properties structure corresponding to the dialog box
00145  */
00146 void move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00147 {
00148     if (dialog_prop != NULL)
00149         {
00150 
00151             if (dialog_prop->displayed == FALSE)
00152                 {
00153                     if (dialog_prop->x > 0 && dialog_prop->y > 0)
00154                         {
00155                             gtk_window_move(GTK_WINDOW(dialog_box), dialog_prop->x, dialog_prop->y);
00156                         }
00157 
00158                     if (dialog_prop->width > 0 && dialog_prop->height > 0)
00159                         {
00160                             gtk_window_resize(GTK_WINDOW(dialog_box), dialog_prop->width, dialog_prop->height);
00161                         }
00162 
00163                     gtk_widget_show_all(dialog_box);
00164                     dialog_prop->displayed = TRUE;
00165                 }
00166         }
00167 }
00168 
00169 
00170 /**
00171  * @fn void record_dialog_box_position(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00172  * Records one dialog position
00173  * @param dialog_box : a dialog box from which we want to record the position
00174  * @param[in,out] dialog_prop : window_prop_t properties structure corresponding to the dialog box
00175  */
00176 void record_dialog_box_position(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00177 {
00178     gint x = 0;
00179     gint y = 0;
00180     gint width = WPT_DEFAULT_WIDTH;
00181     gint height = WPT_DEFAULT_HEIGHT;
00182 
00183     if (dialog_prop != NULL && dialog_prop->displayed == TRUE)
00184         {
00185             if (dialog_box != NULL)
00186                 {
00187                     gtk_window_get_position(GTK_WINDOW(dialog_box), &x, &y);
00188                     gtk_window_get_size(GTK_WINDOW(dialog_box), &width, &height);
00189                     dialog_prop->x = x;
00190                     dialog_prop->y = y;
00191                     dialog_prop->width = width;
00192                     dialog_prop->height = height;
00193                 }
00194         }
00195 }
00196 
00197 
00198 /**
00199  * @fn void record_all_dialog_box_positions(heraia_struct_t *main_struct)
00200  * Records all the positions of the displayed windows
00201  * @param[in,out] main_struct : main structure
00202  */
00203 void record_all_dialog_box_positions(heraia_struct_t *main_struct)
00204 {
00205     GtkWidget *dialog_box = NULL;
00206 
00207     if (main_struct != NULL &&
00208         main_struct->xmls != NULL &&
00209         main_struct->xmls->main != NULL &&
00210         main_struct->win_prop != NULL &&
00211         main_struct->current_DW != NULL)
00212         {
00213             /* data interpretor */
00214             dialog_box = main_struct->current_DW->diw;
00215             record_dialog_box_position(dialog_box, main_struct->win_prop->data_interpretor);
00216 
00217             /* About box */
00218             dialog_box = heraia_get_widget (main_struct->xmls->main, "about_dialog");
00219             record_dialog_box_position(dialog_box, main_struct->win_prop->about_box);
00220 
00221             /* Log window */
00222             dialog_box = heraia_get_widget (main_struct->xmls->main, "log_window");
00223             record_dialog_box_position(dialog_box, main_struct->win_prop->log_box);
00224 
00225             /* main_dialog */
00226             dialog_box = heraia_get_widget (main_struct->xmls->main, "main_window");
00227             record_dialog_box_position(dialog_box, main_struct->win_prop->main_dialog);
00228 
00229             /* plugin_list */
00230             dialog_box = heraia_get_widget (main_struct->xmls->main, "plugin_list_window");
00231             record_dialog_box_position(dialog_box, main_struct->win_prop->plugin_list);
00232 
00233             /* list data types */
00234             dialog_box = heraia_get_widget (main_struct->xmls->main, "list_data_types_window");
00235             record_dialog_box_position(dialog_box, main_struct->win_prop->ldt);
00236 
00237             /* main_preferences */
00238             dialog_box = heraia_get_widget (main_struct->xmls->main, "main_preferences_window");
00239             record_dialog_box_position(dialog_box, main_struct->win_prop->main_pref_window);
00240         }
00241 }
00242 
00243 
00244 /**
00245  * @fn void record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00246  *  Record position and hide a dialog box
00247  * @param dialog_box : the dialog box we want to record its position and then hide
00248  * @param dialog_prop : window_prop_t properties structure corresponding to the dialog box
00249  */
00250 void record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
00251 {
00252 
00253     if (dialog_prop->displayed == TRUE)
00254         {
00255             record_dialog_box_position(dialog_box, dialog_prop);
00256 
00257             gtk_widget_hide(dialog_box);
00258             dialog_prop->displayed = FALSE;
00259         }
00260 }
00261 
00262 
00263 /**
00264  * @fn static void record_and_hide_about_box(heraia_struct_t *main_struct)
00265  *  Record position and hide about dialog box
00266  * @param [in,out] main_struct : main structure
00267  */
00268 static void record_and_hide_about_box(heraia_struct_t *main_struct)
00269 {
00270     GtkWidget *about_dialog = NULL;
00271 
00272     about_dialog = heraia_get_widget(main_struct->xmls->main, "about_dialog");
00273 
00274     if (about_dialog != NULL)
00275         {
00276             record_and_hide_dialog_box(about_dialog, main_struct->win_prop->about_box);
00277         }
00278 }
00279 
00280 
00281 /**
00282  * @fn void a_propos_response(GtkWidget *widget, gint response, gpointer data)
00283  *  To close the A propos dialog box (with the "close" button)
00284  * @param widget : calling widget (may be NULL as we don't use this)
00285  * @param response : may be whatever you want as we neither use this !
00286  * @param data : MUST be heraia_struct_t *main_struct main structure
00287  */
00288 static void a_propos_response(GtkWidget *widget, gint response, gpointer data)
00289 {
00290     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00291     record_and_hide_about_box(main_struct);
00292 }
00293 
00294 
00295 /**
00296  * @fn void a_propos_close(GtkWidget *widget, gpointer data)
00297  *  To close the A propos dialog box
00298  * @param widget : calling widget (may be NULL as we don't use this)
00299  * @param data : MUST be heraia_struct_t *main_struct main structure
00300  */
00301 static void a_propos_close(GtkWidget *widget, gpointer data)
00302 {
00303     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00304     record_and_hide_about_box(main_struct);
00305 }
00306 
00307 
00308 /**
00309  * @fn gboolean a_propos_delete(GtkWidget *widget, GdkEvent  *event, gpointer data)
00310  *  To close the A propos dialog box
00311  * @param widget : calling widget (may be NULL as we don't use this)
00312  * @param event : event associated (may be NULL as we don't use this)
00313  * @param data : MUST be heraia_struct_t *main_struct main structure
00314  * @return returns TRUE in order to allow other functions to do something with
00315  *         that event.
00316  */
00317 static gboolean a_propos_delete(GtkWidget *widget, GdkEvent  *event, gpointer data)
00318 {
00319     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00320     record_and_hide_about_box(main_struct);
00321 
00322     return TRUE;
00323 }
00324 
00325 
00326 /**
00327  *  Undo, edit menu
00328  * @param widget : the widget that issued the signal
00329  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00330  */
00331 void on_undo_activate(GtkWidget *widget, gpointer data)
00332 {
00333     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00334     GtkBuilder *xml = NULL;
00335     gboolean result = FALSE;
00336 
00337     if (main_struct != NULL && main_struct->current_doc != NULL && main_struct->xmls->main != NULL)
00338         {
00339             result = hex_document_undo(main_struct->current_doc->hex_doc);
00340 
00341             xml = main_struct->xmls->main;
00342 
00343             if (result == TRUE)
00344                 {
00345                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), TRUE);
00346                 }
00347 
00348             if (main_struct->current_doc->hex_doc->undo_top == NULL)
00349                 {   /* No more undos are possible. The document is as the origin ! */
00350                     set_notebook_tab_label_color(main_struct, FALSE);
00351                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), FALSE);
00352                     main_struct->current_doc->modified = FALSE;
00353                 }
00354             else
00355                 {
00356                     set_notebook_tab_label_color(main_struct, TRUE);
00357                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), TRUE);
00358                 }
00359 
00360         }
00361 
00362 }
00363 
00364 
00365 /**
00366  *  Redo, edit menu
00367  * @param widget : the widget that issued the signal
00368  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00369  */
00370 void on_redo_activate(GtkWidget *widget, gpointer data)
00371 {
00372     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00373     GtkBuilder *xml = NULL;
00374     gboolean result = FALSE;
00375 
00376     if (main_struct != NULL && main_struct->current_doc != NULL && main_struct->xmls->main != NULL)
00377         {
00378             result = hex_document_redo(main_struct->current_doc->hex_doc);
00379 
00380             xml = main_struct->xmls->main;
00381 
00382             if (result == TRUE)
00383                 {
00384                     set_notebook_tab_label_color(main_struct, TRUE);
00385                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_undo"), TRUE);
00386                     main_struct->current_doc->modified = TRUE;
00387                 }
00388 
00389             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)
00390                 {
00391                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), FALSE);
00392                 }
00393             else
00394                 {
00395                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_redo"), TRUE);
00396                 }
00397         }
00398 }
00399 
00400 
00401 /**
00402  *  Delete, edit menu
00403  * @warning Not yet implemented
00404  * @todo Write a usefull function here :)
00405  * @param widget : the widget that issued the signal
00406  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00407  */
00408 void on_delete_activate(GtkWidget *widget, gpointer data)
00409 {
00410     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00411 
00412     if (main_struct != NULL && main_struct->current_doc != NULL)
00413         {
00414             gtk_hex_delete_selection(main_struct->current_doc->hex_widget);
00415             refresh_event_handler(widget, data);
00416         }
00417 }
00418 
00419 
00420 /**
00421  *  Cut, edit menu
00422  * @warning Not yet implemented
00423  * @todo Write a usefull function here :)
00424  * @param widget : the widget that issued the signal
00425  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00426  */
00427 void on_cut_activate(GtkWidget *widget, gpointer data)
00428 {
00429     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00430 
00431     if (main_struct != NULL && main_struct->current_doc != NULL)
00432         {
00433             gtk_hex_cut_to_clipboard(main_struct->current_doc->hex_widget);
00434             refresh_event_handler(widget, data);
00435         }
00436 }
00437 
00438 
00439 /**
00440  *  Copy, edit menu
00441  * @warning Not yet implemented
00442  * @todo Write a usefull function here :)
00443  * @param widget : the widget that issued the signal
00444  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00445  */
00446 void on_copy_activate(GtkWidget *widget, gpointer data)
00447 {
00448     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00449 
00450     if (main_struct != NULL && main_struct->current_doc != NULL)
00451         {
00452             gtk_hex_copy_to_clipboard(main_struct->current_doc->hex_widget);
00453         }
00454 }
00455 
00456 
00457 /**
00458  *  Paste, edit menu
00459  * @warning Not yet implemented
00460  * @todo Write a usefull function here :)
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_paste_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_paste_from_clipboard(main_struct->current_doc->hex_widget);
00471             refresh_event_handler(widget, data);
00472         }
00473 }
00474 
00475 
00476 /**
00477  *  This function is refreshing the labels on the main
00478  *  window in order to reflect cursor position, selected
00479  *  positions and total selected size.
00480  *  It is also used to refresh the file label on the tab.
00481  * @param main_struct : main structure
00482  */
00483 void refresh_file_labels(heraia_struct_t *main_struct)
00484 {
00485     GtkWidget *position_label = NULL;
00486     GtkWidget *file_size_label = NULL;
00487     GtkWidget *file_sel_label = NULL;
00488     GtkWidget *file_sel_size_label = NULL;
00489     guint64 position = 0;
00490     guint64 file_size = 0;
00491     selection_t *sel = NULL;
00492     gchar *position_text = NULL;
00493     gchar *file_size_text = NULL;
00494     gchar *file_sel_text = NULL;
00495     gchar *file_sel_size_text = NULL;
00496 
00497     if (main_struct != NULL)
00498         {
00499             position_label = heraia_get_widget(main_struct->xmls->main, "file_position_label");
00500             file_size_label = heraia_get_widget(main_struct->xmls->main, "file_size_label");
00501             file_sel_label = heraia_get_widget(main_struct->xmls->main, "file_selection_label");
00502             file_sel_size_label = heraia_get_widget(main_struct->xmls->main, "file_selection_size_label");
00503 
00504             if (main_struct->current_doc != NULL && main_struct->current_doc->hex_widget != NULL)
00505                 {
00506                     position = ghex_get_cursor_position(main_struct->current_doc->hex_widget);
00507                     file_size = ghex_file_size((Heraia_Hex *) main_struct->current_doc->hex_widget);
00508                     sel = ghex_get_selection(main_struct->current_doc->hex_widget);
00509 
00510                     /* position begins at 0 and this is not really human readable */
00511                     /* it's more confusing than anything so we do + 1             */
00512                     /* To translators : do not translate <small> and such         */
00513                     if (is_toggle_button_activated(main_struct->xmls->main, "mp_thousand_bt") == TRUE)
00514                         {
00515                             position_text = g_strdup_printf("<small>%'lu</small>", position + 1);
00516                             file_size_text = g_strdup_printf("<small>%'lu</small>", file_size);
00517                             file_sel_text = g_strdup_printf("<small>%'lu -> %'lu</small>", sel->start + 1, sel->end + 1);
00518                             file_sel_size_text = g_strdup_printf("<small>%'li</small>", (sel->end - sel->start) + 1);
00519                         }
00520                     else
00521                         {
00522                             position_text = g_strdup_printf("<small>%lu</small>", position + 1);
00523                             file_size_text = g_strdup_printf("<small>%lu</small>", file_size);
00524                             file_sel_text = g_strdup_printf("<small>%lu - %lu</small>", sel->start + 1, sel->end + 1);
00525                             file_sel_size_text = g_strdup_printf("<small>%li</small>", (sel->end - sel->start) + 1);
00526                         }
00527 
00528                     gtk_label_set_markup(GTK_LABEL(position_label), position_text);
00529                     gtk_label_set_markup(GTK_LABEL(file_size_label), file_size_text);
00530                     gtk_label_set_markup(GTK_LABEL(file_sel_label), file_sel_text);
00531                     gtk_label_set_markup(GTK_LABEL(file_sel_size_label), file_sel_size_text);
00532 
00533                     g_free(position_text);
00534                     g_free(file_size_text);
00535                     g_free(file_sel_text);
00536                     g_free(file_sel_size_text);
00537                     g_free(sel);
00538 
00539                     /* refreshing the tab filename itself if necessary only ! */
00540                     if (main_struct->current_doc->modified != main_struct->current_doc->hex_doc->changed)
00541                         {
00542                             main_struct->current_doc->modified = main_struct->current_doc->hex_doc->changed;
00543                             set_notebook_tab_label_color(main_struct, main_struct->current_doc->hex_doc->changed);
00544 
00545                             /* If the document changes, then when might undo things ... */
00546                             gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_undo"), TRUE);
00547 
00548                         }
00549 
00550                 }
00551             else
00552                 {
00553                     gtk_label_set_text(GTK_LABEL(position_label), "");
00554                     gtk_label_set_text(GTK_LABEL(file_size_label), "");
00555                     gtk_label_set_text(GTK_LABEL(file_sel_label), "");
00556                     gtk_label_set_text(GTK_LABEL(file_sel_size_label), "");
00557                 }
00558         }
00559 }
00560 
00561 
00562 /**
00563  *  This function is here to ensure that everything will be
00564  *  refreshed upon a signal event.
00565  * @warning This function is not thread safe (do not use in a thread)
00566  * @todo try to put some mutexes on main_struct->event to make this
00567  *       thread safe some way
00568  * @param widget : the widget that issued the signal
00569  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00570  */
00571 void refresh_event_handler(GtkWidget *widget, gpointer data)
00572 {
00573     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00574 
00575     if (main_struct != NULL)
00576         {
00577             /* Beware, this mechanism is not thread safe ! */
00578             if (main_struct->event == HERAIA_REFRESH_NOTHING)
00579                 {
00580                     main_struct->event = HERAIA_REFRESH_CURSOR_MOVE;
00581                 }
00582 
00583             refresh_data_interpretor_window(widget, main_struct);
00584             refresh_all_plugins(main_struct);
00585             refresh_file_labels(main_struct);
00586 
00587             main_struct->event = HERAIA_REFRESH_NOTHING;
00588         }
00589 }
00590 
00591 
00592 /**
00593  *  This handles the menuitem "Ouvrir" to open a file
00594  * @warning This function is not thread safe (do not use in a thread)
00595  * @todo try to put some mutexes on main_struct->event to make this
00596  *       thread safe some way
00597  * @param widget : the widget that issued the signal
00598  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00599  */
00600 void on_open_activate(GtkWidget *widget, gpointer data)
00601 {
00602     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00603     GSList *list = NULL;
00604     GSList *head = NULL;
00605     gboolean success = FALSE;
00606 
00607     list = select_file_to_load(main_struct);
00608 
00609     if (list != NULL)
00610         {
00611             head = list;
00612             while (list != NULL)
00613                 {
00614                     success = load_file_to_analyse(main_struct, list->data);
00615                     g_free(list->data);
00616                     list = g_slist_next(list);
00617                 }
00618 
00619             g_slist_free(head);
00620 
00621             if (success == TRUE && main_struct->current_doc != NULL)
00622                  {
00623                     /* Not thread safe here ? */
00624                     main_struct->event = HERAIA_REFRESH_NEW_FILE;
00625                     refresh_event_handler(main_struct->current_doc->hex_widget, main_struct);
00626                  }
00627         }
00628 }
00629 
00630 
00631 /**
00632  * @fn void on_save_activate(GtkWidget *widget, gpointer data)
00633  *  Here we attemp to save the edited file
00634  *  @todo be more accurate on error (error type, message and filename) returns
00635  *        we should return something at least ...
00636  * @param widget : the widget that issued the signal
00637  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00638  */
00639 void on_save_activate(GtkWidget *widget, gpointer data)
00640 {
00641     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00642     HERAIA_ERROR erreur = HERAIA_NOERR;
00643     gchar *filename = NULL;
00644 
00645     if (main_struct != NULL && main_struct->current_doc != NULL)
00646         {
00647             erreur = heraia_hex_document_save(main_struct->current_doc);
00648 
00649             if (erreur != HERAIA_NOERR)
00650                 {
00651                     filename = doc_t_document_get_filename(main_struct->current_doc);
00652                     log_message(main_struct, G_LOG_LEVEL_ERROR, Q_("Error while saving file %s !"), filename);
00653                 }
00654             else
00655                 {
00656                     set_notebook_tab_label_color(main_struct, FALSE);
00657                     main_struct->current_doc->modified = FALSE; /* document has just been saved (thus it is not modified !) */
00658                 }
00659         }
00660 }
00661 
00662 
00663 /**
00664  * @fn void on_save_as_activate(GtkWidget *widget, gpointer data)
00665  *  This handle the save_as menu entry (here the filename changes)
00666  * @param widget : the widget that issued the signal
00667  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00668  */
00669 void on_save_as_activate(GtkWidget *widget, gpointer data)
00670 {
00671     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00672     HERAIA_ERROR erreur = HERAIA_NOERR;
00673     gchar *filename = NULL;  /**< Auto malloc'ed, do not free */
00674 
00675     if (main_struct != NULL && main_struct->current_doc != NULL)
00676         {
00677             filename = select_a_file_to_save(main_struct);
00678 
00679             if (filename != NULL)
00680                 {
00681                     erreur = heraia_hex_document_save_as(main_struct->current_doc, filename);
00682                 }
00683             else
00684                 {
00685                     erreur = HERAIA_CANCELLED;
00686                 }
00687 
00688             if (erreur != HERAIA_NOERR)
00689                 {
00690                     if (erreur == HERAIA_CANCELLED)
00691                         {
00692                             log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Saving file as... : operation cancelled."));
00693                         }
00694                     else
00695                         {
00696                             log_message(main_struct, G_LOG_LEVEL_ERROR, Q_("Error while saving file as %s"), doc_t_document_get_filename(main_struct->current_doc));
00697                         }
00698                 }
00699             else
00700                 {
00701                     /* updating the window name and tab's name */
00702                     update_main_window_name(main_struct);
00703                     set_notebook_tab_name(main_struct);
00704                     main_struct->current_doc->modified = FALSE; /* document has just been saved (thus it is not modified !) */
00705                     log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("File %s saved and now edited."), doc_t_document_get_filename(main_struct->current_doc));
00706                 }
00707         }
00708 }
00709 
00710 
00711 /**
00712  * @fn void on_DIMenu_activate(GtkWidget *widget, gpointer data)
00713  *  This handles the menuitem "Data Interpretor" that
00714  *  shows or hides the data interpretor window
00715  * @param widget : the widget that issued the signal
00716  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00717  */
00718 void on_DIMenu_activate(GtkWidget *widget, gpointer data)
00719 {
00720 
00721     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00722     data_window_t *dw = NULL;      /**< data_window structure for data interpretor */
00723     GtkNotebook *notebook = NULL;  /**< data interpretor's notebook                */
00724 
00725     if (main_struct != NULL)
00726         {
00727             dw = main_struct->current_DW;
00728 
00729             if (dw != NULL)
00730                 {
00731                     if (dw->diw == NULL)
00732                         {
00733                             dw->diw = heraia_get_widget(main_struct->xmls->main, "data_interpretor_window");
00734                         }
00735 
00736                     if (dw->diw != NULL)
00737                         {
00738                             notebook = GTK_NOTEBOOK(heraia_get_widget(main_struct->xmls->main, "diw_notebook"));
00739 
00740                             if (main_struct->win_prop->data_interpretor->displayed == FALSE)
00741                                 {
00742                                     /* Setting the first page of the notebook as default (Numbers) */
00743                                     gtk_notebook_set_current_page(notebook, dw->tab_displayed);
00744 
00745                                     /* moving to the right position */
00746                                     move_and_show_dialog_box(dw->diw, main_struct->win_prop->data_interpretor);
00747 
00748                                     refresh_data_interpretor_window(widget, data);
00749                                 }
00750                             else
00751                                 {
00752                                     /* recording some prefs from the dialog : position + opened tab */
00753                                     dw->tab_displayed = gtk_notebook_get_current_page(notebook);
00754                                     record_and_hide_dialog_box(dw->diw, main_struct->win_prop->data_interpretor);
00755                                 }
00756                         }
00757                 }
00758         }
00759 }
00760 
00761 
00762 /**
00763  * Called when tests submenu is activated
00764  * @param widget : the widget that issued the signal
00765  * @param data : user data MUST be heraia_struct_t *main_struct main structure
00766  */
00767 void on_tests_menu_activate(GtkWidget *widget, gpointer data)
00768 {
00769     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00770     gboolean result = FALSE;
00771 
00772     if (main_struct != NULL)
00773         {
00774             result = tests_ui(main_struct);
00775 
00776             if (result == TRUE)
00777                 {
00778                     log_message(main_struct, G_LOG_LEVEL_INFO, Q_("All tests went Ok."));
00779                 }
00780             else
00781                 {
00782                     log_message(main_struct, G_LOG_LEVEL_WARNING, Q_("Some tests failed."));
00783                 }
00784         }
00785 }
00786 
00787 
00788 /**
00789  * @fn delete_main_struct_event(GtkWidget *widget, GdkEvent  *event, gpointer data)
00790  *  When the user destroys or delete the main window
00791  * @param widget : calling widget
00792  * @param event : event associated (may be NULL as we don't use this here)
00793  * @param data : MUST be heraia_struct_t *main_struct main structure
00794  */
00795 gboolean delete_main_struct_event(GtkWidget *widget, GdkEvent  *event, gpointer data)
00796 {
00797 
00798     on_quit_activate(widget, data);
00799 
00800     /* If we are leaving heraia, we are not supposed to be here ! */
00801     return TRUE;
00802 }
00803 
00804 
00805 /**
00806  * @fn gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data)
00807  *  call back function for the data interpretor window destruction
00808  * @param widget : calling widget (may be NULL as we don't use this here)
00809  * @param event : event associated (may be NULL as we don't use this here)
00810  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
00811  */
00812 gboolean delete_dt_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data)
00813 {
00814     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00815 
00816     g_signal_emit_by_name(heraia_get_widget(main_struct->xmls->main, "DIMenu"), "activate");
00817 
00818     return TRUE;
00819 }
00820 
00821 
00822 /**
00823  * @fn void destroy_dt_window(GtkWidget *widget, GdkEvent  *event, gpointer data)
00824  *  call back function for the data interpretor window destruction
00825  * @param widget : calling widget (may be NULL as we don't use this here)
00826  * @param event : event associated (may be NULL as we don't use this here)
00827  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
00828  */
00829 void destroy_dt_window(GtkWidget *widget, GdkEvent  *event, gpointer data)
00830 {
00831     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00832 
00833     g_signal_emit_by_name(heraia_get_widget(main_struct->xmls->main, "DIMenu"), "activate");
00834 }
00835 
00836 
00837 /**
00838  * What to do when a change occurs in tabs (user selected a particular
00839  * tab)
00840  * @param notebook : the widget that issued this signal
00841  * @param page : the new current page
00842  * @param tab_num : index of this page
00843  * @param data : MUST be heraia_struct_t *main_struct !
00844  */
00845 gboolean file_notebook_tab_changed(GtkNotebook *notebook, GtkNotebookPage *page, gint tab_num, gpointer data)
00846 {
00847     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00848 
00849     if (main_struct != NULL)
00850         {
00851             if (tab_num >= 0 && tab_num <= main_struct->documents->len)
00852                 {
00853                     /* Current document is now from the selected tab */
00854                     main_struct->current_doc = g_ptr_array_index(main_struct->documents, tab_num);
00855 
00856                     /* Changing main window's name */
00857                     update_main_window_name(main_struct);
00858 
00859                     /* Refreshing the view */
00860                     main_struct->event = HERAIA_REFRESH_TAB_CHANGED;
00861                     refresh_event_handler(GTK_WIDGET(notebook), main_struct);
00862                     main_struct->event = HERAIA_REFRESH_NOTHING;
00863                 }
00864 
00865         }
00866 
00867     return TRUE;
00868 }
00869 
00870 /* End of call back functions that handle the data interpretor window */
00871 
00872 
00873 /**
00874  * @fn static gchar *make_absolute_path(gchar *filename)
00875  *  Returns an absolute path to the filename
00876  *  the string should be freed when no longer needed
00877  *  very UGLy !
00878  * @todo do something without any system calls !!!
00879  * @param filename : relative notation filename from which to extract an
00880  *        absolute path
00881  * @return returns a string with the absolute path which should be freed when
00882  *         no longer needed
00883  */
00884 static gchar *make_absolute_path(gchar *filename)
00885 {
00886     gchar *current_dir = NULL;
00887     gchar *new_dir = NULL;
00888 
00889     if (g_path_is_absolute(filename) == TRUE)
00890         {
00891             /* if the filename is already in an absolute format */
00892             return  g_path_get_dirname(filename);
00893         }
00894     else
00895         {
00896             current_dir = g_get_current_dir();
00897             new_dir = g_path_get_dirname(filename);
00898 
00899             if (g_chdir(new_dir) == 0)
00900                 {
00901                     g_free(new_dir);
00902                     new_dir = g_get_current_dir();
00903                     g_chdir(current_dir);
00904                     g_free(current_dir);
00905 
00906                     return new_dir;
00907                 }
00908             else
00909                 {
00910                     g_free(current_dir);
00911 
00912                     return NULL;
00913                 }
00914         }
00915 }
00916 
00917 
00918 /**
00919  *  Sets the working directory for the file chooser to the directory of the
00920  *  filename (even if filename is a relative filename such as ../docs/test_file)
00921  * @param file_chooser : An initialized GtkFileChooser
00922  * @param filename : a filename (one previously openned)
00923  */
00924 void set_the_working_directory(GtkFileChooser *file_chooser, gchar *filename)
00925 {
00926     gchar *dirname = NULL;    /**< directory where we want to be, at first, in the file chooser */
00927 
00928     dirname = make_absolute_path(filename);
00929 
00930     if (dirname != NULL)
00931         {
00932             gtk_file_chooser_set_current_folder(file_chooser, dirname);
00933             g_free(dirname);
00934         }
00935 }
00936 
00937 
00938 /**
00939  *  This function does open a file selector dialog box and returns the selected
00940  *  filename.
00941  * @param main_struct : main structure
00942  * @return returns a list of filenames to be loaded (if any)
00943  */
00944 GSList *select_file_to_load(heraia_struct_t *main_struct)
00945 {
00946     GtkWidget *parent = NULL; /**< A parent window (we use main_struct)            */
00947     GtkFileChooser *file_chooser = NULL;
00948     GSList *list = NULL;   /**< list of selected (if any) filenames to be openned  */
00949 
00950     parent = heraia_get_widget(main_struct->xmls->main, "main_window");
00951 
00952     file_chooser = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(Q_("Select a file to analyse"),
00953                                                                 GTK_WINDOW(parent),
00954                                                                 GTK_FILE_CHOOSER_ACTION_OPEN,
00955                                                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00956                                                                 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
00957                                                                 NULL));
00958 
00959     /**
00960      *  for the moment we do not want to retrieve multiples selections
00961      *  but this could be a valuable thing in the future
00962      */
00963     gtk_window_set_modal(GTK_WINDOW(file_chooser), TRUE);
00964     gtk_file_chooser_set_select_multiple(file_chooser, TRUE);
00965 
00966     /**
00967      *  We want the file selection path to be the one of the previous
00968      *  openned file if any !
00969      */
00970     if (doc_t_document_get_filename(main_struct->current_doc) != NULL)
00971        {
00972             set_the_working_directory(file_chooser, doc_t_document_get_filename(main_struct->current_doc));
00973        }
00974 
00975     switch (gtk_dialog_run(GTK_DIALOG(file_chooser)))
00976         {
00977             case GTK_RESPONSE_OK:
00978 
00979                 list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(file_chooser));
00980                 gtk_widget_destroy(GTK_WIDGET(file_chooser));
00981 
00982                 return list;
00983              break;
00984 
00985             case GTK_RESPONSE_CANCEL:
00986             default:
00987                 gtk_widget_destroy(GTK_WIDGET(file_chooser));
00988 
00989                 return NULL;
00990              break;
00991         }
00992 }
00993 
00994 
00995 /**
00996  * @fn gchar *select_a_file_to_save(heraia_struct_t *main_struct)
00997  *  This function opens a dialog box that allow one to choose a
00998  *  file name to the file which is about to be saved
00999  * @param main_struct : main structure
01000  * @return returns complete filename (path and filename)
01001  */
01002 gchar *select_a_file_to_save(heraia_struct_t *main_struct)
01003 {
01004     GtkWidget *parent = NULL;     /**< A parent window (we use main_struct) */
01005     GtkFileChooser *fcd = NULL;
01006     gchar *filename = NULL;
01007 
01008     parent = heraia_get_widget(main_struct->xmls->main, "main_window");
01009 
01010     /* Selection a name to the file to save */
01011     fcd = GTK_FILE_CHOOSER(gtk_file_chooser_dialog_new(Q_("Save As..."),
01012                                                        GTK_WINDOW(parent),
01013                                                        GTK_FILE_CHOOSER_ACTION_SAVE,
01014                                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
01015                                                        GTK_STOCK_SAVE, GTK_RESPONSE_OK,
01016                                                        NULL));
01017 
01018     /* window properties : modal, without multi-selection and with confirmation */
01019     gtk_window_set_modal(GTK_WINDOW(fcd), TRUE);
01020     gtk_file_chooser_set_select_multiple(fcd, FALSE);
01021     gtk_file_chooser_set_do_overwrite_confirmation(fcd, TRUE);
01022 
01023     /* we do want to have the file's directory where to save the new file */
01024     if (doc_t_document_get_filename(main_struct->current_doc) != NULL)
01025        {
01026             set_the_working_directory(fcd, doc_t_document_get_filename(main_struct->current_doc));
01027        }
01028 
01029     switch(gtk_dialog_run(GTK_DIALOG(fcd)))
01030         {
01031             case GTK_RESPONSE_OK:
01032                 /* retrieving the filename */
01033                 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fcd));
01034                 break;
01035             default:
01036                 filename = NULL;
01037                 break;
01038         }
01039 
01040     gtk_widget_destroy(GTK_WIDGET(fcd));
01041 
01042     return filename;
01043 }
01044 
01045 
01046 /**
01047  *  Update main window heraia's name to reflect the current edited file
01048  * @param main_struct : main structure
01049  */
01050 void update_main_window_name(heraia_struct_t *main_struct)
01051 {
01052     GtkWidget *widget = NULL;
01053     gchar *filename = NULL;
01054     gchar *whole_filename = NULL;
01055 
01056     if (main_struct != NULL && main_struct->current_doc != NULL)
01057        {
01058             widget = heraia_get_widget(main_struct->xmls->main, "main_window");
01059 
01060             whole_filename = doc_t_document_get_filename(main_struct->current_doc);
01061 
01062             filename = g_filename_display_basename(whole_filename);
01063 
01064             gtk_window_set_title(GTK_WINDOW(widget), filename);
01065        }
01066 }
01067 
01068 
01069 /**
01070  *  Sets notebook's tab's name. This function should only be called
01071  *  when a new filename was set (open and save as functions)
01072  * @param main_struct : main structure
01073  */
01074 void set_notebook_tab_name(heraia_struct_t *main_struct)
01075 {
01076     GtkWidget *notebook = NULL; /* file notebook in main window       */
01077     GtkWidget *page = NULL;     /* Current page for the file notebook */
01078     GtkWidget *label = NULL;    /* tab's label                        */
01079     doc_t *doc = NULL;          /* corresponding tab's document       */
01080     gchar *filename = NULL;
01081     gchar *whole_filename;
01082     gint current = 0;           /* index of the current tab displayed */
01083     gchar *markup= NULL;        /* markup text                        */
01084 
01085     if (main_struct != NULL && main_struct->current_doc != NULL)
01086        {
01087            notebook = heraia_get_widget(main_struct->xmls->main, "file_notebook");
01088            current = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
01089            page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), current);
01090            label = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
01091 
01092            doc = g_ptr_array_index(main_struct->documents, current);
01093            whole_filename = doc_t_document_get_filename(doc);
01094 
01095            if (whole_filename != NULL)
01096                {
01097                     filename = g_filename_display_basename(whole_filename);
01098                     markup =  g_markup_printf_escaped("%s", filename);
01099                     gtk_label_set_markup(GTK_LABEL(label), markup);
01100                     gtk_widget_set_tooltip_text(label, g_filename_display_name(whole_filename));
01101                     g_free(markup);
01102                }
01103        }
01104 }
01105 
01106 
01107 /**
01108  * Set the style for the label
01109  * @param main_struct : main structure
01110  * @param color : If color is TRUE sets the color for the file tab's label
01111  *                If not, then sets it to default
01112  */
01113 void set_notebook_tab_label_color(heraia_struct_t *main_struct, gboolean color)
01114 {
01115     GtkWidget *notebook = NULL; /* file notebook in main window       */
01116     GtkWidget *page = NULL;     /* Current page for the file notebook */
01117     GtkWidget *label = NULL;    /* tab's label                        */
01118     gint current = 0;           /* index of the current tab displayed */
01119     gchar *markup= NULL;        /* markup text                        */
01120     gchar *text = NULL;         /* label's text                       */
01121 
01122     if (main_struct != NULL && main_struct->current_doc != NULL)
01123         {
01124             notebook = heraia_get_widget(main_struct->xmls->main, "file_notebook");
01125             current = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
01126             page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), current);
01127             label = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), page);
01128 
01129             text = g_strdup(gtk_label_get_text(GTK_LABEL(label)));
01130 
01131             if (color == TRUE)
01132                 {
01133                     markup = g_markup_printf_escaped("<span foreground=\"blue\">%s</span>", text);
01134                 }
01135             else
01136                 {
01137                     markup = g_markup_printf_escaped("%s", text);
01138                 }
01139 
01140             log_message(main_struct, G_LOG_LEVEL_DEBUG, Q_("Changing color for filename %s in tab : %d"), markup, current);
01141             gtk_label_set_markup(GTK_LABEL(label), markup);
01142             g_free(markup);
01143             g_free(text);
01144         }
01145 }
01146 
01147 
01148 /**
01149  * Hides or grey all widgets that needs an open file when boolean greyed is
01150  * TRUE. Also sets the current page of the notebook to the first one.
01151  * @param xml : GtkBuilder XML main structure
01152  * @param greyed : boolean (TRUE to hide an grey widgets)
01153  */
01154 void grey_main_widgets(GtkBuilder *xml, gboolean greyed)
01155 {
01156     GtkWidget *notebook = NULL;  /* file notebook in main window */
01157 
01158     if (xml != NULL)
01159         {
01160             notebook = heraia_get_widget(xml, "file_notebook");
01161             gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
01162 
01163             if (greyed == TRUE)
01164                 {
01165                     gtk_widget_set_sensitive(heraia_get_widget(xml, "save"), FALSE);
01166                     gtk_widget_set_sensitive(heraia_get_widget(xml, "save_as"), FALSE);
01167                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_cut"), FALSE);
01168                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_copy"), FALSE);
01169                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_paste"), FALSE);
01170                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_delete"), FALSE);
01171                     gtk_widget_hide(notebook);
01172                 }
01173             else
01174                 {
01175                     gtk_widget_set_sensitive(heraia_get_widget(xml, "save"), TRUE);
01176                     gtk_widget_set_sensitive(heraia_get_widget(xml, "save_as"), TRUE);
01177                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_cut"), TRUE);
01178                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_copy"), TRUE);
01179                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_paste"), TRUE);
01180                     gtk_widget_set_sensitive(heraia_get_widget(xml, "menu_delete"), TRUE);
01181                     gtk_widget_show_all(notebook);
01182                 }
01183         }
01184 }
01185 
01186 
01187 /**
01188  *  Here we might init some call backs and menu options
01189  *  and display the interface (main && sub-windows)
01190  *  This function should be called only once at main program's
01191  *  init time
01192  * @param main_struct : main structure
01193  */
01194 void init_heraia_interface(heraia_struct_t *main_struct)
01195 {
01196 
01197     if (main_struct != NULL)
01198         {
01199             /* inits window states (shows or hide windows) */
01200             init_window_states(main_struct);
01201 
01202 
01203             /* menus */
01204             gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_redo"), FALSE);
01205             gtk_widget_set_sensitive(heraia_get_widget(main_struct->xmls->main, "menu_undo"), FALSE);
01206             if (main_struct->current_doc != NULL)
01207                 {
01208                     grey_main_widgets(main_struct->xmls->main, FALSE);
01209                 }
01210             else
01211                 {
01212                     grey_main_widgets(main_struct->xmls->main, TRUE);
01213                 }
01214 
01215             refresh_file_labels(main_struct);
01216         }
01217 }
01218 
01219 
01220 /**
01221  *  Loads the GtkBuilder xml files that describes the heraia project
01222  *  tries the following paths in that order :
01223  *  - /etc/heraia/heraia.gtkbuilder
01224  *  - /home/[user]/.heraia/heraia.gtkbuilder
01225  *  - PWD/heraia.gtkbuilder
01226  * @param main_struct : main structure
01227  * @return TRUE if everything went ok, FALSE otherwise
01228  */
01229 static gboolean load_heraia_xml(heraia_struct_t *main_struct)
01230 {
01231     gchar *filename = NULL;
01232 
01233     if (main_struct != NULL && main_struct->xmls != NULL)
01234         {
01235             filename = g_strdup_printf("heraia.gtkbuilder");
01236             main_struct->xmls->main = load_xml_file(main_struct->location_list, filename);
01237             g_free(filename);
01238 
01239             if (main_struct->xmls->main == NULL)
01240                 {
01241                     return FALSE;
01242                 }
01243             else
01244                 {
01245                     return TRUE;
01246                 }
01247         }
01248     else
01249         {
01250             return FALSE;
01251         }
01252 }
01253 
01254 
01255 /**
01256  *  Connects the signal that the cursor has moved to
01257  *  the refreshing function
01258  * @param main_struct : main structure
01259  * @param hex_widget : the hex_widget we want to connect the signal to
01260  */
01261 void connect_cursor_moved_signal(heraia_struct_t *main_struct, GtkWidget *hex_widget)
01262 {
01263     g_signal_connect(G_OBJECT(hex_widget), "cursor_moved",
01264                      G_CALLBACK(refresh_event_handler), main_struct);
01265 }
01266 
01267 
01268 /**
01269  *  Connect the signals at the interface
01270  * @param main_struct : main structure
01271  */
01272 static void heraia_ui_connect_signals(heraia_struct_t *main_struct)
01273 {
01274 
01275     /* the data interpretor menu */
01276     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "DIMenu")), "activate",
01277                      G_CALLBACK(on_DIMenu_activate), main_struct);
01278 
01279     /* Quit, file menu */
01280     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "quit")), "activate",
01281                      G_CALLBACK(on_quit_activate), main_struct);
01282 
01283     /* New, file menu */
01284     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "new")), "activate",
01285                      G_CALLBACK(on_new_activate), main_struct);
01286 
01287     /* Open, file menu */
01288     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "open")), "activate",
01289                      G_CALLBACK(on_open_activate), main_struct);
01290 
01291     /* Save, file menu */
01292     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "save")), "activate",
01293                      G_CALLBACK(on_save_activate), main_struct);
01294 
01295     /* Save As, file menu */
01296     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "save_as")), "activate",
01297                      G_CALLBACK(on_save_as_activate), main_struct);
01298 
01299     /* Preferences, file menu ; See main_pref_window.c for main_pref_window's signals */
01300     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "preferences")), "activate",
01301                      G_CALLBACK(on_preferences_activate), main_struct);
01302 
01303    /* Undo, edit menu */
01304     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_undo")), "activate",
01305                      G_CALLBACK(on_undo_activate), main_struct);
01306 
01307    /* Redo, edit menu */
01308     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_redo")), "activate",
01309                      G_CALLBACK(on_redo_activate), main_struct);
01310 
01311     /* Cut, edit menu */
01312     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_cut")), "activate",
01313                      G_CALLBACK(on_cut_activate), main_struct);
01314 
01315     /* Copy, edit menu */
01316     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_copy")), "activate",
01317                      G_CALLBACK(on_copy_activate), main_struct);
01318 
01319     /* Paste, edit menu */
01320     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_paste")), "activate",
01321                      G_CALLBACK(on_paste_activate), main_struct);
01322 
01323     /* Delete, edit menu */
01324     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "menu_delete")), "activate",
01325                      G_CALLBACK(on_delete_activate), main_struct);
01326 
01327     /* Test, Help menu */
01328     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "tests_menu")), "activate",
01329                      G_CALLBACK(on_tests_menu_activate), main_struct);
01330 
01331 
01332     /* about dialog box */
01333     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "a_propos")), "activate",
01334                      G_CALLBACK(a_propos_activate), main_struct);
01335 
01336     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "close",
01337                      G_CALLBACK(a_propos_close), main_struct);
01338 
01339     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "response",
01340                      G_CALLBACK(a_propos_response), main_struct);
01341 
01342     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "about_dialog")), "delete-event",
01343                      G_CALLBACK(a_propos_delete), main_struct);
01344 
01345 
01346     /* main notebook */
01347     g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "file_notebook")),"switch-page",
01348                      G_CALLBACK(file_notebook_tab_changed), main_struct);
01349 
01350 
01351     /* main window killed or destroyed */
01352     g_signal_connect(G_OBJECT (heraia_get_widget(main_struct->xmls->main, "main_window")), "delete-event",
01353                      G_CALLBACK(delete_main_struct_event), main_struct);
01354 }
01355 
01356 
01357 /** @fn int load_heraia_ui(heraia_struct_t *main_struct)
01358  *  Loads, if possible, the gtkbuilder xml file and then connects the
01359  *  signals and inits the following windows :
01360  *  - log window
01361  *  - data_interpretor window
01362  *  - list data types
01363  * @param main_struct : main structure
01364  * @return TRUE if load_heraia_xml suceeded, FALSE otherwise
01365  * @todo add more return values to init functions to detect any error while
01366  *       initializing the ui
01367  */
01368 int load_heraia_ui(heraia_struct_t *main_struct)
01369 {
01370     gboolean success = FALSE;
01371 
01372     /* load the XML interfaces (main & treatment) */
01373     success = load_heraia_xml(main_struct);
01374 
01375     if (success == TRUE)
01376         {
01377             /* Heraia UI signals */
01378             if (main_struct->debug == TRUE)
01379                 {
01380                     fprintf(stdout, Q_("Connecting heraia_ui signals     "));
01381                 }
01382 
01383             heraia_ui_connect_signals(main_struct);
01384 
01385             if (main_struct->debug == TRUE)
01386                 {
01387                     fprintf(stdout, Q_(" [Done]\n"));
01388                 }
01389 
01390             /* The Log window */
01391             if (main_struct->debug == TRUE)
01392                 {
01393                     fprintf(stdout, Q_("log window init interface        "));
01394                 }
01395 
01396             log_window_init_interface(main_struct);
01397 
01398             if (main_struct->debug == TRUE)
01399                 {
01400                     fprintf(stdout, Q_(" [Done]\n"));
01401                 }
01402 
01403             /* Preferences window */
01404             if (main_struct->debug == TRUE)
01405                 {
01406                     fprintf(stdout, Q_("preferences window init interface"));
01407                 }
01408 
01409             main_pref_window_init_interface(main_struct);
01410 
01411             if (main_struct->debug == TRUE)
01412                 {
01413                     fprintf(stdout, Q_(" [Done]\n"));
01414                 }
01415 
01416 
01417             /* The data interpretor window */
01418             if (main_struct->debug == TRUE)
01419                 {
01420                     fprintf(stdout, Q_("data interpretor init interface  "));
01421                 }
01422 
01423             data_interpretor_init_interface(main_struct);
01424 
01425             if (main_struct->debug == TRUE)
01426                 {
01427                     fprintf(stdout, Q_(" [Done]\n"));
01428                 }
01429 
01430 
01431             /* preferences file */
01432 
01433             fprintf(stdout, Q_("Loading heraia preference file   "));
01434 
01435             if (load_preference_file(main_struct) != TRUE)
01436                 {
01437                     fprintf(stdout, Q_(" [FAILED]\n"));
01438                 }
01439             else /* Setting up preferences */
01440                 {
01441                     fprintf(stdout, Q_(" [Done]\n"));
01442                     fprintf(stdout, Q_("Setting up preferences           "));
01443                     load_preferences(main_struct);
01444                     fprintf(stdout, Q_(" [Done]\n"));
01445                 }
01446         }
01447 
01448     return success;
01449 }
01450 
01451 
01452 /**
01453  * @fn void add_text_to_textview(GtkTextView *textview, const char *format, ...)
01454  *  adds a text to a textview
01455  * @param textview : the textview where to add text
01456  * @param format : printf style format
01457  * @param ... : a va_list arguments to fit format (as with printf)
01458  */
01459 void add_text_to_textview(GtkTextView *textview, const char *format, ...)
01460 {
01461     va_list args;
01462     GtkTextBuffer *tb = NULL;
01463     GtkTextIter iEnd;
01464     gchar *display = NULL;
01465     GError *err = NULL;
01466 
01467     va_start(args, format);
01468     display = g_locale_to_utf8(g_strdup_vprintf(format, args), -1, NULL, NULL, &err);
01469     va_end(args);
01470 
01471     tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)));
01472     gtk_text_buffer_get_end_iter(tb, &iEnd);
01473     gtk_text_buffer_insert(tb, &iEnd, display, -1);
01474     g_free(display);
01475 }
01476 
01477 
01478 /**
01479  * @fn kill_text_from_textview(GtkTextView *textview)
01480  *  Kills the text from a textview
01481  * @param textview : the textview to kill the text from
01482  */
01483 void kill_text_from_textview(GtkTextView *textview)
01484 {
01485     GtkTextBuffer *tb = NULL;
01486     GtkTextIter iStart;
01487     GtkTextIter iEnd;
01488 
01489     tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)));
01490     gtk_text_buffer_get_start_iter(tb, &iStart);
01491     gtk_text_buffer_get_end_iter(tb, &iEnd);
01492     gtk_text_buffer_delete (tb, &iStart, &iEnd);
01493 }
01494 
01495 
01496 /**
01497  * @fn GtkWidget *gtk_radio_button_get_active(GSList *group)
01498  *  Try to find the active radio button widget in a group
01499  *  This does not take into account inconsistant states
01500  *  returns the first active radio button otherwise NULL
01501  * @param group : A group of GtkRadioButtons
01502  * @return returns the active widget if any (NULL if none)
01503  */
01504 GtkWidget *gtk_radio_button_get_active(GSList *group)
01505 {
01506     GSList *tmp_slist = group;
01507     GtkToggleButton *toggle_button = NULL;
01508 
01509     while (tmp_slist)
01510         {
01511             toggle_button = tmp_slist->data;
01512 
01513             if (gtk_toggle_button_get_active(toggle_button))
01514                 {
01515                     return GTK_WIDGET(toggle_button);
01516                 }
01517 
01518             tmp_slist = g_slist_next(tmp_slist);
01519         }
01520 
01521     return NULL;
01522 }
01523 
01524 
01525 /**
01526  * @fn GtkWidget *gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_group_member)
01527  * gets the active radio button from a radio group
01528  * @param radio_button : GtkRadioButton to get radio group from
01529  * @returns the active GtkRadioButton within the group from
01530  *          radio_button
01531  **/
01532 GtkWidget *gtk_radio_button_get_active_from_widget(GtkRadioButton *radio_button)
01533 {
01534     if (radio_button != NULL)
01535         {
01536             return gtk_radio_button_get_active(gtk_radio_button_get_group(radio_button));
01537         }
01538     else
01539         {
01540             return NULL;
01541         }
01542 }
01543 
01544 
01545 /**
01546  * Sets the radio button active
01547  * @param radio_button : The GtkRadioButton to be active within it's group
01548  */
01549 void gtk_radio_button_set_active(GtkRadioButton *radio_button)
01550 {
01551     GSList *group = NULL;
01552     GtkToggleButton *toggle_button = NULL;
01553 
01554     group = gtk_radio_button_get_group(radio_button);
01555 
01556     while (group)
01557         {
01558             toggle_button = group->data;
01559 
01560             if (toggle_button == GTK_TOGGLE_BUTTON(radio_button))
01561                 {
01562                    gtk_toggle_button_set_active(toggle_button, TRUE);
01563                 }
01564             else
01565                 {
01566                     gtk_toggle_button_set_active(toggle_button, FALSE);
01567                 }
01568 
01569             group = g_slist_next(group);
01570         }
01571 }
01572 
01573 
01574 /**
01575  * @fn gboolean is_cmi_checked(GtkWidget *check_menu_item)
01576  *  Tells whether a GtkCheckMenuItem is Checked or not
01577  * @param check_menu_item : a GtkCheckMenuItem to verify
01578  * @return returns TRUE if the Check Manu Item is checked, FALSE otherwise
01579  */
01580 gboolean is_cmi_checked(GtkWidget *check_menu_item)
01581 {
01582     return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(check_menu_item));
01583 }
01584 
01585 
01586 /**
01587  * @fn gboolean is_toggle_button_activated(GtkBuilder *main_xml, gchar *check_button)
01588  *  returns the state of a named check button contained
01589  *  in the GtkBuilder XML description
01590  * @param main_xml : a GtkBuilder XML definition
01591  * @param check_button : the name of an existing check_button within the GtkBuilder
01592  *        definition
01593  * @return TRUE if the button is activated / toggled , FALSE otherwise
01594  */
01595 gboolean is_toggle_button_activated(GtkBuilder *main_xml, gchar *check_button)
01596 {
01597     gboolean activated = FALSE;
01598 
01599     if (main_xml != NULL)
01600         {
01601             activated = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(heraia_get_widget(main_xml, check_button)));
01602         }
01603 
01604     return activated;
01605 }
01606 
01607 
01608 /**
01609  *  This is a wrapper to the GtkBuilder xml get widget. It is intended
01610  *  to simplify the developpers lives if they have to choose or
01611  *  propose other means to do the same thing than libglade (say,
01612  *  for example, GtkBuilder ;-)
01613  * @param xml : A GtkBuilder XML definition
01614  * @param widget_name : an existing widget name in the GtkBuilder definition
01615  * @return returns the widget itself if it exists in the definition file (NULL
01616  *         otherwise)
01617  */
01618 GtkWidget *heraia_get_widget(GtkBuilder *xml, gchar *widget_name)
01619 {
01620    /**
01621     * For debug purposes only (very verbose as this function is the main used)
01622     * fprintf(stdout, "Getting Widget named %s\n", widget_name);
01623     */
01624 
01625     if (xml != NULL && widget_name != NULL)
01626         {
01627             return GTK_WIDGET(gtk_builder_get_object(xml, widget_name));
01628         }
01629     else
01630         {
01631             return NULL;
01632         }
01633 }
01634 
01635 
01636 /**
01637  * @fn void destroy_a_single_widget(GtkWidget *widget)
01638  *  Destroys a single widget if it exists
01639  * @param widget : the widget to destroy
01640  */
01641 void destroy_a_single_widget(GtkWidget *widget)
01642 {
01643     if (widget != NULL)
01644         {
01645             gtk_widget_destroy(widget);
01646         }
01647 }
01648 
01649 
01650 /**
01651  * Verify if we can safely close everything
01652  * @param main_struct : main structure
01653  * @return a boolean which is TRUE if unsaved documents still exists and FALSE
01654  *         otherwise
01655  */
01656 static gboolean unsaved_documents(heraia_struct_t *main_struct)
01657 {
01658     doc_t *current_doc = NULL;
01659     gboolean result = FALSE;
01660     guint i = 0;
01661 
01662     if (main_struct != NULL && main_struct->documents != NULL)
01663         {
01664             for(i = 0; i < main_struct->documents->len; i++)
01665                 {
01666                     current_doc =  g_ptr_array_index(main_struct->documents, i);
01667                     result = result | current_doc->modified;
01668                 }
01669 
01670             return result;
01671         }
01672 
01673     return result;
01674 }
01675 
01676 
01677 /**
01678  * @fn void close_heraia(heraia_struct_t *main_struct)
01679  * Before closing heraia we need to do few things
01680  * @param main_struct : main_struct
01681  * @return TRUE if we can safely quit heraia, FALSE otherwise
01682  */
01683 static gboolean close_heraia(heraia_struct_t *main_struct)
01684 {
01685     gboolean unsaved = FALSE;    /* if there is any unsaved documents */
01686     gboolean quit_heraia = TRUE; /* By default we want to quit        */
01687     GtkWidget *dialog = NULL;
01688     GtkWidget *label = NULL;
01689     GtkWidget *content_area = NULL;
01690     GtkWidget *parent = NULL;
01691 
01692     unsaved = unsaved_documents(main_struct);
01693 
01694     if (unsaved == TRUE)
01695         {
01696             /* Displays a dialog box that let the user choose what to do */
01697             parent = heraia_get_widget(main_struct->xmls->main, "main_window");
01698             dialog = gtk_dialog_new_with_buttons(Q_("Unsaved document(s) remains."), GTK_WINDOW(parent), GTK_DIALOG_DESTROY_WITH_PARENT,
01699                                                  GTK_STOCK_YES, GTK_RESPONSE_YES,
01700                                                  GTK_STOCK_NO, GTK_RESPONSE_NO, NULL);
01701             content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
01702             gtk_container_set_border_width(GTK_CONTAINER(content_area), 4);
01703             label = gtk_label_new(Q_("Do you want to quit without saving ?"));
01704             gtk_container_add(GTK_CONTAINER(content_area), label);
01705             gtk_widget_show_all(dialog);
01706 
01707             gint result = gtk_dialog_run(GTK_DIALOG(dialog));
01708 
01709             switch (result)
01710                 {
01711                     case GTK_RESPONSE_YES:
01712                         quit_heraia = TRUE;
01713                     break;
01714 
01715                     default:
01716                         quit_heraia = FALSE;
01717                     break;
01718                 }
01719 
01720             gtk_widget_destroy(dialog);
01721         }
01722 
01723     if ( quit_heraia == TRUE)
01724         {
01725             /* recording window's position */
01726             record_all_dialog_box_positions(main_struct);
01727 
01728             /* . Saving preferences */
01729             save_preferences(main_struct);
01730         }
01731 
01732     return quit_heraia;
01733 }
01734 
01735 
01736 /**
01737  * @fn void init_one_cmi_window_state(GtkWidget *dialog_box, GtkWidget *cmi, window_prop_t *dialog_prop)
01738  * init one cmi window based state
01739  * @param dialog_box : the window or dialog box we want to init its state
01740  * @param cmi : corresponding check menu item
01741  * @param dialog_prop : corresponding window properties (should be initialized and not NULL)
01742  */
01743 static void init_one_cmi_window_state(GtkWidget *dialog_box, GtkWidget *cmi, window_prop_t *dialog_prop)
01744 {
01745     gboolean activated = FALSE;
01746 
01747     if (dialog_box != NULL && cmi != NULL && dialog_prop != NULL)
01748         {
01749             activated = dialog_prop->displayed;
01750             gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(cmi), activated);
01751             if (activated == TRUE)
01752                 {
01753                     gtk_window_move(GTK_WINDOW(dialog_box), dialog_prop->x, dialog_prop->y);
01754                     gtk_window_resize(GTK_WINDOW(dialog_box), dialog_prop->width, dialog_prop->height);
01755                     gtk_widget_show_all(dialog_box);
01756                 }
01757         }
01758 }
01759 
01760 
01761 /**
01762  * @fn init_window_states(heraia_struct_t *main_struct)
01763  *  Inits all windows states (positions, displayed, and so on...)
01764  * @param main_struct : main structure
01765  */
01766 void init_window_states(heraia_struct_t *main_struct)
01767 {
01768     GtkWidget *cmi = NULL;
01769     GtkWidget *dialog_box = NULL;
01770 
01771     if (main_struct != NULL && main_struct->xmls != NULL  && main_struct->xmls->main != NULL)
01772         {
01773             if (main_struct->win_prop)
01774                 {
01775                     /* Main window (always the first one) */
01776                     dialog_box = heraia_get_widget(main_struct->xmls->main, "main_window");
01777                     if (main_struct->win_prop->main_dialog->displayed == TRUE)
01778                         {
01779                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->main_dialog->x, main_struct->win_prop->main_dialog->y);
01780                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->main_dialog->width, main_struct->win_prop->main_dialog->height);
01781                             gtk_widget_show(dialog_box);
01782                         }
01783 
01784                     /* Log Window Interface */
01785                     cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw");
01786                     dialog_box = heraia_get_widget(main_struct->xmls->main, "log_window");
01787                     init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->log_box);
01788 
01789                     /* Data Interpretor Interface */
01790                     cmi = heraia_get_widget(main_struct->xmls->main, "DIMenu");
01791                     /* Emit the specific signal to activate the check_menu_item */
01792                     if (main_struct->win_prop->data_interpretor->displayed == TRUE)
01793                         {
01794                             main_struct->win_prop->data_interpretor->displayed = FALSE; /* dirty trick */
01795                             g_signal_emit_by_name(heraia_get_widget(main_struct->xmls->main, "DIMenu"), "activate");
01796                         }
01797 
01798                     /* List Data type Interface */
01799                     cmi = heraia_get_widget(main_struct->xmls->main, "ldt_menu");
01800                     dialog_box = heraia_get_widget(main_struct->xmls->main, "list_data_types_window");
01801                     init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->ldt);
01802 
01803                     /* Plugin List Interface */
01804                     cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_plugin_list");
01805                     dialog_box = heraia_get_widget(main_struct->xmls->main, "plugin_list_window");
01806                     init_one_cmi_window_state(dialog_box, cmi, main_struct->win_prop->plugin_list);
01807 
01808                     /* Preferences window */
01809                     dialog_box = heraia_get_widget(main_struct->xmls->main, "main_preferences_window");
01810                     if (main_struct->win_prop->main_pref_window->displayed == TRUE)
01811                         {
01812                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->main_pref_window->x, main_struct->win_prop->main_pref_window->y);
01813                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->main_pref_window->width, main_struct->win_prop->main_pref_window->height);
01814                             gtk_widget_show_all(dialog_box);
01815                         }
01816 
01817                     /* About Box */
01818                     dialog_box = heraia_get_widget(main_struct->xmls->main, "about_dialog");
01819                     if (main_struct->win_prop->about_box->displayed == TRUE)
01820                         {
01821                             gtk_window_move(GTK_WINDOW(dialog_box), main_struct->win_prop->about_box->x, main_struct->win_prop->about_box->y);
01822                             gtk_window_resize(GTK_WINDOW(dialog_box), main_struct->win_prop->about_box->width, main_struct->win_prop->about_box->height);
01823                             set_a_propos_properties(dialog_box);
01824                             gtk_widget_show_all(dialog_box);
01825                         }
01826                 }
01827         }
01828 }
01829 
01830 /**
01831  *  Adds a new tab to the main window in file's notebook
01832  * @param main_struct : main structure
01833  * @param doc : the new document that will be related to the tab
01834  */
01835 void add_new_tab_in_main_window(heraia_struct_t *main_struct, doc_t *doc)
01836 {
01837     GtkWidget *vbox = NULL;       /**< used for vbox creation               */
01838     GtkNotebook *notebook = NULL; /**< file_notebook from heraia.gtkbuilder */
01839     GtkWidget *tab_label = NULL;  /**< tab's label                          */
01840     gint tab_num = -1;            /**< new tab's index                      */
01841     gchar *filename = NULL;
01842     gchar *whole_filename;
01843     gchar *markup= NULL;        /* markup text                        */
01844 
01845     notebook = GTK_NOTEBOOK(heraia_get_widget(main_struct->xmls->main, "file_notebook"));
01846     vbox = gtk_vbox_new(FALSE, 2);
01847     gtk_box_pack_start(GTK_BOX(vbox), doc->hex_widget, TRUE, TRUE, 3);
01848 
01849     /* tab's label */
01850     tab_label = gtk_label_new(NULL);
01851     whole_filename = doc_t_document_get_filename(doc);
01852 
01853     if (whole_filename != NULL)
01854         {
01855             filename = g_filename_display_basename(whole_filename);
01856             markup =  g_markup_printf_escaped("%s", filename);
01857             gtk_label_set_markup(GTK_LABEL(tab_label), markup);
01858             gtk_widget_set_tooltip_text(tab_label, g_filename_display_name(whole_filename));
01859             g_free(markup);
01860         }
01861 
01862 
01863     gtk_widget_show_all(vbox);
01864     tab_num = gtk_notebook_append_page(notebook, vbox, tab_label);
01865 
01866     gtk_notebook_set_current_page(notebook, tab_num);
01867     main_struct->current_doc = doc;
01868 }
01869 
01870 
01871 /**
01872  *  To help plugins to deal with widgets, shows or hide a specific widget
01873  * @param widget : the widget to show or hide
01874  * @param show : what to do : TRUE to show the widget, FALSE to hide it
01875  * @param win_prop : window properties.
01876  */
01877 void show_hide_widget(GtkWidget *widget, gboolean show, window_prop_t *win_prop)
01878 {
01879     if (win_prop != NULL)
01880             {
01881                 if (show)
01882                     {
01883                         move_and_show_dialog_box(widget, win_prop);
01884                     }
01885                 else
01886                     {
01887                         record_and_hide_dialog_box(widget, win_prop);
01888                     }
01889             }
01890         else
01891             {
01892                 if (show)
01893                     {
01894                         gtk_widget_show(widget);
01895                     }
01896                 else
01897                     {
01898                         gtk_widget_hide(widget);
01899                     }
01900             }
01901 }
Generated on Tue Aug 10 18:29:02 2010 for Heraia by  doxygen 1.6.3