Heraia  0.1.8
log.c
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /*
3  log.c
4  log functions for heraia
5 
6  (C) Copyright 2006 - 2011 Olivier Delhomme
7  e-mail : heraia@delhomme.org
8  URL : http://heraia.tuxfamily.org
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2, or (at your option)
13  any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24 /**
25  * @file log.c
26  * Includes everything that deals with the logging system
27  */
28 #include <libheraia.h>
29 
30 
31 static void my_log(heraia_struct_t *main_struct, gchar *log_domain, GLogLevelFlags log_level, const char *format, ...);
32 static void log_window_connect_signals(heraia_struct_t *main_struct);
33 static gboolean delete_log_window_event(GtkWidget *widget, GdkEvent *event, gpointer data );
34 static void destroy_log_window(GtkWidget *widget, GdkEvent *event, gpointer data);
35 static void logw_close_clicked(GtkWidget *widget, gpointer data);
36 static void scroll_down_textview(heraia_struct_t *main_struct);
37 
38 /**
39  * @fn print_message(const char *format, ...)
40  * Prints a message to stdout
41  * @param format : a printf style format
42  * @param ... : va_list to fill the format.
43  */
44 void print_message(const char *format, ...)
45 {
46  va_list args;
47  gchar *str = NULL;
48  gchar *str_utf8 = NULL;
49  GError *err = NULL;
50 
51  g_return_if_fail (format != NULL);
52 
53  va_start(args, format);
54  str = g_strdup_vprintf(format, args);
55  va_end(args);
56 
57  str_utf8 = g_locale_to_utf8(str, -1, NULL, NULL, &err);
58 
59  if (str_utf8)
60  {
61  fputs(str_utf8, stdout);
62  g_free(str_utf8);
63  }
64  else
65  {
66  fprintf(stderr, Q_("Can't convert output to the locale: %s\n"), err->message);
67  fputs(str, stderr);
68  g_error_free(err);
69  }
70 
71  g_free(str);
72 }
73 
74 
75 /**
76  * @fn my_log(heraia_struct_t *main_struct, gchar *log_domain, GLogLevelFlags log_level, const char *format, ...);
77  * A function that allow me to printy things on stdout and in th log window
78  * @param main_struct : main structure
79  * @param log_domain : should be the program's name
80  * @param log_level : A string that may be either G_LOG_FLAG_RECURSION,
81  * G_LOG_FLAG_FATAL, G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL,
82  * G_LOG_LEVEL_WARNING, G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO,
83  * G_LOG_LEVEL_DEBUG
84  * @param format : a printf style format
85  * @param ... : va_list to fill the format.
86  */
87 static void my_log(heraia_struct_t *main_struct, gchar *log_domain, GLogLevelFlags log_level, const char *format, ...)
88 {
89  va_list args;
90  gchar *str = NULL;
91  gchar *display = NULL;
92  GtkTextView *logw_textview = GTK_TEXT_VIEW(heraia_get_widget(main_struct->xmls->main, "logw_textview"));
93  GtkTextBuffer *tb = NULL;
94  GtkTextIter iStart;
95 
96  va_start(args, format);
97  str = g_strdup_vprintf(format, args);
98  va_end(args);
99 
100  switch (log_level)
101  {
102  case G_LOG_FLAG_RECURSION:
103  display = g_strdup_printf(Q_("%s - RECURSION: %s\n%c"), log_domain, str, '\0');
104  g_print("%s\n", display);
105  /* exit(log_level); */
106  break;
107 
108  case G_LOG_FLAG_FATAL:
109  display = g_strdup_printf(Q_("%s - FATAL: %s\n%c"), log_domain, str, '\0');
110  g_print("%s\n", display);
111  /* exit(log_level); */
112  break;
113 
114  case G_LOG_LEVEL_ERROR:
115  display = g_strdup_printf(Q_("%s - ERROR: %s\n%c"), log_domain, str, '\0');
116  g_print("%s\n", display);
117  /* exit(log_level); */
118  break;
119 
120  case G_LOG_LEVEL_CRITICAL:
121  display = g_strdup_printf(Q_("%s - CRITICAL: %s\n%c"), log_domain, str, '\0');
122  break;
123 
124  case G_LOG_LEVEL_WARNING:
125  display = g_strdup_printf(Q_("%s - WARNING: %s\n%c"), log_domain, str, '\0');
126  break;
127 
128  case G_LOG_LEVEL_MESSAGE:
129  display = g_strdup_printf(Q_("%s - MESSAGE: %s\n%c"), log_domain, str, '\0');
130  break;
131 
132  case G_LOG_LEVEL_INFO:
133  display = g_strdup_printf(Q_("%s - INFO: %s\n%c"), log_domain, str, '\0');
134  break;
135 
136  case G_LOG_LEVEL_DEBUG:
137  display = g_strdup_printf(Q_("%s - DEBUG: %s\n%c"), log_domain, str, '\0');
138  break;
139 
140  case G_LOG_LEVEL_MASK: /* To avoid a compilation warning */
141  break;
142  }
143 
144  g_print("%s", display);
145 
146  /* inserting text in the textview */
147  tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(logw_textview)));
148 
149  gtk_text_buffer_get_end_iter(tb, &iStart);
150  gtk_text_buffer_insert(tb, &iStart, display, -1);
151 
152  /* scrolling down */
153  scroll_down_textview(main_struct);
154 
155  g_free(str);
156  g_free(display);
157 }
158 
159 
160 /**
161  * Scrolling down to the new line at the end of the textview
162  * @param main_struct : main structure
163  */
164 static void scroll_down_textview(heraia_struct_t *main_struct)
165 {
166  GtkTextView *logw_textview = NULL;
167  GtkTextBuffer *tb = NULL;
168  GtkTextIter end;
169  GtkTextMark *mark = NULL;
170 
171  logw_textview = GTK_TEXT_VIEW(heraia_get_widget(main_struct->xmls->main, "logw_textview"));
172  tb = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(logw_textview)));
173 
174  gtk_text_buffer_get_end_iter(tb, &end);
175  gtk_text_iter_set_line_offset(&end, 0);
176  mark = gtk_text_buffer_get_mark(tb, "scroll");
177  gtk_text_buffer_move_mark(tb, mark, &end);
178  gtk_text_view_scroll_mark_onscreen(logw_textview, mark);
179 }
180 
181 
182 /**
183  * @fn log_message(heraia_struct_t *main_struct, GLogLevelFlags log_level, const char *format, ...)
184  * A function that helps logging a message a the specified level. A wrapper to
185  * my_log function log_domain is defined by HERAIA_LOG_DOMAIN
186  * @param main_struct : main structure
187  * @param log_level : A string that may be either G_LOG_FLAG_RECURSION,
188  * G_LOG_FLAG_FATAL, G_LOG_LEVEL_ERROR, G_LOG_LEVEL_CRITICAL,
189  * G_LOG_LEVEL_WARNING, G_LOG_LEVEL_MESSAGE, G_LOG_LEVEL_INFO,
190  * G_LOG_LEVEL_DEBUG
191  * @param format : a printf style format
192  * @param ... : va_list to fill the format.
193  * @todo may be include the hability to choose a different log domain ?
194  */
195 void log_message(heraia_struct_t *main_struct, GLogLevelFlags log_level, const char *format, ...)
196 {
197 
198 #if LOGOUTPUT == 1 /* Logging things only if LOGOUTPUT has a value of 1 (use --disable-logoutput in ./configure to change this) */
199  va_list args;
200  gchar *str = NULL;
201  gchar *str_time = NULL;
202  gchar *str_time_utf8 = NULL;
203  gchar *str_utf8 = NULL;
204  GTimeVal *time = NULL;
205  GError *err = NULL;
206 
207  if (!(main_struct->debug == FALSE && log_level == G_LOG_LEVEL_DEBUG))
208  {
209  g_return_if_fail(format != NULL);
210 
211  va_start(args, format);
212  str = g_strdup_vprintf(format, args);
213  va_end(args);
214  str_utf8 = g_locale_to_utf8(str, -1, NULL, NULL, &err);
215 
216  time = (GTimeVal *) g_malloc0 (sizeof(GTimeVal));
217  g_get_current_time(time);
218  str_time = g_time_val_to_iso8601(time);
219  str_time_utf8 = g_locale_to_utf8(str_time, -1, NULL, NULL, &err);
220 
221 
222  if (str_utf8)
223  {
224  if (str_time_utf8)
225  {
226  my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time_utf8, str_utf8, '\0');
227  }
228  else
229  {
230  my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time, str_utf8, '\0');
231  }
232  }
233  else
234  {
235  if (str_time_utf8)
236  {
237  my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time_utf8, str, '\0');
238  }
239  else
240  {
241  my_log(main_struct, HERAIA_LOG_DOMAIN, log_level, "%s - %s%c", str_time, str, '\0');
242  }
243  }
244 
245  g_free(time);
246  g_free(str);
247  g_free(str_time);
248  g_free(str_time_utf8);
249  g_free(str_utf8);
250  }
251 
252 #endif /* LOGOUTPUT */
253 }
254 
255 
256 /**
257  * @fn mw_cmi_show_logw_toggle(GtkWidget *widget, gpointer data)
258  * The Check menu item for the Log window
259  * @param widget : the widget that issued the signal (here the log check menu
260  * item
261  * @param data : user data, MUST be main_struct main structure
262  */
263 void mw_cmi_show_logw_toggle(GtkWidget *widget, gpointer data)
264 {
265  heraia_struct_t *main_struct = (heraia_struct_t *) data;
266  GtkWidget *cmi = NULL;
267  gboolean checked = FALSE;
268  GtkWidget *log_dialog = NULL;
269 
270  log_dialog = heraia_get_widget(main_struct->xmls->main, "log_window");
271 
272  cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw");
273  checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(cmi));
274 
275  if (checked == TRUE)
276  {
277  scroll_down_textview(main_struct);
278  move_and_show_dialog_box(log_dialog, main_struct->win_prop->log_box);
279  }
280  else
281  {
282  record_and_hide_dialog_box(log_dialog, main_struct->win_prop->log_box);
283  }
284 }
285 
286 
287 /******************************** The Signals *********************************/
288 
289 /**
290  * @fn gboolean delete_log_window_event(GtkWidget *widget, GdkEvent *event, gpointer data )
291  * Closing the window
292  * @param widget : calling widget
293  * @param event : event associated (may be NULL as we don't use this here)
294  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
295  * @return Always returns TRUE in order to propagate the signal
296  */
297 static gboolean delete_log_window_event(GtkWidget *widget, GdkEvent *event, gpointer data )
298 {
299  logw_close_clicked(widget, data);
300 
301  return TRUE;
302 }
303 
304 
305 /**
306  * @fn void destroy_log_window(GtkWidget *widget, GdkEvent *event, gpointer data)
307  * When the window is destroyed (Gtk's doc says that we may never get there)
308  * @param widget : calling widget
309  * @param event : event associated (may be NULL as we don't use this here)
310  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
311 */
312 static void destroy_log_window(GtkWidget *widget, GdkEvent *event, gpointer data)
313 {
314  logw_close_clicked(widget, data);
315 }
316 
317 
318 /**
319  * @fn void logw_close_clicked(GtkWidget *widget, gpointer data)
320  * Close button is clicked
321  * @param widget : calling widget
322  * @param data : MUST be heraia_struct_t *main_struct main structure and not NULL
323  */
324 static void logw_close_clicked(GtkWidget *widget, gpointer data)
325 {
326  heraia_struct_t *main_struct = (heraia_struct_t *) data;
327  GtkWidget *cmi = NULL;
328  GtkWidget *log_dialog = NULL;
329 
330  if (main_struct != NULL && main_struct->xmls != NULL && main_struct->xmls->main != NULL)
331  {
332  log_dialog = heraia_get_widget(main_struct->xmls->main, "log_window");
333  record_and_hide_dialog_box(log_dialog, main_struct->win_prop->log_box);
334 
335  cmi = heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw");
336  gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(cmi), FALSE); /* This emits the signals that calls mw_cmi_show_logw_toggle function */
337  }
338 }
339 
340 
341 /**
342  * @fn void log_window_connect_signals(heraia_struct_t *main_struct)
343  * Connecting the window signals to the right functions
344  * @param main_struct : main structure
345  */
347 {
348 
349  if (main_struct != NULL && main_struct->xmls != NULL && main_struct->xmls->main != NULL)
350  {
351 
352  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "log_window")), "delete_event",
353  G_CALLBACK(delete_log_window_event), main_struct);
354 
355  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "log_window")), "destroy",
356  G_CALLBACK(destroy_log_window), main_struct);
357 
358  /* Close Button */
359  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "logw_close_b")), "clicked",
360  G_CALLBACK(logw_close_clicked), main_struct);
361 
362  /* the toogle button */
363  g_signal_connect(G_OBJECT(heraia_get_widget(main_struct->xmls->main, "mw_cmi_show_logw")), "toggled",
364  G_CALLBACK(mw_cmi_show_logw_toggle), main_struct);
365  }
366 }
367 /******************************** End Signals *********************************/
368 
369 
370 /**
371  * @fn log_window_init_interface(heraia_struct_t *main_struct)
372  * Inits the log window interface
373  * Called once at init time
374  * @param main_struct : main structure
375  */
377 {
378  GtkTextView *logw_textview = NULL;
379  GtkTextBuffer *tb = NULL;
380  GtkTextIter iStart;
381 
382 
383  if (main_struct != NULL)
384  {
385  /* Connecting signals */
386  log_window_connect_signals(main_struct);
387 
388  /* Creating a "scroll" mark on the textview */
389  if (main_struct->xmls != NULL && main_struct->xmls->main != NULL)
390  {
391  logw_textview = GTK_TEXT_VIEW(heraia_get_widget(main_struct->xmls->main, "logw_textview"));
392  tb = gtk_text_view_get_buffer(logw_textview);
393  gtk_text_buffer_get_end_iter(tb, &iStart);
394  gtk_text_buffer_create_mark(tb, "scroll", &iStart, TRUE);
395  }
396  }
397 }
static void destroy_log_window(GtkWidget *widget, GdkEvent *event, gpointer data)
When the window is destroyed (Gtk's doc says that we may never get there)
Definition: log.c:312
This is the main structure.
Definition: libheraia.h:332
#define HERAIA_LOG_DOMAIN
Defines heraia log domain (the one printed out on the logging window)
Definition: log.h:34
static void log_window_connect_signals(heraia_struct_t *main_struct)
Connecting the window signals to the right functions.
Definition: log.c:346
void print_message(const char *format,...)
Prints a message to stdout.
Definition: log.c:44
void record_and_hide_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
Record position and hide a dialog box.
Definition: heraia_ui.c:314
all_window_prop_t * win_prop
Keeps window properties.
Definition: libheraia.h:342
void log_message(heraia_struct_t *main_struct, GLogLevelFlags log_level, const char *format,...)
A function that helps logging a message a the specified level.
Definition: log.c:195
static void logw_close_clicked(GtkWidget *widget, gpointer data)
Close button is clicked.
Definition: log.c:324
xml_t * xmls
All the xmls used in the program, loaded at running time.
Definition: libheraia.h:337
gboolean debug
Used to tell the program wether we want to display debug messages or not.
Definition: libheraia.h:334
static void my_log(heraia_struct_t *main_struct, gchar *log_domain, GLogLevelFlags log_level, const char *format,...)
A function that allow me to printy things on stdout and in th log window.
Definition: log.c:87
void mw_cmi_show_logw_toggle(GtkWidget *widget, gpointer data)
The Check menu item for the Log window.
Definition: log.c:263
GtkBuilder * main
the main interface xml description
Definition: libheraia.h:222
void move_and_show_dialog_box(GtkWidget *dialog_box, window_prop_t *dialog_prop)
Move the dialog box to the wanted position, shows it and says it in the displayed prop...
Definition: heraia_ui.c:193
void log_window_init_interface(heraia_struct_t *main_struct)
Inits the log window interface Called once at init time.
Definition: log.c:376
static void scroll_down_textview(heraia_struct_t *main_struct)
Scrolling down to the new line at the end of the textview.
Definition: log.c:164
window_prop_t * log_box
log window
Definition: libheraia.h:263
This file contains all the definitions and includes all other .h files.
GtkWidget * heraia_get_widget(GtkBuilder *xml, gchar *widget_name)
This is a wrapper to the GtkBuilder xml get widget.
Definition: heraia_ui.c:2184
static gboolean delete_log_window_event(GtkWidget *widget, GdkEvent *event, gpointer data)
Closing the window.
Definition: log.c:297