Mercurial > pidgin.yaz
annotate src/gtklog.c @ 12233:02833a0ae716
[gaim-migrate @ 14535]
SF Patch #1367116 from Michael Carlson
"In profiling gaim, I noticed that on simply starting
CVS gaim, xmlnode_insert_child is using up by far the
most CPU time. After some testing, I realized the
reason why: xmlnode_insert_child is called some 18,000
times on startup, and it is inserting the child at the
end of the list each time, simply by traversing through
the entire linked list. Sometimes this list can have as
many as 800 elements.
This patch adds a variable to the _xmlnode struct,
lastchild, which simply keeps track of the last node in
the list of children. This is then used by
xmlnode_insert_child to insert at the end of the list,
instead of traversing through the whole list each time.
The two relevant functions in xmlnode.c that need to be
updated to keep track of this function appropriately
have been updated.
Running 3 times with and without the change, the
results from oprofile say it all. Here are the measured
number of clock cycles / % of total clock cycles /
function used to simply start and close gaim before the
change:
204 60.7143 xmlnode_insert_child
210 61.4035 xmlnode_insert_child
230 61.8280 xmlnode_insert_child
And after (note that one time no clock cycles were
caught at all)
3 2.5862 xmlnode_insert_child
3 2.5641 xmlnode_insert_child
This affects other areas of the program than just
starting up, but this seems to be the most noticeable
place."
Speed is good. As I was verifying this patch, I added some g_return_val_if_fail() checks.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Sun, 27 Nov 2005 03:42:39 +0000 |
parents | 375f1f3817a8 |
children | e856f985a0b9 |
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 "gtkblist.h" | |
30 #include "gtkimhtml.h" | |
31 #include "gtklog.h" | |
32 #include "gtkutils.h" | |
33 #include "log.h" | |
11769 | 34 #include "notify.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; | |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
90 GdkCursor *cursor; |
10175 | 91 |
10663 | 92 if (lv->search != NULL) |
7535 | 93 g_free(lv->search); |
10175 | 94 |
11585 | 95 gtk_tree_store_clear(lv->treestore); |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
96 if (!(*search_term)) { |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
97 /* reset the tree */ |
7535 | 98 populate_log_tree(lv); |
99 lv->search = NULL; | |
7537
083427fd8ba8
[gaim-migrate @ 8150]
Christian Hammond <chipx86@chipx86.com>
parents:
7535
diff
changeset
|
100 gtk_imhtml_search_clear(GTK_IMHTML(lv->imhtml)); |
7535 | 101 return; |
102 } | |
10175 | 103 |
7535 | 104 lv->search = g_strdup(search_term); |
10175 | 105 |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
106 cursor = gdk_cursor_new(GDK_WATCH); |
7535 | 107 gdk_window_set_cursor(lv->window->window, cursor); |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
108 gdk_cursor_unref(cursor); |
7535 | 109 while (gtk_events_pending()) |
110 gtk_main_iteration(); | |
10175 | 111 |
7535 | 112 for (logs = lv->logs; logs != NULL; logs = logs->next) { |
113 char *read = gaim_log_read((GaimLog*)logs->data, NULL); | |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
114 if (read && *read && gaim_strcasestr(read, search_term)) { |
7535 | 115 GtkTreeIter iter; |
116 GaimLog *log = logs->data; | |
117 char title[64]; | |
7676 | 118 char *title_utf8; /* temporary variable for utf8 conversion */ |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
119 |
10636 | 120 gaim_strftime(title, sizeof(title), "%c", localtime(&log->time)); |
7676 | 121 title_utf8 = gaim_utf8_try_convert(title); |
122 strncpy(title, title_utf8, sizeof(title)); | |
123 g_free(title_utf8); | |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
124 |
7535 | 125 gtk_tree_store_append (lv->treestore, &iter, NULL); |
126 gtk_tree_store_set(lv->treestore, &iter, | |
127 0, title, | |
10175 | 128 1, log, -1); |
7535 | 129 } |
10574 | 130 g_free(read); |
7535 | 131 } |
10175 | 132 |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
133 gdk_window_set_cursor(lv->window->window, NULL); |
7535 | 134 } |
135 | |
7454 | 136 static gboolean destroy_cb(GtkWidget *w, gint resp, struct log_viewer_hash_t *ht) { |
8573 | 137 GaimGtkLogViewer *lv = syslog_viewer; |
7454 | 138 |
10663 | 139 if (ht != NULL) { |
8573 | 140 lv = g_hash_table_lookup(log_viewers, ht); |
141 g_hash_table_remove(log_viewers, ht); | |
10663 | 142 |
143 if (ht->screenname != NULL) | |
144 g_free(ht->screenname); | |
145 | |
8573 | 146 g_free(ht); |
147 } else | |
148 syslog_viewer = NULL; | |
149 | |
10663 | 150 while (lv->logs != NULL) { |
7535 | 151 GList *logs2; |
10663 | 152 |
153 gaim_log_free((GaimLog *)lv->logs->data); | |
154 | |
7535 | 155 logs2 = lv->logs->next; |
156 g_list_free_1(lv->logs); | |
157 lv->logs = logs2; | |
7533 | 158 } |
10663 | 159 |
160 if (lv->search != NULL) | |
7535 | 161 g_free(lv->search); |
10663 | 162 |
8573 | 163 g_free(lv); |
7454 | 164 gtk_widget_destroy(w); |
165 | |
166 return TRUE; | |
167 } | |
168 | |
10663 | 169 static void log_row_activated_cb(GtkTreeView *tv, GtkTreePath *path, GtkTreeViewColumn *col, GaimGtkLogViewer *viewer) { |
170 if (gtk_tree_view_row_expanded(tv, path)) | |
171 gtk_tree_view_collapse_row(tv, path); | |
172 else | |
173 gtk_tree_view_expand_row(tv, path, FALSE); | |
8573 | 174 } |
10663 | 175 |
7454 | 176 static void log_select_cb(GtkTreeSelection *sel, GaimGtkLogViewer *viewer) { |
7432 | 177 GtkTreeIter iter; |
178 GValue val = { 0, }; | |
179 GtkTreeModel *model = GTK_TREE_MODEL(viewer->treestore); | |
180 GaimLog *log = NULL; | |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
181 GdkCursor *cursor; |
7432 | 182 GaimLogReadFlags flags; |
183 char *read = NULL; | |
184 char time[64]; | |
185 | |
10663 | 186 if (!gtk_tree_selection_get_selected(sel, &model, &iter)) |
7432 | 187 return; |
188 gtk_tree_model_get_value (model, &iter, 1, &val); | |
189 log = g_value_get_pointer(&val); | |
190 g_value_unset(&val); | |
191 | |
10663 | 192 if (log == NULL) |
7432 | 193 return; |
194 | |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
195 /* When we set the initial log, this gets called and the window is still NULL. */ |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
196 if (viewer->window->window != NULL) |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
197 { |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
198 cursor = gdk_cursor_new(GDK_WATCH); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
199 gdk_window_set_cursor(viewer->window->window, cursor); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
200 gdk_cursor_unref(cursor); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
201 while (gtk_events_pending()) |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
202 gtk_main_iteration(); |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
203 } |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
204 |
10663 | 205 if (log->type != GAIM_LOG_SYSTEM) { |
206 char *title; | |
207 char *title_utf8; /* temporary variable for utf8 conversion */ | |
208 | |
209 gaim_strftime(time, sizeof(time), "%c", localtime(&log->time)); | |
210 | |
211 if (log->type == GAIM_LOG_CHAT) | |
212 title = g_strdup_printf(_("Conversation in %s on %s"), log->name, time); | |
213 else | |
214 title = g_strdup_printf(_("Conversation with %s on %s"), log->name, time); | |
215 | |
216 title_utf8 = gaim_utf8_try_convert(title); | |
217 g_free(title); | |
218 | |
219 title = g_strdup_printf("<span size='larger' weight='bold'>%s</span>", title_utf8); | |
220 g_free(title_utf8); | |
221 | |
222 gtk_label_set_markup(GTK_LABEL(viewer->label), title); | |
223 g_free(title); | |
224 } | |
225 | |
7432 | 226 read = gaim_log_read(log, &flags); |
227 viewer->flags = flags; | |
10663 | 228 |
7432 | 229 gtk_imhtml_clear(GTK_IMHTML(viewer->imhtml)); |
10645 | 230 gtk_imhtml_set_protocol_name(GTK_IMHTML(viewer->imhtml), |
231 gaim_account_get_protocol_name(log->account)); | |
10574 | 232 gtk_imhtml_append_text(GTK_IMHTML(viewer->imhtml), read, |
10175 | 233 GTK_IMHTML_NO_COMMENTS | GTK_IMHTML_NO_TITLE | GTK_IMHTML_NO_SCROLL | |
7432 | 234 ((flags & GAIM_LOG_READ_NO_NEWLINE) ? GTK_IMHTML_NO_NEWLINE : 0)); |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
235 g_free(read); |
7535 | 236 |
10663 | 237 if (viewer->search != NULL) { |
10574 | 238 gtk_imhtml_search_clear(GTK_IMHTML(viewer->imhtml)); |
7537
083427fd8ba8
[gaim-migrate @ 8150]
Christian Hammond <chipx86@chipx86.com>
parents:
7535
diff
changeset
|
239 gtk_imhtml_search_find(GTK_IMHTML(viewer->imhtml), viewer->search); |
10574 | 240 } |
10175 | 241 |
12232
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
242 /* When we set the initial log, this gets called and the window is still NULL. */ |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
243 if (viewer->window->window != NULL) |
375f1f3817a8
[gaim-migrate @ 14534]
Richard Laager <rlaager@wiktel.com>
parents:
11869
diff
changeset
|
244 gdk_window_set_cursor(viewer->window->window, NULL); |
7432 | 245 } |
246 | |
247 /* I want to make this smarter, but haven't come up with a cool algorithm to do so, yet. | |
248 * I want the tree to be divided into groups like "Today," "Yesterday," "Last week," | |
249 * "August," "2002," etc. based on how many conversation took place in each subdivision. | |
250 * | |
251 * For now, I'll just make it a flat list. | |
252 */ | |
253 static void populate_log_tree(GaimGtkLogViewer *lv) | |
11585 | 254 /* Logs are made from trees in real life. |
7432 | 255 This is a tree made from logs */ |
256 { | |
9435 | 257 char month[30]; |
7440 | 258 char title[64]; |
10663 | 259 char prev_top_month[30] = ""; |
9435 | 260 char *utf8_tmp; /* temporary variable for utf8 conversion */ |
261 GtkTreeIter toplevel, child; | |
7432 | 262 GList *logs = lv->logs; |
10663 | 263 |
264 while (logs != NULL) { | |
7432 | 265 GaimLog *log = logs->data; |
10175 | 266 |
10636 | 267 gaim_strftime(month, sizeof(month), "%B %Y", localtime(&log->time)); |
268 gaim_strftime(title, sizeof(title), "%c", localtime(&log->time)); | |
10175 | 269 |
9435 | 270 /* do utf8 conversions */ |
271 utf8_tmp = gaim_utf8_try_convert(month); | |
272 strncpy(month, utf8_tmp, sizeof(month)); | |
10574 | 273 g_free(utf8_tmp); |
9435 | 274 utf8_tmp = gaim_utf8_try_convert(title); |
275 strncpy(title, utf8_tmp, sizeof(title)); | |
276 g_free(utf8_tmp); | |
10175 | 277 |
9435 | 278 if (strncmp(month, prev_top_month, sizeof(month)) != 0) { |
279 /* top level */ | |
280 gtk_tree_store_append(lv->treestore, &toplevel, NULL); | |
281 gtk_tree_store_set(lv->treestore, &toplevel, 0, month, 1, NULL, -1); | |
10175 | 282 |
10680 | 283 strncpy(prev_top_month, month, sizeof(prev_top_month)); |
284 } | |
10175 | 285 |
10680 | 286 /* sub */ |
287 gtk_tree_store_append(lv->treestore, &child, &toplevel); | |
288 gtk_tree_store_set(lv->treestore, &child, 0, title, 1, log, -1); | |
10175 | 289 |
7432 | 290 logs = logs->next; |
291 } | |
292 } | |
293 | |
10663 | 294 static GaimGtkLogViewer *display_log_viewer(struct log_viewer_hash_t *ht, GList *logs, |
11585 | 295 const char *title, GdkPixbuf *pixbuf, int log_size) |
10663 | 296 { |
297 GaimGtkLogViewer *lv; | |
298 GtkWidget *title_box; | |
299 char *text; | |
11769 | 300 GtkWidget *pane; |
301 GtkWidget *sw; | |
302 GtkCellRenderer *rend; | |
303 GtkTreeViewColumn *col; | |
304 GtkTreeSelection *sel; | |
11780 | 305 #if GTK_CHECK_VERSION(2,2,0) |
11769 | 306 GtkTreePath *path_to_first_log; |
11780 | 307 #endif |
11769 | 308 GtkWidget *vbox; |
309 GtkWidget *frame; | |
310 GtkWidget *hbox; | |
311 GtkWidget *button; | |
312 GtkWidget *size_label; | |
7432 | 313 |
314 lv = g_new0(GaimGtkLogViewer, 1); | |
10663 | 315 lv->logs = logs; |
316 | |
11769 | 317 if (logs == NULL) |
318 { | |
319 /* No logs were found. */ | |
320 const char *log_preferences = NULL; | |
321 | |
322 if (ht == NULL) { | |
323 if (!gaim_prefs_get_bool("/core/logging/log_system")) | |
324 log_preferences = _("System events will only be logged if the \"Log all status changes to system log\" preference is enabled."); | |
325 } else { | |
326 if (ht->type == GAIM_LOG_IM) { | |
327 if (!gaim_prefs_get_bool("/core/logging/log_ims")) | |
328 log_preferences = _("Instant messages will only be logged if the \"Log all instant messages\" preference is enabled."); | |
329 } else if (ht->type == GAIM_LOG_CHAT) { | |
330 if (!gaim_prefs_get_bool("/core/logging/log_chats")) | |
11869 | 331 log_preferences = _("Chats will only be logged if the \"Log all chats\" preference is enabled."); |
11769 | 332 } |
333 } | |
334 | |
335 gaim_notify_info(NULL, title, _("No logs were found"), log_preferences); | |
336 return NULL; | |
337 } | |
338 | |
10663 | 339 if (ht != NULL) |
340 g_hash_table_insert(log_viewers, ht, lv); | |
7432 | 341 |
342 /* Window ***********/ | |
10663 | 343 lv->window = gtk_dialog_new_with_buttons(title, NULL, 0, |
7432 | 344 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); |
11243 | 345 gtk_container_set_border_width (GTK_CONTAINER(lv->window), GAIM_HIG_BOX_SPACE); |
7432 | 346 gtk_dialog_set_has_separator(GTK_DIALOG(lv->window), FALSE); |
347 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(lv->window)->vbox), 0); | |
10175 | 348 g_signal_connect(G_OBJECT(lv->window), "response", |
7454 | 349 G_CALLBACK(destroy_cb), ht); |
11004
a3d3729a9130
[gaim-migrate @ 12859]
Etan Reisner <pidgin@unreliablesource.net>
parents:
10884
diff
changeset
|
350 gtk_window_set_role(GTK_WINDOW(lv->window), "log_viewer"); |
7454 | 351 |
10663 | 352 /* Icon *************/ |
353 if (pixbuf != NULL) { | |
354 GdkPixbuf *scale; | |
355 GtkWidget *icon; | |
7432 | 356 |
11243 | 357 title_box = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); |
358 gtk_container_set_border_width(GTK_CONTAINER(title_box), GAIM_HIG_BOX_SPACE); | |
10663 | 359 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), title_box, FALSE, FALSE, 0); |
360 | |
361 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, GDK_INTERP_BILINEAR); | |
362 icon = gtk_image_new_from_pixbuf(scale); | |
363 gtk_box_pack_start(GTK_BOX(title_box), icon, FALSE, FALSE, 0); | |
364 g_object_unref(G_OBJECT(pixbuf)); | |
365 g_object_unref(G_OBJECT(scale)); | |
366 } else | |
367 title_box = GTK_DIALOG(lv->window)->vbox; | |
7432 | 368 |
369 /* Label ************/ | |
10663 | 370 lv->label = gtk_label_new(NULL); |
371 | |
372 text = g_strdup_printf("<span size='larger' weight='bold'>%s</span>", title); | |
9624 | 373 |
10663 | 374 gtk_label_set_markup(GTK_LABEL(lv->label), text); |
375 gtk_misc_set_alignment(GTK_MISC(lv->label), 0, 0); | |
376 gtk_box_pack_start(GTK_BOX(title_box), lv->label, FALSE, FALSE, 0); | |
7432 | 377 g_free(text); |
378 | |
11769 | 379 /* Pane *************/ |
380 pane = gtk_hpaned_new(); | |
381 gtk_container_set_border_width(GTK_CONTAINER(pane), GAIM_HIG_BOX_SPACE); | |
382 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(lv->window)->vbox), pane, TRUE, TRUE, 0); | |
7432 | 383 |
11769 | 384 /* List *************/ |
385 sw = gtk_scrolled_window_new (NULL, NULL); | |
386 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); | |
387 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); | |
388 gtk_paned_add1(GTK_PANED(pane), sw); | |
389 lv->treestore = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER); | |
390 lv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (lv->treestore)); | |
391 rend = gtk_cell_renderer_text_new(); | |
392 col = gtk_tree_view_column_new_with_attributes ("time", rend, "markup", 0, NULL); | |
393 gtk_tree_view_append_column (GTK_TREE_VIEW(lv->treeview), col); | |
394 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (lv->treeview), FALSE); | |
395 gtk_container_add (GTK_CONTAINER (sw), lv->treeview); | |
11402 | 396 |
11769 | 397 populate_log_tree(lv); |
11402 | 398 |
11769 | 399 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (lv->treeview)); |
400 g_signal_connect (G_OBJECT (sel), "changed", | |
401 G_CALLBACK (log_select_cb), | |
402 lv); | |
403 g_signal_connect (G_OBJECT(lv->treeview), "row-activated", | |
404 G_CALLBACK(log_row_activated_cb), | |
405 lv); | |
406 gaim_set_accessible_label(lv->treeview, lv->label); | |
11585 | 407 |
11769 | 408 /* Log size ************/ |
409 if(log_size) { | |
410 char *sz_txt = gaim_str_size_to_units(log_size); | |
411 text = g_strdup_printf("<span weight='bold'>%s</span> %s", _("Total log size:"), sz_txt); | |
412 size_label = gtk_label_new(NULL); | |
413 gtk_label_set_markup(GTK_LABEL(size_label), text); | |
414 /* gtk_paned_add1(GTK_PANED(pane), size_label); */ | |
415 gtk_misc_set_alignment(GTK_MISC(size_label), 0, 0); | |
416 gtk_box_pack_end(GTK_BOX(GTK_DIALOG(lv->window)->vbox), size_label, FALSE, FALSE, 0); | |
417 g_free(sz_txt); | |
418 g_free(text); | |
419 } | |
11402 | 420 |
11769 | 421 /* A fancy little box ************/ |
422 vbox = gtk_vbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
423 gtk_paned_add2(GTK_PANED(pane), vbox); | |
11402 | 424 |
11769 | 425 /* Viewer ************/ |
426 frame = gaim_gtk_create_imhtml(FALSE, &lv->imhtml, NULL); | |
427 gtk_widget_set_name(lv->imhtml, "gaim_gtklog_imhtml"); | |
428 gtk_widget_set_size_request(lv->imhtml, 320, 200); | |
429 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); | |
430 gtk_widget_show(frame); | |
10181 | 431 |
11769 | 432 /* Search box **********/ |
433 hbox = gtk_hbox_new(FALSE, GAIM_HIG_BOX_SPACE); | |
434 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
435 lv->entry = gtk_entry_new(); | |
436 gtk_box_pack_start(GTK_BOX(hbox), lv->entry, TRUE, TRUE, 0); | |
437 button = gtk_button_new_from_stock(GTK_STOCK_FIND); | |
438 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0); | |
439 g_signal_connect(GTK_ENTRY(lv->entry), "activate", G_CALLBACK(search_cb), lv); | |
440 g_signal_connect(GTK_BUTTON(button), "activate", G_CALLBACK(search_cb), lv); | |
441 g_signal_connect(GTK_BUTTON(button), "clicked", G_CALLBACK(search_cb), lv); | |
10175 | 442 |
11780 | 443 #if GTK_CHECK_VERSION(2,2,0) |
11769 | 444 /* Show most recent log **********/ |
445 path_to_first_log = gtk_tree_path_new_from_string("0:0"); | |
446 if (path_to_first_log) | |
447 { | |
448 gtk_tree_view_expand_to_path(GTK_TREE_VIEW(lv->treeview), path_to_first_log); | |
449 gtk_tree_selection_select_path(sel, path_to_first_log); | |
450 gtk_tree_path_free(path_to_first_log); | |
10663 | 451 } |
11780 | 452 #endif |
7432 | 453 |
454 gtk_widget_show_all(lv->window); | |
10663 | 455 |
456 return lv; | |
457 } | |
458 | |
459 void gaim_gtk_log_show(GaimLogType type, const char *screenname, GaimAccount *account) { | |
460 struct log_viewer_hash_t *ht = g_new0(struct log_viewer_hash_t, 1); | |
461 GaimGtkLogViewer *lv = NULL; | |
462 const char *name = screenname; | |
463 char *title; | |
464 | |
465 g_return_if_fail(account != NULL); | |
466 g_return_if_fail(screenname != NULL); | |
467 | |
468 ht->type = type; | |
469 ht->screenname = g_strdup(screenname); | |
470 ht->account = account; | |
471 | |
472 if (log_viewers == NULL) { | |
473 log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal); | |
474 } else if ((lv = g_hash_table_lookup(log_viewers, ht))) { | |
475 gtk_window_present(GTK_WINDOW(lv->window)); | |
476 g_free(ht); | |
477 return; | |
478 } | |
479 | |
480 if (type == GAIM_LOG_CHAT) { | |
481 GaimChat *chat; | |
482 | |
483 chat = gaim_blist_find_chat(account, screenname); | |
484 if (chat != NULL) | |
485 name = gaim_chat_get_name(chat); | |
486 | |
487 title = g_strdup_printf(_("Conversations in %s"), name); | |
488 } else { | |
489 GaimBuddy *buddy; | |
490 | |
491 buddy = gaim_find_buddy(account, screenname); | |
492 if (buddy != NULL) | |
493 name = gaim_buddy_get_contact_alias(buddy); | |
494 | |
495 title = g_strdup_printf(_("Conversations with %s"), name); | |
496 } | |
497 | |
498 display_log_viewer(ht, gaim_log_get_logs(type, screenname, account), | |
11585 | 499 title, gaim_gtk_create_prpl_icon(account), gaim_log_get_total_size(type, screenname, account)); |
10663 | 500 g_free(title); |
501 } | |
502 | |
503 void gaim_gtk_log_show_contact(GaimContact *contact) { | |
504 struct log_viewer_hash_t *ht = g_new0(struct log_viewer_hash_t, 1); | |
505 GaimBlistNode *child; | |
506 GaimGtkLogViewer *lv = NULL; | |
507 GList *logs = NULL; | |
508 char *filename; | |
509 GdkPixbuf *pixbuf; | |
510 const char *name = NULL; | |
511 char *title; | |
11585 | 512 int total_log_size = 0; |
10663 | 513 |
514 g_return_if_fail(contact != NULL); | |
515 | |
516 ht->type = GAIM_LOG_IM; | |
517 ht->contact = contact; | |
518 | |
519 if (log_viewers == NULL) { | |
520 log_viewers = g_hash_table_new(log_viewer_hash, log_viewer_equal); | |
521 } else if ((lv = g_hash_table_lookup(log_viewers, ht))) { | |
522 gtk_window_present(GTK_WINDOW(lv->window)); | |
523 g_free(ht); | |
524 return; | |
525 } | |
526 | |
527 for (child = contact->node.child ; child ; child = child->next) { | |
528 if (!GAIM_BLIST_NODE_IS_BUDDY(child)) | |
529 continue; | |
530 | |
11703
a53cef8bd22b
[gaim-migrate @ 13994]
Richard Laager <rlaager@wiktel.com>
parents:
11700
diff
changeset
|
531 logs = g_list_concat(gaim_log_get_logs(GAIM_LOG_IM, ((GaimBuddy *)child)->name, |
a53cef8bd22b
[gaim-migrate @ 13994]
Richard Laager <rlaager@wiktel.com>
parents:
11700
diff
changeset
|
532 ((GaimBuddy *)child)->account), logs); |
11585 | 533 total_log_size += gaim_log_get_total_size(GAIM_LOG_IM, ((GaimBuddy *)child)->name, ((GaimBuddy *)child)->account); |
10663 | 534 } |
535 logs = g_list_sort(logs, gaim_log_compare); | |
536 | |
537 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "icons", "online.png", NULL); | |
538 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); | |
539 g_free(filename); | |
540 | |
541 if (contact->alias != NULL) | |
542 name = contact->alias; | |
543 else if (contact->priority != NULL) | |
544 name = gaim_buddy_get_contact_alias(contact->priority); | |
545 | |
546 title = g_strdup_printf(_("Conversations with %s"), name); | |
11585 | 547 display_log_viewer(ht, logs, title, pixbuf, total_log_size); |
10663 | 548 g_free(title); |
7432 | 549 } |
8573 | 550 |
551 void gaim_gtk_syslog_show() | |
552 { | |
553 GList *accounts = NULL; | |
10663 | 554 GList *logs = NULL; |
8573 | 555 |
10181 | 556 if (syslog_viewer != NULL) { |
8573 | 557 gtk_window_present(GTK_WINDOW(syslog_viewer->window)); |
558 return; | |
559 } | |
560 | |
10663 | 561 for(accounts = gaim_accounts_get_all(); accounts != NULL; accounts = accounts->next) { |
8573 | 562 |
563 GaimAccount *account = (GaimAccount *)accounts->data; | |
10663 | 564 if(gaim_find_prpl(gaim_account_get_protocol_id(account)) == NULL) |
8573 | 565 continue; |
566 | |
11703
a53cef8bd22b
[gaim-migrate @ 13994]
Richard Laager <rlaager@wiktel.com>
parents:
11700
diff
changeset
|
567 logs = g_list_concat(gaim_log_get_system_logs(account), logs); |
8573 | 568 } |
10663 | 569 logs = g_list_sort(logs, gaim_log_compare); |
10175 | 570 |
11585 | 571 syslog_viewer = display_log_viewer(NULL, logs, _("System Log"), NULL, 0); |
8573 | 572 } |