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

Generated on Tue Jun 30 23:18:17 2009 for Heraia by  doxygen 1.5.8