2 * log.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2008 The Geany contributors
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 * Logging functions and the debug messages window.
42 static GString
*log_buffer
= NULL
;
43 static GtkTextBuffer
*dialog_textbuffer
= NULL
;
47 DIALOG_RESPONSE_CLEAR
= 1
51 static void update_dialog(void)
53 if (dialog_textbuffer
!= NULL
)
56 GtkTextView
*textview
= g_object_get_data(G_OBJECT(dialog_textbuffer
), "textview");
58 gtk_text_buffer_set_text(dialog_textbuffer
, log_buffer
->str
, log_buffer
->len
);
59 /* scroll to the end of the messages as this might be most interesting */
60 mark
= gtk_text_buffer_get_insert(dialog_textbuffer
);
61 gtk_text_view_scroll_to_mark(textview
, mark
, 0.0, FALSE
, 0.0, 0.0);
66 /* Geany's main debug/log function, declared in geany.h */
67 void geany_debug(gchar
const *format
, ...)
70 va_start(args
, format
);
71 g_logv(G_LOG_DOMAIN
, G_LOG_LEVEL_INFO
, format
, args
);
76 static void handler_print(const gchar
*msg
)
79 if (G_LIKELY(log_buffer
!= NULL
))
81 g_string_append_printf(log_buffer
, "%s", msg
);
87 static void handler_printerr(const gchar
*msg
)
89 fprintf(stderr
, "%s", msg
);
90 if (G_LIKELY(log_buffer
!= NULL
))
92 g_string_append_printf(log_buffer
, "%s", msg
);
98 static const gchar
*get_log_prefix(GLogLevelFlags log_level
)
100 switch (log_level
& G_LOG_LEVEL_MASK
)
102 case G_LOG_LEVEL_ERROR
:
104 case G_LOG_LEVEL_CRITICAL
:
106 case G_LOG_LEVEL_WARNING
:
108 case G_LOG_LEVEL_MESSAGE
:
110 case G_LOG_LEVEL_INFO
:
112 case G_LOG_LEVEL_DEBUG
:
119 static void handler_log(const gchar
*domain
, GLogLevelFlags level
, const gchar
*msg
, gpointer data
)
123 if (G_LIKELY(app
!= NULL
&& app
->debug_mode
) ||
124 ! ((G_LOG_LEVEL_DEBUG
| G_LOG_LEVEL_INFO
| G_LOG_LEVEL_MESSAGE
) & level
))
127 /* On Windows g_log_default_handler() is not enough, we need to print it
128 * explicitly on stderr for the console window */
129 /** TODO this can be removed if/when we remove the console window on Windows */
131 fprintf(stderr
, "%s: %s\n", domain
, msg
);
133 fprintf(stderr
, "%s\n", msg
);
135 /* print the message as usual on stdout/stderr */
136 g_log_default_handler(domain
, level
, msg
, data
);
140 time_str
= utils_get_current_time_string(TRUE
);
142 g_string_append_printf(log_buffer
, "%s: %s %s: %s\n", time_str
, domain
,
143 get_log_prefix(level
), msg
);
151 void log_handlers_init(void)
153 log_buffer
= g_string_sized_new(2048);
155 g_set_print_handler(handler_print
);
156 g_set_printerr_handler(handler_printerr
);
157 g_log_set_default_handler(handler_log
, NULL
);
161 static void on_dialog_response(GtkDialog
*dialog
, gint response
, gpointer user_data
)
163 if (response
== DIALOG_RESPONSE_CLEAR
)
165 GtkTextIter start_iter
, end_iter
;
167 gtk_text_buffer_get_start_iter(dialog_textbuffer
, &start_iter
);
168 gtk_text_buffer_get_end_iter(dialog_textbuffer
, &end_iter
);
169 gtk_text_buffer_delete(dialog_textbuffer
, &start_iter
, &end_iter
);
171 g_string_erase(log_buffer
, 0, -1);
175 gtk_widget_destroy(GTK_WIDGET(dialog
));
176 dialog_textbuffer
= NULL
;
181 void log_show_debug_messages_dialog(void)
183 GtkWidget
*dialog
, *textview
, *vbox
, *swin
;
185 dialog
= gtk_dialog_new_with_buttons(_("Debug Messages"), GTK_WINDOW(main_widgets
.window
),
186 GTK_DIALOG_DESTROY_WITH_PARENT
,
187 _("Cl_ear"), DIALOG_RESPONSE_CLEAR
,
188 GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
, NULL
);
189 vbox
= ui_dialog_vbox_new(GTK_DIALOG(dialog
));
190 gtk_box_set_spacing(GTK_BOX(vbox
), 6);
191 gtk_widget_set_name(dialog
, "GeanyDialog");
193 gtk_window_set_default_size(GTK_WINDOW(dialog
), 550, 300);
194 gtk_dialog_set_default_response(GTK_DIALOG(dialog
), GTK_RESPONSE_CLOSE
);
196 textview
= gtk_text_view_new();
197 dialog_textbuffer
= gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview
));
198 g_object_set_data(G_OBJECT(dialog_textbuffer
), "textview", textview
);
199 gtk_text_view_set_editable(GTK_TEXT_VIEW(textview
), FALSE
);
200 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview
), FALSE
);
201 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview
), GTK_WRAP_WORD_CHAR
);
203 swin
= gtk_scrolled_window_new(NULL
, NULL
);
204 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(swin
), GTK_SHADOW_IN
);
205 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swin
),
206 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
207 gtk_container_add(GTK_CONTAINER(swin
), textview
);
209 gtk_box_pack_start(GTK_BOX(vbox
), swin
, TRUE
, TRUE
, 0);
211 g_signal_connect(dialog
, "response", G_CALLBACK(on_dialog_response
), textview
);
212 gtk_widget_show_all(dialog
);
214 update_dialog(); /* set text after showing the window, to not scroll an unrealized textview */
218 void log_finalize(void)
220 g_log_set_default_handler(g_log_default_handler
, NULL
);
222 g_string_free(log_buffer
, TRUE
);