2 * log.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2008-2012 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
5 * Copyright 2008-2012 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 * Logging functions and the debug messages window.
38 static GString
*log_buffer
= NULL
;
39 static GtkTextBuffer
*dialog_textbuffer
= NULL
;
43 DIALOG_RESPONSE_CLEAR
= 1
47 static void update_dialog(void)
49 if (dialog_textbuffer
!= NULL
)
52 GtkTextView
*textview
= g_object_get_data(G_OBJECT(dialog_textbuffer
), "textview");
54 gtk_text_buffer_set_text(dialog_textbuffer
, log_buffer
->str
, log_buffer
->len
);
55 /* scroll to the end of the messages as this might be most interesting */
56 mark
= gtk_text_buffer_get_insert(dialog_textbuffer
);
57 gtk_text_view_scroll_to_mark(textview
, mark
, 0.0, FALSE
, 0.0, 0.0);
62 /* Geany's main debug/log function, declared in geany.h */
63 void geany_debug(gchar
const *format
, ...)
66 va_start(args
, format
);
67 g_logv(G_LOG_DOMAIN
, G_LOG_LEVEL_INFO
, format
, args
);
72 static void handler_print(const gchar
*msg
)
75 if (G_LIKELY(log_buffer
!= NULL
))
77 g_string_append_printf(log_buffer
, "%s\n", msg
);
83 static void handler_printerr(const gchar
*msg
)
85 fprintf(stderr
, "%s\n", msg
);
86 if (G_LIKELY(log_buffer
!= NULL
))
88 g_string_append_printf(log_buffer
, "%s\n", msg
);
94 static const gchar
*get_log_prefix(GLogLevelFlags log_level
)
96 switch (log_level
& G_LOG_LEVEL_MASK
)
98 case G_LOG_LEVEL_ERROR
:
100 case G_LOG_LEVEL_CRITICAL
:
102 case G_LOG_LEVEL_WARNING
:
104 case G_LOG_LEVEL_MESSAGE
:
106 case G_LOG_LEVEL_INFO
:
108 case G_LOG_LEVEL_DEBUG
:
115 static void handler_log(const gchar
*domain
, GLogLevelFlags level
, const gchar
*msg
, gpointer data
)
119 if (G_LIKELY(app
!= NULL
&& app
->debug_mode
) ||
120 ! ((G_LOG_LEVEL_DEBUG
| G_LOG_LEVEL_INFO
| G_LOG_LEVEL_MESSAGE
) & level
))
123 /* On Windows g_log_default_handler() is not enough, we need to print it
124 * explicitly on stderr for the console window */
125 /** TODO this can be removed if/when we remove the console window on Windows */
127 fprintf(stderr
, "%s: %s\n", domain
, msg
);
129 fprintf(stderr
, "%s\n", msg
);
131 /* print the message as usual on stdout/stderr */
132 g_log_default_handler(domain
, level
, msg
, data
);
136 time_str
= utils_get_current_time_string();
138 g_string_append_printf(log_buffer
, "%s: %s %s: %s\n", time_str
, domain
,
139 get_log_prefix(level
), msg
);
147 void log_handlers_init(void)
149 log_buffer
= g_string_sized_new(2048);
151 g_set_print_handler(handler_print
);
152 g_set_printerr_handler(handler_printerr
);
153 g_log_set_default_handler(handler_log
, NULL
);
157 static void on_dialog_response(GtkDialog
*dialog
, gint response
, gpointer user_data
)
159 if (response
== DIALOG_RESPONSE_CLEAR
)
161 GtkTextIter start_iter
, end_iter
;
163 gtk_text_buffer_get_start_iter(dialog_textbuffer
, &start_iter
);
164 gtk_text_buffer_get_end_iter(dialog_textbuffer
, &end_iter
);
165 gtk_text_buffer_delete(dialog_textbuffer
, &start_iter
, &end_iter
);
167 g_string_erase(log_buffer
, 0, -1);
171 gtk_widget_destroy(GTK_WIDGET(dialog
));
172 dialog_textbuffer
= NULL
;
177 void log_show_debug_messages_dialog(void)
179 GtkWidget
*dialog
, *textview
, *vbox
, *swin
;
181 dialog
= gtk_dialog_new_with_buttons(_("Debug Messages"), GTK_WINDOW(main_widgets
.window
),
182 GTK_DIALOG_DESTROY_WITH_PARENT
,
183 _("Cl_ear"), DIALOG_RESPONSE_CLEAR
,
184 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
, NULL
);
185 vbox
= ui_dialog_vbox_new(GTK_DIALOG(dialog
));
186 gtk_box_set_spacing(GTK_BOX(vbox
), 6);
187 gtk_widget_set_name(dialog
, "GeanyDialog");
189 gtk_window_set_default_size(GTK_WINDOW(dialog
), 550, 300);
190 gtk_dialog_set_default_response(GTK_DIALOG(dialog
), GTK_RESPONSE_CLOSE
);
192 textview
= gtk_text_view_new();
193 dialog_textbuffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview
));
194 g_object_set_data(G_OBJECT(dialog_textbuffer
), "textview", textview
);
195 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview
), FALSE
);
196 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview
), FALSE
);
197 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview
), GTK_WRAP_WORD_CHAR
);
199 swin
= gtk_scrolled_window_new(NULL
, NULL
);
200 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin
),
201 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
202 gtk_container_add(GTK_CONTAINER(swin
), textview
);
204 gtk_box_pack_start(GTK_BOX(vbox
), swin
, TRUE
, TRUE
, 0);
206 g_signal_connect(dialog
, "response", G_CALLBACK(on_dialog_response
), textview
);
207 gtk_widget_show_all(dialog
);
209 update_dialog(); /* set text after showing the window, to not scroll an unrealized textview */
213 void log_finalize(void)
215 g_log_set_default_handler(g_log_default_handler
, NULL
);
217 g_string_free(log_buffer
, TRUE
);