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.
37 #include "gtkcompat.h"
43 static GString
*log_buffer
= NULL
;
44 static GtkTextBuffer
*dialog_textbuffer
= NULL
;
48 DIALOG_RESPONSE_CLEAR
= 1
52 static void update_dialog(void)
54 if (dialog_textbuffer
!= NULL
)
57 GtkTextView
*textview
= g_object_get_data(G_OBJECT(dialog_textbuffer
), "textview");
59 gtk_text_buffer_set_text(dialog_textbuffer
, log_buffer
->str
, log_buffer
->len
);
60 /* scroll to the end of the messages as this might be most interesting */
61 mark
= gtk_text_buffer_get_insert(dialog_textbuffer
);
62 gtk_text_view_scroll_to_mark(textview
, mark
, 0.0, FALSE
, 0.0, 0.0);
67 /* Geany's main debug/log function, declared in geany.h */
68 void geany_debug(gchar
const *format
, ...)
71 va_start(args
, format
);
72 g_logv(G_LOG_DOMAIN
, G_LOG_LEVEL_INFO
, format
, args
);
77 static void handler_print(const gchar
*msg
)
80 if (G_LIKELY(log_buffer
!= NULL
))
82 g_string_append_printf(log_buffer
, "%s\n", msg
);
88 static void handler_printerr(const gchar
*msg
)
90 fprintf(stderr
, "%s\n", msg
);
91 if (G_LIKELY(log_buffer
!= NULL
))
93 g_string_append_printf(log_buffer
, "%s\n", msg
);
99 static const gchar
*get_log_prefix(GLogLevelFlags log_level
)
101 switch (log_level
& G_LOG_LEVEL_MASK
)
103 case G_LOG_LEVEL_ERROR
:
105 case G_LOG_LEVEL_CRITICAL
:
107 case G_LOG_LEVEL_WARNING
:
109 case G_LOG_LEVEL_MESSAGE
:
111 case G_LOG_LEVEL_INFO
:
113 case G_LOG_LEVEL_DEBUG
:
120 static void handler_log(const gchar
*domain
, GLogLevelFlags level
, const gchar
*msg
, gpointer data
)
124 if (G_LIKELY(app
!= NULL
&& app
->debug_mode
) ||
125 ! ((G_LOG_LEVEL_DEBUG
| G_LOG_LEVEL_INFO
| G_LOG_LEVEL_MESSAGE
) & level
))
128 /* On Windows g_log_default_handler() is not enough, we need to print it
129 * explicitly on stderr for the console window */
130 /** TODO this can be removed if/when we remove the console window on Windows */
132 fprintf(stderr
, "%s: %s\n", domain
, msg
);
134 fprintf(stderr
, "%s\n", msg
);
136 /* print the message as usual on stdout/stderr */
137 g_log_default_handler(domain
, level
, msg
, data
);
141 time_str
= utils_get_current_time_string();
143 g_string_append_printf(log_buffer
, "%s: %s %s: %s\n", time_str
, domain
,
144 get_log_prefix(level
), msg
);
152 void log_handlers_init(void)
154 log_buffer
= g_string_sized_new(2048);
156 g_set_print_handler(handler_print
);
157 g_set_printerr_handler(handler_printerr
);
158 g_log_set_default_handler(handler_log
, NULL
);
162 static void on_dialog_response(GtkDialog
*dialog
, gint response
, gpointer user_data
)
164 if (response
== DIALOG_RESPONSE_CLEAR
)
166 GtkTextIter start_iter
, end_iter
;
168 gtk_text_buffer_get_start_iter(dialog_textbuffer
, &start_iter
);
169 gtk_text_buffer_get_end_iter(dialog_textbuffer
, &end_iter
);
170 gtk_text_buffer_delete(dialog_textbuffer
, &start_iter
, &end_iter
);
172 g_string_erase(log_buffer
, 0, -1);
176 gtk_widget_destroy(GTK_WIDGET(dialog
));
177 dialog_textbuffer
= NULL
;
182 void log_show_debug_messages_dialog(void)
184 GtkWidget
*dialog
, *textview
, *vbox
, *swin
;
186 dialog
= gtk_dialog_new_with_buttons(_("Debug Messages"), GTK_WINDOW(main_widgets
.window
),
187 GTK_DIALOG_DESTROY_WITH_PARENT
,
188 _("Cl_ear"), DIALOG_RESPONSE_CLEAR
,
189 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
, NULL
);
190 vbox
= ui_dialog_vbox_new(GTK_DIALOG(dialog
));
191 gtk_box_set_spacing(GTK_BOX(vbox
), 6);
192 gtk_widget_set_name(dialog
, "GeanyDialog");
194 gtk_window_set_default_size(GTK_WINDOW(dialog
), 550, 300);
195 gtk_dialog_set_default_response(GTK_DIALOG(dialog
), GTK_RESPONSE_CLOSE
);
197 textview
= gtk_text_view_new();
198 dialog_textbuffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview
));
199 g_object_set_data(G_OBJECT(dialog_textbuffer
), "textview", textview
);
200 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview
), FALSE
);
201 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview
), FALSE
);
202 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview
), GTK_WRAP_WORD_CHAR
);
204 swin
= gtk_scrolled_window_new(NULL
, NULL
);
205 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin
), GTK_SHADOW_IN
);
206 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin
),
207 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
208 gtk_container_add(GTK_CONTAINER(swin
), textview
);
210 gtk_box_pack_start(GTK_BOX(vbox
), swin
, TRUE
, TRUE
, 0);
212 g_signal_connect(dialog
, "response", G_CALLBACK(on_dialog_response
), textview
);
213 gtk_widget_show_all(dialog
);
215 update_dialog(); /* set text after showing the window, to not scroll an unrealized textview */
219 void log_finalize(void)
221 g_log_set_default_handler(g_log_default_handler
, NULL
);
223 g_string_free(log_buffer
, TRUE
);