log.c

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 /*
00003   log.c
00004   log functions for heraia
00005 
00006   (C) Copyright 2006 - 2011 Olivier Delhomme
00007   e-mail : heraia@delhomme.org
00008   URL    : http://heraia.tuxfamily.org
00009 
00010   This program is free software; you can redistribute it and/or modify
00011   it under the terms of the GNU General Public License as published by
00012   the Free Software Foundation; either version 2, or  (at your option)
00013   any later version.
00014 
00015   This program is distributed in the hope that it will be useful,
00016   but WITHOUT ANY WARRANTY;  without even the implied warranty of
00017   MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the
00018   GNU General Public License for more details.
00019 
00020   You should have received a copy of the GNU General Public License
00021   along with this program; if not, write to the Free Software
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023 */
00024 /**
00025  * @file log.c
00026  * Includes everything that deals with the logging system
00027  */
00028 #include <libheraia.h>
00029 
00030 
00031 static void my_log(heraia_struct_t *main_struct, gchar *log_domain, GLogLevelFlags log_level, const char *format, ...);
00032 static void log_window_connect_signals(heraia_struct_t *main_struct);
00033 static gboolean delete_log_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data );
00034 static void destroy_log_window(GtkWidget *widget, GdkEvent  *event, gpointer data);
00035 static void logw_close_clicked(GtkWidget *widget, gpointer data);
00036 static void scroll_down_textview(heraia_struct_t *main_struct);
00037 
00038 /**
00039  * @fn print_message(const char *format, ...)
00040  * Prints a  message to stdout
00041  * @param format : a printf style format
00042  * @param ... : va_list to fill the format.
00043  */
00044 void print_message(const char *format, ...)
00045 {
00046     va_list args;
00047     gchar *str = NULL;
00048     gchar *str_utf8 = NULL;
00049     GError *err = NULL;
00050 
00051     g_return_if_fail (format != NULL);
00052 
00053     va_start(args, format);
00054     str = g_strdup_vprintf(format, args);
00055     va_end(args);
00056 
00057     str_utf8 = g_locale_to_utf8(str, -1, NULL, NULL, &err);
00058 
00059     if (str_utf8)
00060         {
00061             fputs(str_utf8, stdout);
00062             g_free(str_utf8);
00063         }
00064     else
00065         {
00066             fprintf(stderr, Q_("Can't convert output to the locale: %s\n"), err->message);
00067             fputs(str, stderr);
00068             g_error_free(err);
00069         }
00070 
00071     g_free(str);
00072 }
00073 
00074 
00075 /**
00076  * @fn my_log(heraia_struct_t *main_struct, gchar *log_domain, GLogLevelFlags log_level, const char *format, ...);
00077  *  A function that allow me to printy things on stdout and in th log window
00078  * @param main_struct : main structure
00079  * @param log_domain : should be the program's name
00080  * @param log_level : A string that may be either G_LOG_FLAG_RECURSION,
00081  *        G_LOG_FLAG_FATAL, G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL,
00082  *        G_LOG_LEVEL_WARNING, G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO,
00083  *        G_LOG_LEVEL_DEBUG
00084  * @param format : a printf style format
00085  * @param ... : va_list to fill the format.
00086  */
00087 static void my_log(heraia_struct_t *main_struct, gchar *log_domain, GLogLevelFlags log_level, const char *format, ...)
00088 {
00089     va_list args;
00090     gchar *str = NULL;
00091     gchar *display = NULL;
00092     GtkTextView *logw_textview = GTK_TEXT_VIEW(heraia_get_widget(main_struct->xmls->main, "logw_textview"));
00093     GtkTextBuffer *tb = NULL;
00094     GtkTextIter iStart;
00095 
00096     va_start(args, format);
00097     str = g_strdup_vprintf(format, args);
00098     va_end(args);
00099 
00100     switch (log_level)
00101         {
00102             case G_LOG_FLAG_RECURSION:
00103                 display = g_strdup_printf(Q_("%s - RECURSION: %s\n%c"), log_domain, str, '\0');
00104                 g_print("%s\n", display);
00105                 /* exit(log_level); */
00106                 break;
00107 
00108             case G_LOG_FLAG_FATAL:
00109                 display = g_strdup_printf(Q_("%s - FATAL: %s\n%c"), log_domain, str, '\0');
00110                 g_print("%s\n", display);
00111                 /* exit(log_level); */
00112                 break;
00113 
00114             case G_LOG_LEVEL_ERROR:
00115                 display = g_strdup_printf(Q_("%s - ERROR: %s\n%c"), log_domain, str, '\0');
00116                 g_print("%s\n", display);
00117                 /* exit(log_level); */
00118                 break;
00119 
00120             case G_LOG_LEVEL_CRITICAL:
00121                 display = g_strdup_printf(Q_("%s - CRITICAL: %s\n%c"), log_domain, str, '\0');
00122                 break;
00123 
00124             case G_LOG_LEVEL_WARNING:
00125                 display = g_strdup_printf(Q_("%s - WARNING: %s\n%c"), log_domain, str, '\0');
00126                 break;
00127 
00128             case G_LOG_LEVEL_MESSAGE:
00129                 display = g_strdup_printf(Q_("%s - MESSAGE: %s\n%c"), log_domain, str, '\0');
00130                 break;
00131 
00132             case G_LOG_LEVEL_INFO:
00133                 display = g_strdup_printf(Q_("%s - INFO: %s\n%c"), log_domain, str, '\0');
00134                 break;
00135 
00136             case G_LOG_LEVEL_DEBUG:
00137                 display = g_strdup_printf(Q_("%s - DEBUG: %s\n%c"), log_domain, str, '\0');
00138                 break;
00139 
00140             case G_LOG_LEVEL_MASK: /* To avoid a compilation warning */
00141                 break;
00142         }
00143 
00144     g_print("%s", display);
00145 
00146     /* inserting text in the textview */
00147     tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(logw_textview)));
00148 
00149     gtk_text_buffer_get_end_iter(tb, &iStart);
00150     gtk_text_buffer_insert(tb, &iStart, display, -1);
00151 
00152     /* scrolling down */
00153     scroll_down_textview(main_struct);
00154 
00155     g_free(str);
00156     g_free(display);
00157 }
00158 
00159 
00160 /**
00161  * Scrolling down to the new line at the end of the textview
00162  * @param main_struct : main structure
00163  */
00164 static void scroll_down_textview(heraia_struct_t *main_struct)
00165 {
00166     GtkTextView *logw_textview = NULL;
00167     GtkTextBuffer *tb = NULL;
00168     GtkTextIter end;
00169     GtkTextMark *mark = NULL;
00170 
00171     logw_textview = GTK_TEXT_VIEW(heraia_get_widget(main_struct->xmls->main, "logw_textview"));
00172     tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(logw_textview)));
00173 
00174     gtk_text_buffer_get_end_iter(tb, &end);
00175     gtk_text_iter_set_line_offset(&end, 0);
00176     mark = gtk_text_buffer_get_mark(tb, "scroll");
00177     gtk_text_buffer_move_mark(tb, mark, &end);
00178     gtk_text_view_scroll_mark_onscreen(logw_textview, mark);
00179 }
00180 
00181 
00182 /**
00183  * @fn log_message(heraia_struct_t *main_struct, GLogLevelFlags log_level, const char *format, ...)
00184  *  A function that helps logging a message a the specified level. A wrapper to
00185  *  my_log function log_domain is defined by HERAIA_LOG_DOMAIN
00186  * @param main_struct : main structure
00187  * @param log_level : A string that may be either G_LOG_FLAG_RECURSION,
00188  *        G_LOG_FLAG_FATAL, G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL,
00189  *        G_LOG_LEVEL_WARNING, G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO,
00190  *        G_LOG_LEVEL_DEBUG
00191  * @param format : a printf style format
00192  * @param ... : va_list to fill the format.
00193  * @todo may be include the hability to choose a different log domain ?
00194  */
00195 void log_message(heraia_struct_t *main_struct, GLogLevelFlags log_level, const char *format, ...)
00196 {
00197     va_list args;
00198     gchar *str = NULL;
00199     gchar *str_time = NULL;
00200     gchar *str_time_utf8 = NULL;
00201     gchar *str_utf8 = NULL;
00202     GTimeVal *time = NULL;
00203     GError *err = NULL;
00204 
00205     if (!(main_struct->debug == FALSE && log_level == G_LOG_LEVEL_DEBUG))
00206         {
00207             g_return_if_fail(format != NULL);
00208 
00209             va_start(args, format);
00210             str = g_strdup_vprintf(format, args);
00211             va_end(args);
00212             str_utf8 = g_locale_to_utf8(str, -1, NULL, NULL, &err);
00213 
00214             time = (GTimeVal *) g_malloc0 (sizeof(GTimeVal));
00215             g_get_current_time(time);
00216             str_time = g_time_val_to_iso8601(time);
00217             str_time_utf8 = g_locale_to_utf8(str_time, -1, NULL, NULL, &err);
00218 
00219 
00220             if (str_utf8)
00221                 {
00222                     if (str_time_utf8)
00223                         {
00224                             my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time_utf8, str_utf8, '\0');
00225                         }
00226                     else
00227                         {
00228                             my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time, str_utf8, '\0');
00229                         }
00230                 }
00231             else
00232                 {
00233                     if (str_time_utf8)
00234                         {
00235                             my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time_utf8, str, '\0');
00236                         }
00237                     else
00238                         {
00239                             my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time, str, '\0');
00240                         }
00241                 }
00242 
00243             g_free(time);
00244             g_free(str);
00245             g_free(str_time);
00246             g_free(str_time_utf8);
00247             g_free(str_utf8);
00248         }
00249 }
00250 
00251 
00252 /**
00253  * @fn mw_cmi_show_logw_toggle(GtkWidget *widget, gpointer data)
00254  *  The Check menu item for the Log window
00255  * @param widget : the widget that issued the signal (here the log check menu
00256  *                 item
00257  * @param data : user data, MUST be main_struct main structure
00258  */
00259 void mw_cmi_show_logw_toggle(GtkWidget *widget, gpointer data)
00260 {
00261     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00262     GtkWidget *cmi = NULL;
00263     gboolean checked = FALSE;
00264     GtkWidget *log_dialog = NULL;
00265 
00266      log_dialog = heraia_get_widget(main_struct->xmls->main, "log_window");
00267 
00268     cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw");
00269     checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(cmi));
00270 
00271     if (checked == TRUE)
00272         {
00273             scroll_down_textview(main_struct);
00274             move_and_show_dialog_box(log_dialog, main_struct->win_prop->log_box);
00275         }
00276     else
00277         {
00278             record_and_hide_dialog_box(log_dialog, main_struct->win_prop->log_box);
00279         }
00280 }
00281 
00282 
00283 /******************************** The Signals *********************************/
00284 
00285 /**
00286  * @fn gboolean delete_log_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data )
00287  *  Closing the window
00288  * @param widget : calling widget
00289  * @param event : event associated (may be NULL as we don't use this here)
00290  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
00291  * @return Always returns TRUE in order to propagate the signal
00292  */
00293 static gboolean delete_log_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data )
00294 {
00295     logw_close_clicked(widget, data);
00296 
00297     return TRUE;
00298 }
00299 
00300 
00301 /**
00302  * @fn void destroy_log_window(GtkWidget *widget, GdkEvent  *event, gpointer data)
00303  * When the window is destroyed (Gtk's doc says that we may never get there)
00304  * @param widget : calling widget
00305  * @param event : event associated (may be NULL as we don't use this here)
00306  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
00307 */
00308 static void destroy_log_window(GtkWidget *widget, GdkEvent  *event, gpointer data)
00309 {
00310     logw_close_clicked(widget, data);
00311 }
00312 
00313 
00314 /**
00315  * @fn  void logw_close_clicked(GtkWidget *widget, gpointer data)
00316  *  Close button is clicked
00317  * @param widget : calling widget
00318  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
00319  */
00320 static void logw_close_clicked(GtkWidget *widget, gpointer data)
00321 {
00322     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00323     GtkWidget *cmi = NULL;
00324     GtkWidget *log_dialog = NULL;
00325 
00326     if (main_struct != NULL && main_struct->xmls != NULL && main_struct->xmls->main != NULL)
00327         {
00328             log_dialog = heraia_get_widget(main_struct->xmls->main, "log_window");
00329             record_and_hide_dialog_box(log_dialog, main_struct->win_prop->log_box);
00330 
00331             cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw");
00332             gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(cmi), FALSE); /* This emits the signals that calls mw_cmi_show_logw_toggle function */
00333         }
00334 }
00335 
00336 
00337 /**
00338  * @fn void log_window_connect_signals(heraia_struct_t *main_struct)
00339  *  Connecting the window signals to the right functions
00340  * @param main_struct : main structure
00341  */
00342 static void log_window_connect_signals(heraia_struct_t *main_struct)
00343 {
00344 
00345     if (main_struct != NULL && main_struct->xmls != NULL && main_struct->xmls->main != NULL)
00346         {
00347 
00348             g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "log_window")), "delete_event",
00349                              G_CALLBACK(delete_log_window_event), main_struct);
00350 
00351             g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "log_window")), "destroy",
00352                              G_CALLBACK(destroy_log_window), main_struct);
00353 
00354             /* Close Button */
00355             g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "logw_close_b")), "clicked",
00356                              G_CALLBACK(logw_close_clicked), main_struct);
00357 
00358             /* the toogle button */
00359             g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw")), "toggled",
00360                              G_CALLBACK(mw_cmi_show_logw_toggle), main_struct);
00361         }
00362 }
00363 /******************************** End Signals *********************************/
00364 
00365 
00366 /**
00367  * @fn log_window_init_interface(heraia_struct_t *main_struct)
00368  *  Inits the log window interface
00369  *  Called once at init time
00370  * @param main_struct : main structure
00371  */
00372 void log_window_init_interface(heraia_struct_t *main_struct)
00373 {
00374     GtkTextView *logw_textview = NULL;
00375     GtkTextBuffer *tb = NULL;
00376     GtkTextIter iStart;
00377 
00378 
00379     if (main_struct != NULL)
00380         {
00381             /* Connecting signals */
00382             log_window_connect_signals(main_struct);
00383 
00384             /* Creating a "scroll" mark on the textview */
00385             if (main_struct->xmls != NULL && main_struct->xmls->main != NULL)
00386                 {
00387                     logw_textview = GTK_TEXT_VIEW(heraia_get_widget(main_struct->xmls->main, "logw_textview"));
00388                     tb = gtk_text_view_get_buffer(logw_textview);
00389                     gtk_text_buffer_get_end_iter(tb, &iStart);
00390                     gtk_text_buffer_create_mark(tb, "scroll", &iStart, TRUE);
00391                 }
00392         }
00393 }
Generated on Mon May 2 21:04:49 2011 for Heraia by  doxygen 1.6.3