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 - 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 /**
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 
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     GtkTextMark *mark = NULL;
00096 
00097     va_start(args, format);
00098     str = g_strdup_vprintf(format, args);
00099     va_end(args);
00100 
00101     switch (log_level)
00102         {
00103             case G_LOG_FLAG_RECURSION:
00104                 display = g_strdup_printf(Q_("%s - RECURSION: %s\n%c"), log_domain, str, '\0');
00105                 g_print("%s\n", display);
00106                 /* exit(log_level); */
00107                 break;
00108 
00109             case G_LOG_FLAG_FATAL:
00110                 display = g_strdup_printf(Q_("%s - FATAL: %s\n%c"), log_domain, str, '\0');
00111                 g_print("%s\n", display);
00112                 /* exit(log_level); */
00113                 break;
00114 
00115             case G_LOG_LEVEL_ERROR:
00116                 display = g_strdup_printf(Q_("%s - ERROR: %s\n%c"), log_domain, str, '\0');
00117                 g_print("%s\n", display);
00118                 /* exit(log_level); */
00119                 break;
00120 
00121             case G_LOG_LEVEL_CRITICAL:
00122                 display = g_strdup_printf(Q_("%s - CRITICAL: %s\n%c"), log_domain, str, '\0');
00123                 break;
00124 
00125             case G_LOG_LEVEL_WARNING:
00126                 display = g_strdup_printf(Q_("%s - WARNING: %s\n%c"), log_domain, str, '\0');
00127                 break;
00128 
00129             case G_LOG_LEVEL_MESSAGE:
00130                 display = g_strdup_printf(Q_("%s - MESSAGE: %s\n%c"), log_domain, str, '\0');
00131                 break;
00132 
00133             case G_LOG_LEVEL_INFO:
00134                 display = g_strdup_printf(Q_("%s - INFO: %s\n%c"), log_domain, str, '\0');
00135                 break;
00136 
00137             case G_LOG_LEVEL_DEBUG:
00138                 display = g_strdup_printf(Q_("%s - DEBUG: %s\n%c"), log_domain, str, '\0');
00139                 break;
00140 
00141             case G_LOG_LEVEL_MASK: /* To avoid a compilation warning */
00142                 break;
00143         }
00144 
00145     g_print("%s", display);
00146     tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(logw_textview)));
00147     gtk_text_buffer_get_end_iter(tb, &iStart);
00148     gtk_text_buffer_insert(tb, &iStart, display, -1);
00149 
00150     /* Scrolling down to the new line */
00151     gtk_text_iter_set_line_offset(&iStart, 0);
00152     mark = gtk_text_buffer_get_mark(tb, "scroll");
00153     gtk_text_buffer_move_mark(tb, mark, &iStart);
00154     gtk_text_view_scroll_mark_onscreen(logw_textview, mark);
00155 
00156     g_free(str);
00157     g_free(display);
00158 }
00159 
00160 
00161 /**
00162  * @fn log_message(heraia_struct_t *main_struct, GLogLevelFlags log_level, const char *format, ...)
00163  *  A function that helps logging a message a the specified level. A wrapper to
00164  *  my_log function log_domain is defined by HERAIA_LOG_DOMAIN
00165  * @param main_struct : main structure
00166  * @param log_level : A string that may be either G_LOG_FLAG_RECURSION,
00167  *        G_LOG_FLAG_FATAL, G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL,
00168  *        G_LOG_LEVEL_WARNING, G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO,
00169  *        G_LOG_LEVEL_DEBUG
00170  * @param format : a printf style format
00171  * @param ... : va_list to fill the format.
00172  * @todo may be include the hability to choose a different log domain ?
00173  */
00174 void log_message(heraia_struct_t *main_struct, GLogLevelFlags log_level, const char *format, ...)
00175 {
00176     va_list args;
00177     gchar *str = NULL;
00178     gchar *str_time = NULL;
00179     gchar *str_time_utf8 = NULL;
00180     gchar *str_utf8 = NULL;
00181     GTimeVal *time = NULL;
00182     GError *err = NULL;
00183 
00184     if (!(main_struct->debug == FALSE && log_level == G_LOG_LEVEL_DEBUG))
00185         {
00186             g_return_if_fail(format != NULL);
00187 
00188             va_start(args, format);
00189             str = g_strdup_vprintf(format, args);
00190             va_end(args);
00191             str_utf8 = g_locale_to_utf8(str, -1, NULL, NULL, &err);
00192 
00193             time = (GTimeVal *) g_malloc0 (sizeof(GTimeVal));
00194             g_get_current_time(time);
00195             str_time = g_time_val_to_iso8601(time);
00196             str_time_utf8 = g_locale_to_utf8(str_time, -1, NULL, NULL, &err);
00197 
00198 
00199             if (str_utf8)
00200                 {
00201                     if (str_time_utf8)
00202                         {
00203                             my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time_utf8, str_utf8, '\0');
00204                         }
00205                     else
00206                         {
00207                             my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time, str_utf8, '\0');
00208                         }
00209                 }
00210             else
00211                 {
00212                     if (str_time_utf8)
00213                         {
00214                             my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time_utf8, str, '\0');
00215                         }
00216                     else
00217                         {
00218                             my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time, str, '\0');
00219                         }
00220                 }
00221 
00222             g_free(time);
00223             g_free(str);
00224             g_free(str_time);
00225             g_free(str_time_utf8);
00226             g_free(str_utf8);
00227         }
00228 }
00229 
00230 
00231 /**
00232  * @fn void show_hide_log_window(heraia_struct_t *main_struct, gboolean show, GtkCheckMenuItem *cmi)
00233  *  Shows and hides the log window
00234  * @param main_struct : main structure
00235  * @param show : a boolean to say whether we want to show (TRUE) or hide (FALSE)
00236  *               the window
00237  * @param cmi : the associated check menu item in the menu
00238  */
00239 
00240 void show_hide_log_window(heraia_struct_t *main_struct, gboolean show, GtkCheckMenuItem *cmi)
00241 {
00242     GtkWidget *log_dialog = NULL;
00243     window_prop_t *log_box_prop = main_struct->win_prop->log_box;
00244 
00245     log_dialog = heraia_get_widget(main_struct->xmls->main, "log_window");
00246 
00247     if (show == TRUE)
00248         {
00249             move_and_show_dialog_box(log_dialog, log_box_prop);
00250         }
00251     else
00252         {
00253             if (log_box_prop->displayed == TRUE)
00254                 {
00255                     gtk_check_menu_item_set_active(cmi, FALSE);
00256                     record_and_hide_dialog_box(log_dialog, log_box_prop);
00257                 }
00258         }
00259 }
00260 
00261 
00262 /**
00263  * @fn mw_cmi_show_logw_toggle(GtkWidget *widget, gpointer data)
00264  *  The Check menu item for the Log window
00265  * @param widget : the widget that issued the signal (here the log check menu
00266  *                 item
00267  * @param data : user data, MUST be main_struct main structure
00268  */
00269 void mw_cmi_show_logw_toggle(GtkWidget *widget, gpointer data)
00270 {
00271     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00272     GtkCheckMenuItem *cmi = GTK_CHECK_MENU_ITEM(widget);
00273     gboolean checked = gtk_check_menu_item_get_active(cmi);
00274 
00275     show_hide_log_window(main_struct, checked, cmi);
00276 }
00277 
00278 
00279 /******************************** The Signals *********************************/
00280 
00281 /**
00282  * @fn gboolean delete_log_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data )
00283  *  Closing the window
00284  * @param widget : calling widget
00285  * @param event : event associated (may be NULL as we don't use this here)
00286  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
00287  * @return Always returns TRUE in order to propagate the signal
00288  */
00289 static gboolean delete_log_window_event(GtkWidget *widget, GdkEvent  *event, gpointer data )
00290 {
00291     logw_close_clicked(widget, data);
00292 
00293     return TRUE;
00294 }
00295 
00296 
00297 /**
00298  * @fn void destroy_log_window(GtkWidget *widget, GdkEvent  *event, gpointer data)
00299  * When the window is destroyed (Gtk's doc says that we may never get there)
00300  * @param widget : calling widget
00301  * @param event : event associated (may be NULL as we don't use this here)
00302  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
00303 */
00304 static void destroy_log_window(GtkWidget *widget, GdkEvent  *event, gpointer data)
00305 {
00306     logw_close_clicked(widget, data);
00307 }
00308 
00309 
00310 /**
00311  * @fn  void logw_close_clicked(GtkWidget *widget, gpointer data)
00312  *  Close button is clicked
00313  * @param widget : calling widget
00314  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
00315  */
00316 static void logw_close_clicked(GtkWidget *widget, gpointer data)
00317 {
00318     heraia_struct_t *main_struct = (heraia_struct_t *) data;
00319     GtkWidget *cmi = NULL;
00320 
00321     if (main_struct != NULL && main_struct->xmls != NULL && main_struct->xmls->main != NULL)
00322         {
00323             cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw");
00324             show_hide_log_window(main_struct, FALSE, GTK_CHECK_MENU_ITEM(cmi));
00325         }
00326 }
00327 
00328 
00329 /**
00330  * @fn void log_window_connect_signals(heraia_struct_t *main_struct)
00331  *  Connecting the window signals to the right functions
00332  * @param main_struct : main structure
00333  */
00334 static void log_window_connect_signals(heraia_struct_t *main_struct)
00335 {
00336 
00337     if (main_struct != NULL && main_struct->xmls != NULL && main_struct->xmls->main != NULL)
00338         {
00339 
00340             g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "log_window")), "delete_event",
00341                              G_CALLBACK(delete_log_window_event), main_struct);
00342 
00343             g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "log_window")), "destroy",
00344                              G_CALLBACK(destroy_log_window), main_struct);
00345 
00346             /* Close Button */
00347             g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "logw_close_b")), "clicked",
00348                              G_CALLBACK(logw_close_clicked), main_struct);
00349 
00350             /* the toogle button */
00351             g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw")), "toggled",
00352                              G_CALLBACK(mw_cmi_show_logw_toggle), main_struct);
00353         }
00354 }
00355 /******************************** End Signals *********************************/
00356 
00357 
00358 /**
00359  * @fn log_window_init_interface(heraia_struct_t *main_struct)
00360  *  Inits the log window interface
00361  *  Called once at init time
00362  * @param main_struct : main structure
00363  */
00364 void log_window_init_interface(heraia_struct_t *main_struct)
00365 {
00366     GtkTextView *logw_textview = NULL;
00367     GtkTextBuffer *tb = NULL;
00368     GtkTextIter iStart;
00369 
00370 
00371     if (main_struct != NULL)
00372         {
00373             /* Connecting signals */
00374             log_window_connect_signals(main_struct);
00375 
00376             /* Creating a "scroll" mark on the textview */
00377             if (main_struct->xmls != NULL && main_struct->xmls->main != NULL)
00378                 {
00379                     logw_textview = GTK_TEXT_VIEW(heraia_get_widget(main_struct->xmls->main, "logw_textview"));
00380                     tb = gtk_text_view_get_buffer(logw_textview);
00381                     gtk_text_buffer_get_end_iter(tb, &iStart);
00382                     gtk_text_buffer_create_mark (tb, "scroll", &iStart, TRUE);
00383                 }
00384         }
00385 }
Generated on Fri Aug 20 09:15:18 2010 for Heraia by  doxygen 1.6.3