Mercurial > pidgin
annotate src/gtklog.c @ 11157:f068eaabe332
[gaim-migrate @ 13242]
Patch submitted to gaim-devel...
"Marcin Owsiany sent you a draft advisory regarding multiple libgadu
vulnerabilities. "Fortunately" gaim contains an extremely old version of
libgadu and is affected only by memory alignment bug, which cannot be
exploited on x86. No other critical vulnerabilities are known in gaim's
version of libgadu.
You'll find the patch in attachment.
Regards,
Wojtek Kaniewski
ekg/libgadu maintainer"
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Mon, 25 Jul 2005 21:20:14 +0000 |
parents | a3d3729a9130 |
children | a511b77a368b |
rev | line source |
---|---|
7432 | 1 /** |
2 * @file gtklog.c GTK+ Log viewer | |
3 * @ingroup gtkui | |
4 * | |
5 * gaim | |
6 * | |
8046 | 7 * Gaim is the legal property of its developers, whose names are too numerous |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
7537
083427fd8ba8
[gaim-migrate @ 8150]
Christian Hammond <chipx86@chipx86.com>
parents:
7535
diff
changeset
|
10 * |
7432 | 11 * This program is free software; you can redistribute it and/or modify |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
9791 | 25 #include "internal.h" |
26 #include "gtkgaim.h" | |
7432 | 27 |
28 #include "account.h" | |
29 #include "util.h" | |
30 #include "gtkblist.h" | |
31 #include "gtkimhtml.h" | |
32 #include "gtklog.h" | |
33 #include "gtkutils.h" | |
34 #include "log.h" | |
10636 | 35 #include "util.h" |
7432 | 36 |
37 static GHashTable *log_viewers = NULL; | |
7535 | 38 static void populate_log_tree(GaimGtkLogViewer *lv); |
8573 | 39 static GaimGtkLogViewer *syslog_viewer = NULL; |
7432 | 40 |
41 struct log_viewer_hash_t { | |
10663 | 42 GaimLogType type; |
7432 | 43 char *screenname; |
44 GaimAccount *account; | |
10663 | 45 GaimContact *contact; |
7432 | 46 }; |
47 | |
7440 | 48 static guint log_viewer_hash(gconstpointer data) |
7432 | 49 { |
7440 | 50 const struct log_viewer_hash_t *viewer = data; |
51 | |
10663 | 52 if (viewer->contact != NULL) |
53 return g_direct_hash(viewer->contact); | |
54 | |
55 return g_str_hash(viewer->screenname) + | |
56 g_str_hash(gaim_account_get_username(viewer->account)); | |
7432 | 57 } |
58 | |
10663 | 59 static gboolean log_viewer_equal(gconstpointer y, gconstpointer z) |
7432 | 60 { |
7440 | 61 const struct log_viewer_hash_t *a, *b; |
7432 | 62 int ret; |
7440 | 63 char *normal; |
64 | |
65 a = y; | |
66 b = z; | |
67 | |
10663 | 68 if (a->contact != NULL) { |
69 if (b->contact != NULL) | |
70 return (a->contact == b->contact); | |
71 else | |
72 return FALSE; | |
73 } else { | |
74 if (b->contact != NULL) | |
75 return FALSE; | |
76 } | |
77 | |
7440 | 78 normal = g_strdup(gaim_normalize(a->account, a->screenname)); |
79 ret = (a->account == b->account) && | |
80 !strcmp(normal, gaim_normalize(b->account, b->screenname)); | |
7432 | 81 g_free(normal); |
10663 | 82 |
7432 | 83 return ret; |
84 } | |
85 | |
7535 | 86 static void search_cb(GtkWidget *button, GaimGtkLogViewer *lv) |
87 { | |
88 const char *search_term = gtk_entry_get_text(GTK_ENTRY(lv->entry)); | |
89 GList *logs; | |
90 GdkCursor *cursor = gdk_cursor_new(GDK_WATCH); | |
10175 | 91 |
10663 | 92 if (lv->search != NULL) |
7535 | 93 g_free(lv->search); |
10175 | 94 |
7535 | 95 gtk_tree_store_clear(lv->treestore); |
96 if (strlen(search_term) == 0) {/* reset the tree */ | |
97 populate_log_tree(lv); | |
98 lv->search = NULL; | |
7537
083427fd8ba8
[gaim-migrate @ 8150]
Christian Hammond <chipx86@chipx86.com>
parents:
7535
diff
changeset
|
99 gtk_imhtml_search_clear(GTK_IMHTML(lv->imhtml)); |
7535 | 100 return; |
101 } | |
10175 | 102 |
7535 | 103 lv->search = g_strdup(search_term); |
10175 | 104 |
7535 | 105 gdk_window_set_cursor(lv->window->window, cursor); |
106 while (gtk_events_pending()) | |
107 gtk_main_iteration(); | |
108 gdk_cursor_unref(cursor); | |
10175 | 109 |
7535 | 110 for (logs = lv->logs; logs != NULL; logs = logs->next) { |
111 char *read = gaim_log_read((GaimLog*)logs->data, NULL); | |
112 if (gaim_strcasestr(read, search_term)) { | |
113 GtkTreeIter iter; | |
114 GaimLog *log = logs->data; | |
115 char title[64]; | |
7676 | 116 char *title_utf8; /* temporary variable for utf8 conversion */ |
10636 | 117 gaim_strftime(title, sizeof(title), "%c", localtime(&log->time)); |
7676 | 118 title_utf8 = gaim_utf8_try_convert(title); |
119 strncpy(title, title_utf8, sizeof(title)); | |
120 g_free(title_utf8); | |
7535 | 121 gtk_tree_store_append (lv->treestore, &iter, NULL); |
122 gtk_tree_store_set(lv->treestore, &iter, | |
123 0, title, | |
10175 | 124 1, log, -1); |
7535 | 125 } |
10574 | 126 g_free(read); |
7535 | 127 } |
10175 | 128 |
129 | |
7535 | 130 cursor = gdk_cursor_new(GDK_LEFT_PTR); |
131 gdk_window_set_cursor(lv->window->window, cursor); | |
132 gdk_cursor_unref(cursor); | |
133 } | |
134 | |
7454 | 135 static gboolean destroy_cb(GtkWidget *w, gint resp, struct log_viewer_hash_t *ht) { |
8573 | 136 GaimGtkLogViewer *lv = syslog_viewer; |
7454 | 137 |
10663 | 138 if (ht != NULL) { |
8573 | 139 lv = g_hash_table_lookup(log_viewers, ht); |
140 g_hash_table_remove(log_viewers, ht); | |
10663 | 141 |
142 if (ht->screenname != NULL) | |
143 g_free(ht->screenname); | |
144 | |
8573 | 145 g_free(ht); |
146 } else | |
147 syslog_viewer = NULL; | |
148 | |
10663 | 149 while (lv->logs != NULL) { |
7535 | 150 GList *logs2; |
10663 | 151 |
152 gaim_log_free((GaimLog *)lv->logs->data); | |
153 | |
7535 | 154 logs2 = lv->logs->next; |
155 g_list_free_1(lv->logs); | |
156 lv->logs = logs2; | |
7533 | 157 } |
10663 | 158 |
159 if (lv->search != NULL) | |
7535 | 160 g_free(lv->search); |
10663 | 161 |
8573 | 162 g_free(lv); |
7454 | 163 gtk_widget_destroy(w); |
164 | |
165 return TRUE; | |
166 } | |
167 | |
10663 | 168 static void log_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, GaimGtkLogViewer *viewer) { |
169 if (gtk_tree_view_row_expanded(tv, path)) | |
170 gtk_tree_view_collapse_row(tv, path); | |
171 else | |
172 gtk_tree_view_expand_row(tv, path, FALSE); | |
8573 | 173 } |
10663 | 174 |
7454 | 175 static void log_select_cb(GtkTreeSelection *sel, GaimGtkLogViewer *viewer) { |
7432 | 176 GtkTreeIter iter; |
177 GValue val = { 0, }; | |
178 GtkTreeModel *model = GTK_TREE_MODEL(viewer->treestore); | |
179 GaimLog *log = NULL; | |
180 GaimLogReadFlags flags; | |
181 char *read = NULL; | |
182 char time[64]; | |
183 | |
10663 | 184 if (!gtk_tree_selection_get_selected(sel, &model, &iter)) |
7432 | 185 return; |
186 gtk_tree_model_get_value (model, &iter, 1, &val); | |
187 log = g_value_get_pointer(&val); | |
188 g_value_unset(&val); | |
189 | |
10663 | 190 if (log == NULL) |
7432 | 191 return; |
192 | |
10663 | 193 if (log->type != GAIM_LOG_SYSTEM) { |
194 char *title; | |
195 char *title_utf8; /* temporary variable for utf8 conversion */ | |
196 | |
197 gaim_strftime(time, sizeof(time), "%c", localtime(&log->time)); | |
198 | |
199 if (log->type == GAIM_LOG_CHAT) | |
200 title = g_strdup_printf(_("Conversation in %s on %s"), log->name, time); | |
201 else | |
202 title = g_strdup_printf(_("Conversation with %s on %s"), log->name, time); | |
203 | |
204 title_utf8 = gaim_utf8_try_convert(title); | |
205 g_free(title); | |
206 | |
207 title = g_strdup_printf("<span size='larger' weight='bold'>%s</span>", title_utf8); | |
208 g_free(title_utf8); | |
209 | |
210 gtk_label_set_markup(GTK_LABEL(viewer->label), title); | |
211 g_free(title); | |
212 } | |
213 | |
7432 | 214 read = gaim_log_read(log, &flags); |
215 viewer->flags = flags; | |
10663 | 216 |
7432 | 217 gtk_imhtml_clear(GTK_IMHTML(viewer->imhtml)); |
10645 | 218 gtk_imhtml_set_protocol_name(GTK_IMHTML(viewer->imhtml), |
219 gaim_account_get_protocol_name(log->account)); | |
10574 | 220 gtk_imhtml_append_text(GTK_IMHTML(viewer->imhtml), read, |
10175 | 221 GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_SCROLL | |
7432 | 222 ((flags & GAIM_LOG_READ_NO_NEWLINE) ? GTK_IMHTML_NO_NEWLINE : 0)); |
7535 | 223 |
10663 | 224 if (viewer->search != NULL) { |
10574 | 225 gtk_imhtml_search_clear(GTK_IMHTML(viewer->imhtml)); |
7537
083427fd8ba8
[gaim-migrate @ 8150]
Christian Hammond <chipx86@chipx86.com>
parents:
7535
diff
changeset
|
226 gtk_imhtml_search_find(GTK_IMHTML(viewer->imhtml), viewer->search); |
10574 | 227 } |
10175 | 228 |
7432 | 229 g_free(read); |
230 } | |
231 | |
232 /* I want to make this smarter, but haven't come up with a cool algorithm to do so, yet. | |
233 * I want the tree to be divided into groups like "Today," "Yesterday," "Last week," | |
234 * "August," "2002," etc. based on how many conversation took place in each subdivision. | |
235 * | |
236 * For now, I'll just make it a flat list. | |
237 */ | |
238 static void populate_log_tree(GaimGtkLogViewer *lv) | |
239 /* Logs are made from trees in real life. | |
240 This is a tree made from logs */ | |
241 { | |
9435 | 242 char month[30]; |
7440 | 243 char title[64]; |
10663 | 244 char prev_top_month[30] = ""; |
9435 | 245 char *utf8_tmp; /* temporary variable for utf8 conversion */ |
246 GtkTreeIter toplevel, child; | |
7432 | 247 GList *logs = lv->logs; |
10663 | 248 |
249 while (logs != NULL) { | |
7432 | 250 GaimLog *log = logs->data; |
10175 | 251 |
10636 | 252 gaim_strftime(month, sizeof(month), "%B %Y", localtime(&log->time)); |
253 gaim_strftime(title, sizeof(title), "%c", localtime(&log->time)); | |
10175 | 254 |
9435 | 255 /* do utf8 conversions */ |
256 utf8_tmp = gaim_utf8_try_convert(month); | |
257 strncpy(month, utf8_tmp, sizeof(month)); | |
10574 | 258 g_free(utf8_tmp); |
9435 | 259 utf8_tmp = gaim_utf8_try_convert(title); |
260 strncpy(title, utf8_tmp, sizeof(title)); | |
261 g_free(utf8_tmp); | |
10175 | 262 |
9435 | 263 if (strncmp(month, prev_top_month, sizeof(month)) != 0) { |
264 /* top level */ | |
265 gtk_tree_store_append(lv->treestore, &toplevel, NULL); | |
266 gtk_tree_store_set(lv->treestore, &toplevel, 0, month, 1, NULL, -1); | |
10175 | 267 |
10680 | 268 strncpy(prev_top_month, month, sizeof(prev_top_month)); |
269 } | |
10175 | 270 |
10680 | 271 /* sub */ |
272 gtk_tree_store_append(lv->treestore, &child, &toplevel); | |
273 gtk_tree_store_set(lv->treestore, &child, 0, title, 1, log, -1); | |
10175 | 274 |
7432 | 275 logs = logs->next; |
276 } | |
277 } | |
278 | |
10663 | 279 static GaimGtkLogViewer *display_log_viewer(struct log_viewer_hash_t *ht, GList *logs, |
280 const char *title, GdkPixbuf *pixbuf) | |
281 { | |
282 GaimGtkLogViewer *lv; | |
283 GtkWidget *title_box; | |
284 char *text; | |
7432 | 285 |
286 lv = g_new0(GaimGtkLogViewer, 1); | |
10663 | 287 lv->logs = logs; |
288 | |
289 if (ht != NULL) | |
290 g_hash_table_insert(log_viewers, ht, lv); | |
7432 | 291 |
292 /* Window ***********/ | |
10663 | 293 lv->window = gtk_dialog_new_with_buttons(title, NULL, 0, |
7432 | 294 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); |
295 gtk_container_set_border_width (GTK_CONTAINER(lv->window), 6); | |
296 gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE); | |
297 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(lv->window)->vbox), 0); | |
10175 | 298 g_signal_connect(G_OBJECT(lv->window), "response", |
7454 | 299 G_CALLBACK(destroy_cb), ht); |
11004
a3d3729a9130
[gaim-migrate @ 12859]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10884
diff
changeset
|
300 gtk_window_set_role(GTK_WINDOW(lv->window), "log_viewer"); |
7454 | 301 |
10663 | 302 /* Icon *************/ |
303 if (pixbuf != NULL) { | |
304 GdkPixbuf *scale; | |
305 GtkWidget *icon; | |
7432 | 306 |
10663 | 307 title_box = gtk_hbox_new(FALSE, 6); |
308 gtk_container_set_border_width(GTK_CONTAINER(title_box), 6); | |
309 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), title_box, FALSE, FALSE, 0); | |
310 | |
311 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR); | |
312 icon = gtk_image_new_from_pixbuf(scale); | |
313 gtk_box_pack_start(GTK_BOX(title_box), icon, FALSE, FALSE, 0); | |
314 g_object_unref(G_OBJECT(pixbuf)); | |
315 g_object_unref(G_OBJECT(scale)); | |
316 } else | |
317 title_box = GTK_DIALOG(lv->window)->vbox; | |
7432 | 318 |
319 /* Label ************/ | |
10663 | 320 lv->label = gtk_label_new(NULL); |
321 | |
322 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>", title); | |
9624 | 323 |
10663 | 324 gtk_label_set_markup(GTK_LABEL(lv->label), text); |
325 gtk_misc_set_alignment(GTK_MISC(lv->label), 0, 0); | |
326 gtk_box_pack_start(GTK_BOX(title_box), lv->label, FALSE, FALSE, 0); | |
7432 | 327 g_free(text); |
328 | |
10663 | 329 if (logs != NULL) { |
330 GtkWidget *pane; | |
331 GtkWidget *sw; | |
332 GtkCellRenderer *rend; | |
333 GtkTreeViewColumn *col; | |
334 GtkTreeSelection *sel; | |
335 GtkWidget *vbox; | |
336 GtkWidget *frame; | |
337 GtkWidget *hbox; | |
338 GtkWidget *button; | |
10175 | 339 |
10663 | 340 /* Pane *************/ |
341 pane = gtk_hpaned_new(); | |
342 gtk_container_set_border_width(GTK_CONTAINER(pane), 6); | |
343 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), pane, TRUE, TRUE, 0); | |
7432 | 344 |
10663 | 345 /* List *************/ |
346 sw = gtk_scrolled_window_new (NULL, NULL); | |
347 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); | |
348 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); | |
349 gtk_paned_add1(GTK_PANED(pane), sw); | |
350 lv->treestore = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); | |
351 lv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (lv->treestore)); | |
352 rend = gtk_cell_renderer_text_new(); | |
353 col = gtk_tree_view_column_new_with_attributes ("time", rend, "markup", 0, NULL); | |
354 gtk_tree_view_append_column (GTK_TREE_VIEW(lv->treeview), col); | |
355 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (lv->treeview), FALSE); | |
356 gtk_container_add (GTK_CONTAINER (sw), lv->treeview); | |
357 | |
358 populate_log_tree(lv); | |
359 | |
360 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (lv->treeview)); | |
361 g_signal_connect (G_OBJECT (sel), "changed", | |
362 G_CALLBACK (log_select_cb), | |
363 lv); | |
364 g_signal_connect (G_OBJECT(lv->treeview), "row-activated", | |
365 G_CALLBACK(log_row_activated_cb), | |
366 lv); | |
367 gaim_set_accessible_label(lv->treeview, lv->label); | |
368 | |
369 /* A fancy little box ************/ | |
370 vbox = gtk_vbox_new(FALSE, 6); | |
371 gtk_paned_add2(GTK_PANED(pane), vbox); | |
372 | |
373 /* Viewer ************/ | |
374 frame = gaim_gtk_create_imhtml(FALSE, &lv->imhtml, NULL); | |
375 gtk_widget_set_name(lv->imhtml, "gaim_gtklog_imhtml"); | |
376 gtk_widget_set_size_request(lv->imhtml, 320, 200); | |
377 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | |
378 gtk_widget_show(frame); | |
379 | |
380 /* Search box **********/ | |
381 hbox = gtk_hbox_new(FALSE, 6); | |
382 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
383 lv->entry = gtk_entry_new(); | |
384 gtk_box_pack_start(GTK_BOX(hbox), lv->entry, TRUE, TRUE, 0); | |
385 button = gtk_button_new_from_stock(GTK_STOCK_FIND); | |
386 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
387 g_signal_connect(GTK_ENTRY(lv->entry), "activate", G_CALLBACK(search_cb), lv); | |
388 g_signal_connect(GTK_BUTTON(button), "activate", G_CALLBACK(search_cb), lv); | |
389 g_signal_connect(GTK_BUTTON(button), "clicked", G_CALLBACK(search_cb), lv); | |
390 } else { | |
391 /* No logs were found. */ | |
392 const char *log_preferences = NULL; | |
393 GtkWidget *label; | |
10181 | 394 |
10663 | 395 if (ht == NULL) { |
396 if (!gaim_prefs_get_bool("/core/logging/log_system")) | |
397 log_preferences = _("System events will only be logged if the <span style=\"italic\">Enable system log preference</span> is set."); | |
398 } else { | |
399 if (ht->type == GAIM_LOG_IM) { | |
400 if (!gaim_prefs_get_bool("/core/logging/log_ims")) | |
401 log_preferences = _("Instant messages will only be logged if the <span style=\"italic\">Log all instant messages</span> preference is enabled."); | |
402 } else if (ht->type == GAIM_LOG_CHAT) { | |
403 if (!gaim_prefs_get_bool("/core/logging/log_chats")) | |
404 log_preferences = _("Chats will only be logged if the <span style=\"italic\">Log all chats preference</span> is enabled."); | |
405 } | |
406 } | |
10175 | 407 |
10663 | 408 text = g_strdup_printf("\n<span weight=\"bold\">%s</span>%s%s\n", |
409 _("No logs were found."), | |
410 log_preferences ? "\n" : "", | |
411 log_preferences ? log_preferences : ""); | |
412 | |
413 label = gtk_label_new(NULL); | |
414 | |
415 gtk_label_set_markup(GTK_LABEL(label), text); | |
416 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
417 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); | |
418 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), label, FALSE, FALSE, 0); | |
419 g_free(text); | |
420 } | |
7432 | 421 |
422 gtk_widget_show_all(lv->window); | |
10663 | 423 |
424 return lv; | |
425 } | |
426 | |
427 void gaim_gtk_log_show(GaimLogType type, const char *screenname, GaimAccount *account) { | |
428 struct log_viewer_hash_t *ht = g_new0(struct log_viewer_hash_t, 1); | |
429 GaimGtkLogViewer *lv = NULL; | |
430 const char *name = screenname; | |
431 char *title; | |
432 | |
433 g_return_if_fail(account != NULL); | |
434 g_return_if_fail(screenname != NULL); | |
435 | |
436 ht->type = type; | |
437 ht->screenname = g_strdup(screenname); | |
438 ht->account = account; | |
439 | |
440 if (log_viewers == NULL) { | |
441 log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal); | |
442 } else if ((lv = g_hash_table_lookup(log_viewers, ht))) { | |
443 gtk_window_present(GTK_WINDOW(lv->window)); | |
444 g_free(ht); | |
445 return; | |
446 } | |
447 | |
448 if (type == GAIM_LOG_CHAT) { | |
449 GaimChat *chat; | |
450 | |
451 chat = gaim_blist_find_chat(account, screenname); | |
452 if (chat != NULL) | |
453 name = gaim_chat_get_name(chat); | |
454 | |
455 title = g_strdup_printf(_("Conversations in %s"), name); | |
456 } else { | |
457 GaimBuddy *buddy; | |
458 | |
459 buddy = gaim_find_buddy(account, screenname); | |
460 if (buddy != NULL) | |
461 name = gaim_buddy_get_contact_alias(buddy); | |
462 | |
463 title = g_strdup_printf(_("Conversations with %s"), name); | |
464 } | |
465 | |
466 display_log_viewer(ht, gaim_log_get_logs(type, screenname, account), | |
10884 | 467 title, gaim_gtk_create_prpl_icon(account)); |
10663 | 468 g_free(title); |
469 } | |
470 | |
471 void gaim_gtk_log_show_contact(GaimContact *contact) { | |
472 struct log_viewer_hash_t *ht = g_new0(struct log_viewer_hash_t, 1); | |
473 GaimBlistNode *child; | |
474 GaimGtkLogViewer *lv = NULL; | |
475 GList *logs = NULL; | |
476 char *filename; | |
477 GdkPixbuf *pixbuf; | |
478 const char *name = NULL; | |
479 char *title; | |
480 | |
481 g_return_if_fail(contact != NULL); | |
482 | |
483 ht->type = GAIM_LOG_IM; | |
484 ht->contact = contact; | |
485 | |
486 if (log_viewers == NULL) { | |
487 log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal); | |
488 } else if ((lv = g_hash_table_lookup(log_viewers, ht))) { | |
489 gtk_window_present(GTK_WINDOW(lv->window)); | |
490 g_free(ht); | |
491 return; | |
492 } | |
493 | |
494 for (child = contact->node.child ; child ; child = child->next) { | |
495 if (!GAIM_BLIST_NODE_IS_BUDDY(child)) | |
496 continue; | |
497 | |
498 logs = g_list_concat(logs, | |
499 gaim_log_get_logs(GAIM_LOG_IM, ((GaimBuddy *)child)->name, | |
500 ((GaimBuddy *)child)->account)); | |
501 } | |
502 logs = g_list_sort(logs, gaim_log_compare); | |
503 | |
504 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "icons", "online.png", NULL); | |
505 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); | |
506 g_free(filename); | |
507 | |
508 if (contact->alias != NULL) | |
509 name = contact->alias; | |
510 else if (contact->priority != NULL) | |
511 name = gaim_buddy_get_contact_alias(contact->priority); | |
512 | |
513 title = g_strdup_printf(_("Conversations with %s"), name); | |
514 display_log_viewer(ht, logs, title, pixbuf); | |
515 g_free(title); | |
7432 | 516 } |
8573 | 517 |
518 void gaim_gtk_syslog_show() | |
519 { | |
520 GList *accounts = NULL; | |
10663 | 521 GList *logs = NULL; |
8573 | 522 |
10181 | 523 if (syslog_viewer != NULL) { |
8573 | 524 gtk_window_present(GTK_WINDOW(syslog_viewer->window)); |
525 return; | |
526 } | |
527 | |
10663 | 528 for(accounts = gaim_accounts_get_all(); accounts != NULL; accounts = accounts->next) { |
8573 | 529 |
530 GaimAccount *account = (GaimAccount *)accounts->data; | |
10663 | 531 if(gaim_find_prpl(gaim_account_get_protocol_id(account)) == NULL) |
8573 | 532 continue; |
533 | |
10663 | 534 logs = g_list_concat(logs, gaim_log_get_system_logs(account)); |
8573 | 535 } |
10663 | 536 logs = g_list_sort(logs, gaim_log_compare); |
10175 | 537 |
10663 | 538 syslog_viewer = display_log_viewer(NULL, logs, _("System Log"), NULL); |
8573 | 539 } |