Statistics
| Revision:

root / src / logwindow.c @ 2164

History | View | Annotate | Download (7.1 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2005 Hiroyuki Yamamoto
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 */
19
20
#ifdef HAVE_CONFIG_H
21
#  include "config.h"
22
#endif
23
24
#include <glib.h>
25
#include <glib/gi18n.h>
26
#include <gdk/gdkkeysyms.h>
27
#include <gtk/gtkwidget.h>
28
#include <gtk/gtkwindow.h>
29
#include <gtk/gtksignal.h>
30
#include <gtk/gtkscrolledwindow.h>
31
#include <gtk/gtktextview.h>
32
#include <gtk/gtkstyle.h>
33
34
#include "logwindow.h"
35
#include "prefs_common.h"
36
#include "utils.h"
37
#include "gtkutils.h"
38
#include "codeconv.h"
39
40
#define TRIM_LINES        25
41
42
static LogWindow *logwindow;
43
44
static void log_window_print_func        (const gchar        *str);
45
static void log_window_message_func        (const gchar        *str);
46
static void log_window_warning_func        (const gchar        *str);
47
static void log_window_error_func        (const gchar        *str);
48
49
static void hide_cb                (GtkWidget        *widget,
50
                                 LogWindow        *logwin);
51
static gboolean key_pressed        (GtkWidget        *widget,
52
                                 GdkEventKey        *event,
53
                                 LogWindow        *logwin);
54
55
LogWindow *log_window_create(void)
56
{
57
        LogWindow *logwin;
58
        GtkWidget *window;
59
        GtkWidget *scrolledwin;
60
        GtkWidget *text;
61
        GtkTextBuffer *buffer;
62
        GtkTextIter iter;
63
64
        debug_print("Creating log window...\n");
65
        logwin = g_new0(LogWindow, 1);
66
67
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
68
        gtk_window_set_title(GTK_WINDOW(window), _("Protocol log"));
69
        gtk_window_set_wmclass(GTK_WINDOW(window), "log_window", "Sylpheed");
70
        gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
71
        gtk_widget_set_size_request(window, 520, 400);
72
        g_signal_connect(G_OBJECT(window), "delete_event",
73
                         G_CALLBACK(gtk_widget_hide_on_delete), NULL);
74
        g_signal_connect(G_OBJECT(window), "key_press_event",
75
                         G_CALLBACK(key_pressed), logwin);
76
        g_signal_connect(G_OBJECT(window), "hide",
77
                         G_CALLBACK(hide_cb), logwin);
78
        gtk_widget_realize(window);
79
80
        scrolledwin = gtk_scrolled_window_new(NULL, NULL);
81
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
82
                                       GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
83
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin),
84
                                            GTK_SHADOW_IN);
85
        gtk_container_add(GTK_CONTAINER(window), scrolledwin);
86
        gtk_widget_show(scrolledwin);
87
88
        text = gtk_text_view_new();
89
        gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
90
        gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
91
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
92
        gtk_text_buffer_get_start_iter(buffer, &iter);
93
        gtk_text_buffer_create_mark(buffer, "end", &iter, FALSE);
94
        gtk_container_add(GTK_CONTAINER(scrolledwin), text);
95
        gtk_widget_show(text);
96
97
        logwin->window = window;
98
        logwin->scrolledwin = scrolledwin;
99
        logwin->text = text;
100
        logwin->lines = 1;
101
102
        logwindow = logwin;
103
104
        return logwin;
105
}
106
107
void log_window_init(LogWindow *logwin)
108
{
109
        GtkTextBuffer *buffer;
110
        GdkColormap *colormap;
111
        GdkColor color[3] =
112
                {{0, 0, 0xafff, 0}, {0, 0xefff, 0, 0}, {0, 0xefff, 0, 0}};
113
        gboolean success[3];
114
        gint i;
115
116
        logwin->msg_color   = color[0];
117
        logwin->warn_color  = color[1];
118
        logwin->error_color = color[2];
119
120
        colormap = gdk_window_get_colormap(logwin->window->window);
121
        gdk_colormap_alloc_colors(colormap, color, 3, FALSE, TRUE, success);
122
123
        for (i = 0; i < 3; i++) {
124
                if (success[i] == FALSE) {
125
                        GtkStyle *style;
126
127
                        g_warning("LogWindow: color allocation failed\n");
128
                        style = gtk_widget_get_style(logwin->window);
129
                        logwin->msg_color = logwin->warn_color =
130
                        logwin->error_color = style->black;
131
                        break;
132
                }
133
        }
134
135
        buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(logwin->text));
136
        gtk_text_buffer_create_tag(buffer, "message",
137
                                   "foreground-gdk", &logwindow->msg_color,
138
                                   NULL);
139
        gtk_text_buffer_create_tag(buffer, "warn",
140
                                   "foreground-gdk", &logwindow->warn_color,
141
                                   NULL);
142
        gtk_text_buffer_create_tag(buffer, "error",
143
                                   "foreground-gdk", &logwindow->error_color,
144
                                   NULL);
145
146
        set_log_ui_func(log_window_print_func, log_window_message_func,
147
                        log_window_warning_func, log_window_error_func);
148
}
149
150
void log_window_show(LogWindow *logwin)
151
{
152
        GtkTextView *text = GTK_TEXT_VIEW(logwin->text);
153
        GtkTextBuffer *buffer;
154
        GtkTextMark *mark;
155
156
        buffer = gtk_text_view_get_buffer(text);
157
        mark = gtk_text_buffer_get_mark(buffer, "end");
158
        gtk_text_view_scroll_mark_onscreen(text, mark);
159
160
        gtk_window_present(GTK_WINDOW(logwin->window));
161
}
162
163
void log_window_append(const gchar *str, LogType type)
164
{
165
        GtkTextView *text;
166
        GtkTextBuffer *buffer;
167
        GtkTextIter iter;
168
        GdkColor *color = NULL;
169
        gchar *head = NULL;
170
        const gchar *tag;
171
        gint line_limit = prefs_common.logwin_line_limit;
172
173
        g_return_if_fail(logwindow != NULL);
174
175
        text = GTK_TEXT_VIEW(logwindow->text);
176
        buffer = gtk_text_view_get_buffer(text);
177
178
        if (line_limit > 0 && logwindow->lines >= line_limit) {
179
                GtkTextIter start, end;
180
181
                gtk_text_buffer_get_start_iter(buffer, &start);
182
                end = start;
183
                gtk_text_iter_forward_lines(&end, TRIM_LINES);
184
                gtk_text_buffer_delete(buffer, &start, &end);
185
                logwindow->lines = gtk_text_buffer_get_line_count(buffer);
186
        }
187
188
        switch (type) {
189
        case LOG_MSG:
190
                color = &logwindow->msg_color;
191
                tag = "message";
192
                head = "* ";
193
                break;
194
        case LOG_WARN:
195
                color = &logwindow->warn_color;
196
                tag = "warn";
197
                head = "** ";
198
                break;
199
        case LOG_ERROR:
200
                color = &logwindow->error_color;
201
                tag = "error";
202
                head = "*** ";
203
                break;
204
        default:
205
                tag = NULL;
206
                break;
207
        }
208
209
        gtk_text_buffer_get_end_iter(buffer, &iter);
210
211
        if (head)
212
                gtk_text_buffer_insert_with_tags_by_name
213
                        (buffer, &iter, head, -1, tag, NULL);
214
215
        if (!g_utf8_validate(str, -1, NULL)) {
216
                gchar *str_;
217
218
                str_ = conv_utf8todisp(str, NULL);
219
                if (str_) {
220
                        gtk_text_buffer_insert_with_tags_by_name
221
                                (buffer, &iter, str_, -1, tag, NULL);
222
                        g_free(str_);
223
                }
224
        } else {
225
                gtk_text_buffer_insert_with_tags_by_name
226
                        (buffer, &iter, str, -1, tag, NULL);
227
        }
228
229
        if (GTK_WIDGET_VISIBLE(text)) {
230
                GtkTextMark *mark;
231
                mark = gtk_text_buffer_get_mark(buffer, "end");
232
                gtk_text_view_scroll_mark_onscreen(text, mark);
233
        }
234
235
        logwindow->lines++;
236
}
237
238
static void log_window_print_func(const gchar *str)
239
{
240
        log_window_append(str, LOG_NORMAL);
241
}
242
243
static void log_window_message_func(const gchar *str)
244
{
245
        log_window_append(str, LOG_MSG);
246
}
247
248
static void log_window_warning_func(const gchar *str)
249
{
250
        log_window_append(str, LOG_WARN);
251
}
252
253
static void log_window_error_func(const gchar *str)
254
{
255
        log_window_append(str, LOG_ERROR);
256
}
257
258
static void hide_cb(GtkWidget *widget, LogWindow *logwin)
259
{
260
}
261
262
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
263
                            LogWindow *logwin)
264
{
265
        if (event && event->keyval == GDK_Escape)
266
                gtk_widget_hide(logwin->window);
267
        return FALSE;
268
}