2 * log.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2008-2010 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
5 * Copyright 2008-2010 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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 * Logging functions and the debug messages window.
40 static GString
*log_buffer
= NULL
;
41 static GtkTextBuffer
*dialog_textbuffer
= NULL
;
45 DIALOG_RESPONSE_CLEAR
= 1
49 static void update_dialog(void)
51 if (dialog_textbuffer
!= NULL
)
54 GtkTextView
*textview
= g_object_get_data(G_OBJECT(dialog_textbuffer
), "textview");
56 gtk_text_buffer_set_text(dialog_textbuffer
, log_buffer
->str
, log_buffer
->len
);
57 /* scroll to the end of the messages as this might be most interesting */
58 mark
= gtk_text_buffer_get_insert(dialog_textbuffer
);
59 gtk_text_view_scroll_to_mark(textview
, mark
, 0.0, FALSE
, 0.0, 0.0);
64 /* Geany's main debug/log function, declared in geany.h */
65 void geany_debug(gchar
const *format
, ...)
68 va_start(args
, format
);
69 g_logv(G_LOG_DOMAIN
, G_LOG_LEVEL_INFO
, format
, args
);
74 static void handler_print(const gchar
*msg
)
77 if (G_LIKELY(log_buffer
!= NULL
))
79 g_string_append_printf(log_buffer
, "%s\n", msg
);
85 static void handler_printerr(const gchar
*msg
)
87 fprintf(stderr
, "%s\n", msg
);
88 if (G_LIKELY(log_buffer
!= NULL
))
90 g_string_append_printf(log_buffer
, "%s\n", msg
);
96 static const gchar
*get_log_prefix(GLogLevelFlags log_level
)
98 switch (log_level
& G_LOG_LEVEL_MASK
)
100 case G_LOG_LEVEL_ERROR
:
102 case G_LOG_LEVEL_CRITICAL
:
104 case G_LOG_LEVEL_WARNING
:
106 case G_LOG_LEVEL_MESSAGE
:
108 case G_LOG_LEVEL_INFO
:
110 case G_LOG_LEVEL_DEBUG
:
117 static void handler_log(const gchar
*domain
, GLogLevelFlags level
, const gchar
*msg
, gpointer data
)
121 if (G_LIKELY(app
!= NULL
) && app
->debug_mode
)
124 /* On Windows g_log_default_handler() is not enough, we need to print it
125 * explicitly on stderr for the console window */
126 /** TODO this can be removed if/when we remove the console window on Windows */
128 fprintf(stderr
, "%s: %s\n", domain
, msg
);
130 fprintf(stderr
, "%s\n", msg
);
132 /* print the message as usual on stdout/stderr */
133 g_log_default_handler(domain
, level
, msg
, data
);
137 time_str
= utils_get_current_time_string();
139 g_string_append_printf(log_buffer
, "%s: %s %s: %s\n", time_str
, domain
,
140 get_log_prefix(level
), msg
);
148 void log_handlers_init(void)
150 log_buffer
= g_string_sized_new(2048);
152 g_set_print_handler(handler_print
);
153 g_set_printerr_handler(handler_printerr
);
154 g_log_set_default_handler(handler_log
, NULL
);
158 static void on_dialog_response(GtkDialog
*dialog
, gint response
, gpointer user_data
)
160 if (response
== DIALOG_RESPONSE_CLEAR
)
162 GtkTextIter start_iter
, end_iter
;
164 gtk_text_buffer_get_start_iter(dialog_textbuffer
, &start_iter
);
165 gtk_text_buffer_get_end_iter(dialog_textbuffer
, &end_iter
);
166 gtk_text_buffer_delete(dialog_textbuffer
, &start_iter
, &end_iter
);
168 g_string_erase(log_buffer
, 0, -1);
172 gtk_widget_destroy(GTK_WIDGET(dialog
));
173 dialog_textbuffer
= NULL
;
178 void log_show_debug_messages_dialog(void)
180 GtkWidget
*dialog
, *textview
, *vbox
, *swin
;
182 dialog
= gtk_dialog_new_with_buttons(_("Debug Messages"), GTK_WINDOW(main_widgets
.window
),
183 GTK_DIALOG_DESTROY_WITH_PARENT
,
184 _("Cl_ear"), DIALOG_RESPONSE_CLEAR
,
185 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
, NULL
);
186 vbox
= ui_dialog_vbox_new(GTK_DIALOG(dialog
));
187 gtk_box_set_spacing(GTK_BOX(vbox
), 6);
188 gtk_widget_set_name(dialog
, "GeanyDialog");
190 gtk_window_set_default_size(GTK_WINDOW(dialog
), 550, 300);
191 gtk_dialog_set_default_response(GTK_DIALOG(dialog
), GTK_RESPONSE_CLOSE
);
193 textview
= gtk_text_view_new();
194 dialog_textbuffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview
));
195 g_object_set_data(G_OBJECT(dialog_textbuffer
), "textview", textview
);
196 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview
), FALSE
);
197 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview
), FALSE
);
198 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview
), GTK_WRAP_WORD_CHAR
);
200 swin
= gtk_scrolled_window_new(NULL
, NULL
);
201 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin
),
202 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
203 gtk_container_add(GTK_CONTAINER(swin
), textview
);
205 gtk_box_pack_start(GTK_BOX(vbox
), swin
, TRUE
, TRUE
, 0);
207 g_signal_connect(dialog
, "response", G_CALLBACK(on_dialog_response
), textview
);
208 gtk_widget_show_all(dialog
);
210 update_dialog(); /* set text after showing the window, to not scroll an unrealized textview */
214 void log_finalize(void)
216 g_log_set_default_handler(g_log_default_handler
, NULL
);
218 g_string_free(log_buffer
, TRUE
);