Updated copyright text/header in most source files.
[geda-gaf/peter-b.git] / gschem / src / x_log.c
blob747b7b836ff5a319004defe159c6f77278d6df8e
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
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
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 #include <config.h>
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #ifdef HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #ifdef HAVE_FCNTL_H
32 #include <fcntl.h>
33 #endif
34 #ifdef HAVE_STRING_H
35 #include <string.h>
36 #endif
38 #include "gschem.h"
40 #ifdef HAVE_LIBDMALLOC
41 #include <dmalloc.h>
42 #endif
44 static void x_log_callback_response (GtkDialog *dialog,
45 gint arg1,
46 gpointer user_data);
47 static void log_message (Log *log,
48 const gchar *message,
49 const gchar *style);
51 static void log_class_init (LogClass *class);
52 static void log_init (Log *log);
54 static GtkWidget *log_dialog = NULL;
56 /*! \todo Finish function documentation!!!
57 * \brief
58 * \par Function Description
61 void x_log_open ()
63 if (log_dialog == NULL) {
64 gchar *contents;
66 log_dialog = GTK_WIDGET (g_object_new (TYPE_LOG,
67 /* GschemDialog */
68 "settings-name", "log",
69 /* "toplevel", TOPEVEL * */
70 NULL));
72 g_signal_connect (log_dialog,
73 "response",
74 G_CALLBACK (x_log_callback_response),
75 NULL);
77 /* make it read the content of the current log file */
78 /* and add its contents to the dialog */
79 contents = s_log_read ();
81 /* s_log_read can return NULL if the log file cannot be written to */
82 if (contents == NULL)
84 return;
87 log_message (LOG (log_dialog), contents, "old");
88 g_free (contents);
90 x_log_update_func = x_log_message;
92 if( auto_place_mode )
93 gtk_widget_set_uposition( log_dialog, 10, 10);
94 gtk_widget_show (log_dialog);
95 } else {
96 g_assert (IS_LOG (log_dialog));
97 gtk_window_present ((GtkWindow*)log_dialog);
102 /*! \todo Finish function documentation!!!
103 * \brief
104 * \par Function Description
107 void x_log_close ()
109 if (log_dialog) {
110 g_assert (IS_LOG (log_dialog));
111 gtk_widget_destroy (log_dialog);
112 x_log_update_func = NULL;
113 log_dialog = NULL;
118 /*! \todo Finish function documentation!!!
119 * \brief
120 * \par Function Description
123 void x_log_message (const gchar *log_domain, GLogLevelFlags log_level,
124 const gchar *message)
126 gchar *style;
127 g_return_if_fail (log_dialog != NULL);
129 if (log_level & (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_ERROR)) {
130 style = "critical";
131 } else if (log_level & G_LOG_LEVEL_WARNING) {
132 style = "warning";
133 } else {
134 style = "message";
137 log_message (LOG(log_dialog), message, style);
140 /*! \todo Finish function documentation!!!
141 * \brief
142 * \par Function Description
145 static void x_log_callback_response (GtkDialog *dialog,
146 gint arg1,
147 gpointer user_data)
149 switch (arg1) {
150 case GTK_RESPONSE_DELETE_EVENT:
151 case LOG_RESPONSE_CLOSE:
152 g_assert (GTK_WIDGET (dialog) == log_dialog);
153 x_log_close ();
154 break;
155 default:
156 g_assert_not_reached ();
161 /*! \todo Finish function documentation!!!
162 * \brief
163 * \par Function Description
166 static void log_message (Log *log, const gchar *message,
167 const gchar *style)
169 GtkTextBuffer *buffer;
170 GtkTextIter iter;
171 GtkTextMark *mark;
173 g_return_if_fail (IS_LOG (log));
175 buffer = gtk_text_view_get_buffer (log->textview);
176 gtk_text_buffer_get_end_iter (buffer, &iter);
177 /* Apply the "plain" tag before the level-specific tag in order to
178 * reset the formatting */
180 if (g_utf8_validate (message, -1, NULL)) {
181 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, message, -1,
182 "plain", style, NULL);
183 } else {
184 /* If UTF-8 wasn't valid (due to a system locale encoded filename or
185 * other string being included by mistake), log a warning, and print
186 * the original message to stderr, where it may be partly intelligible */
187 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
188 _("** Invalid UTF-8 in log message. See stderr or gschem.log.\n"),
189 -1, "plain", style, NULL);
190 fprintf (stderr, "%s", message);
193 mark = gtk_text_buffer_create_mark(buffer, NULL, &iter, FALSE);
194 gtk_text_view_scroll_to_mark (log->textview, mark, 0, TRUE, 0, 1);
195 gtk_text_buffer_delete_mark (buffer, mark);
198 /*! \todo Finish function documentation!!!
199 * \brief
200 * \par Function Description
203 GType log_get_type ()
205 static GType log_type = 0;
207 if (!log_type) {
208 static const GTypeInfo log_info = {
209 sizeof(LogClass),
210 NULL, /* base_init */
211 NULL, /* base_finalize */
212 (GClassInitFunc) log_class_init,
213 NULL, /* class_finalize */
214 NULL, /* class_data */
215 sizeof(Log),
216 0, /* n_preallocs */
217 (GInstanceInitFunc) log_init,
220 log_type = g_type_register_static (GSCHEM_TYPE_DIALOG,
221 "Log",
222 &log_info, 0);
225 return log_type;
228 /*! \todo Finish function documentation!!!
229 * \brief
230 * \par Function Description
233 static void log_class_init (LogClass *klass)
235 /* GObjectClass *gobject_class = G_OBJECT_CLASS (klass); */
239 /*! \todo Finish function documentation!!!
240 * \brief
241 * \par Function Description
244 static void log_init (Log *log)
246 GtkWidget *scrolled_win, *text_view;
247 GtkTextBuffer *text_buffer;
248 GtkTextMark *mark;
250 /* dialog initialization */
251 g_object_set (G_OBJECT (log),
252 /* GtkContainer */
253 "border-width", 0,
254 /* GtkWindow */
255 "type", GTK_WINDOW_TOPLEVEL,
256 "title", _("Status"),
257 "default-width", 600,
258 "default-height", 200,
259 "modal", FALSE,
260 "window-position", GTK_WIN_POS_NONE,
261 "type-hint", GDK_WINDOW_TYPE_HINT_NORMAL,
262 /* GtkDialog */
263 "has-separator", TRUE,
264 NULL);
266 /* create a scrolled window for the textview */
267 scrolled_win = GTK_WIDGET (
268 g_object_new (GTK_TYPE_SCROLLED_WINDOW,
269 /* GtkContainer */
270 "border-width", 5,
271 /* GtkScrolledWindow */
272 "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
273 "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
274 "shadow-type", GTK_SHADOW_ETCHED_IN,
275 NULL));
276 /* create the text buffer */
277 text_buffer = GTK_TEXT_BUFFER (g_object_new (GTK_TYPE_TEXT_BUFFER,
278 NULL));
280 /* Add some tags for highlighting log messages to the buffer */
281 gtk_text_buffer_create_tag (text_buffer, "plain",
282 "foreground", "black",
283 "foreground-set", TRUE,
284 "weight", PANGO_WEIGHT_NORMAL,
285 "weight-set", TRUE,
286 NULL);
287 /* The default "message" style is plain */
288 gtk_text_buffer_create_tag (text_buffer, "message", NULL);
289 /* "old" messages are in dark grey */
290 gtk_text_buffer_create_tag (text_buffer, "old",
291 "foreground", "#404040",
292 "foreground-set", TRUE,
293 NULL);
294 /* "warning" messages are printed in red */
295 gtk_text_buffer_create_tag (text_buffer, "warning",
296 "foreground", "red",
297 "foreground-set", TRUE,
298 NULL);
299 /* "critical" messages are bold red */
300 gtk_text_buffer_create_tag (text_buffer, "critical",
301 "foreground", "red",
302 "foreground-set", TRUE,
303 "weight", PANGO_WEIGHT_BOLD,
304 "weight-set", TRUE,
305 NULL);
307 /* create the text view and attach the buffer to it */
308 text_view = GTK_WIDGET (g_object_new (GTK_TYPE_TEXT_VIEW,
309 /* GtkTextView */
310 /* unknown property in GTK 2.2, use gtk_text_view_set_buffer() instead */
311 /* "buffer", text_buffer, */
312 "editable", FALSE,
313 NULL));
314 gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), text_buffer);
316 /* add the text view to the scrolled window */
317 gtk_container_add (GTK_CONTAINER (scrolled_win), text_view);
318 /* set textview of log */
319 log->textview = GTK_TEXT_VIEW (text_view);
321 /* add the scrolled window to the dialog vbox */
322 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (log)->vbox), scrolled_win,
323 TRUE, TRUE, 0);
324 gtk_widget_show_all (scrolled_win);
326 /* now add the close button to the action area */
327 gtk_dialog_add_button (GTK_DIALOG (log),
328 GTK_STOCK_CLOSE, LOG_RESPONSE_CLOSE);
330 /* scroll to the end of the buffer */
331 mark = gtk_text_buffer_get_insert (text_buffer);
332 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view), mark, 0.0, TRUE, 0.0, 1.0);