| 218 gpointer data) |
224 gpointer data) |
| 219 { |
225 { |
| 220 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data), GPOINTER_TO_INT(value)); |
226 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data), GPOINTER_TO_INT(value)); |
| 221 } |
227 } |
| 222 |
228 |
| |
229 static void |
| |
230 filter_cb(GtkToggleButton *button, DebugWindow *win) |
| |
231 { |
| |
232 if (gtk_toggle_button_get_active(button)) { |
| |
233 filter_enabled = TRUE; |
| |
234 } else { |
| |
235 filter_enabled = FALSE; |
| |
236 } |
| |
237 } |
| |
238 |
| |
239 static void |
| |
240 debug_liststore_append(gpointer key, gpointer value, gpointer user_data) |
| |
241 { |
| |
242 GtkTreeIter iter; |
| |
243 GtkListStore **liststore = (GtkListStore **)user_data; |
| |
244 |
| |
245 gtk_list_store_append(*liststore, &iter); |
| |
246 gtk_list_store_set(*liststore, &iter, 0, key, -1); |
| |
247 } |
| |
248 |
| 223 static DebugWindow * |
249 static DebugWindow * |
| 224 debug_window_new(void) |
250 debug_window_new(void) |
| 225 { |
251 { |
| 226 DebugWindow *win; |
252 DebugWindow *win; |
| 227 GtkWidget *vbox; |
253 GtkWidget *vbox; |
| 228 GtkWidget *toolbar; |
254 GtkWidget *toolbar; |
| 229 GtkWidget *frame; |
255 GtkWidget *frame; |
| 230 GtkWidget *button; |
256 GtkWidget *button; |
| 231 GtkWidget *image; |
257 GtkWidget *image; |
| |
258 GtkListStore *liststore = NULL; |
| |
259 GtkCellRenderer *renderer = NULL; |
| |
260 GtkTreeSelection *selection = NULL; |
| |
261 GtkTreeViewColumn *column = NULL; |
| 232 int width, height; |
262 int width, height; |
| 233 |
263 |
| 234 win = g_new0(DebugWindow, 1); |
264 win = g_new0(DebugWindow, 1); |
| 235 |
265 |
| 236 width = gaim_prefs_get_int("/gaim/gtk/debug/width"); |
266 width = gaim_prefs_get_int("/gaim/gtk/debug/width"); |
| 237 height = gaim_prefs_get_int("/gaim/gtk/debug/height"); |
267 height = gaim_prefs_get_int("/gaim/gtk/debug/height"); |
| 238 |
268 |
| 239 GAIM_DIALOG(win->window); |
269 GAIM_DIALOG(win->window); |
| 240 gaim_debug_info("gtkdebug", "Setting dimensions to %d, %d\n", |
270 gaim_debug_info("gtkdebug", "Setting dimensions to %d, %d\n", |
| 241 width, height); |
271 width, height); |
| 242 |
272 |
| 243 gtk_window_set_default_size(GTK_WINDOW(win->window), width, height); |
273 gtk_window_set_default_size(GTK_WINDOW(win->window), width, height); |
| 244 gtk_window_set_role(GTK_WINDOW(win->window), "debug"); |
274 gtk_window_set_role(GTK_WINDOW(win->window), "debug"); |
| 245 gtk_window_set_title(GTK_WINDOW(win->window), _("Debug Window")); |
275 gtk_window_set_title(GTK_WINDOW(win->window), _("Debug Window")); |
| 246 |
276 |
| 247 g_signal_connect(G_OBJECT(win->window), "delete_event", |
277 g_signal_connect(G_OBJECT(win->window), "delete_event", |
| 248 G_CALLBACK(debug_window_destroy), NULL); |
278 G_CALLBACK(debug_window_destroy), NULL); |
| 249 g_signal_connect(G_OBJECT(win->window), "configure_event", |
279 g_signal_connect(G_OBJECT(win->window), "configure_event", |
| 250 G_CALLBACK(configure_cb), win); |
280 G_CALLBACK(configure_cb), win); |
| 251 |
281 |
| 252 /* Setup the vbox */ |
282 /* Setup the vbox */ |
| 253 vbox = gtk_vbox_new(FALSE, 0); |
283 vbox = gtk_vbox_new(FALSE, 0); |
| 254 gtk_container_add(GTK_CONTAINER(win->window), vbox); |
284 gtk_container_add(GTK_CONTAINER(win->window), vbox); |
| 255 |
285 |
| 256 if (gaim_prefs_get_bool("/gaim/gtk/debug/toolbar")) { |
286 if (gaim_prefs_get_bool("/gaim/gtk/debug/toolbar")) { |
| 257 /* Setup our top button bar thingie. */ |
287 /* Setup our top button bar thingie. */ |
| 258 toolbar = gtk_toolbar_new(); |
288 toolbar = gtk_toolbar_new(); |
| 259 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH_HORIZ); |
289 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), |
| |
290 GTK_TOOLBAR_BOTH_HORIZ); |
| 260 gtk_toolbar_set_icon_size(GTK_TOOLBAR(toolbar), |
291 gtk_toolbar_set_icon_size(GTK_TOOLBAR(toolbar), |
| 261 GTK_ICON_SIZE_SMALL_TOOLBAR); |
292 GTK_ICON_SIZE_SMALL_TOOLBAR); |
| 262 |
293 |
| 263 gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0); |
294 gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0); |
| 264 |
295 |
| 265 /* Find button */ |
296 /* Find button */ |
| 266 gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_FIND, |
297 gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_FIND, |
| 267 NULL, NULL, G_CALLBACK(find_cb), win, -1); |
298 NULL, NULL, G_CALLBACK(find_cb), |
| |
299 win, -1); |
| 268 |
300 |
| 269 /* Save */ |
301 /* Save */ |
| 270 gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_SAVE, |
302 gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_SAVE, |
| 271 NULL, NULL, G_CALLBACK(save_cb), win, -1); |
303 NULL, NULL, G_CALLBACK(save_cb), |
| |
304 win, -1); |
| 272 |
305 |
| 273 /* Clear button */ |
306 /* Clear button */ |
| 274 gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_CLEAR, |
307 gtk_toolbar_insert_stock(GTK_TOOLBAR(toolbar), GTK_STOCK_CLEAR, |
| 275 NULL, NULL, G_CALLBACK(clear_cb), win, -1); |
308 NULL, NULL, G_CALLBACK(clear_cb), |
| |
309 win, -1); |
| 276 |
310 |
| 277 gtk_toolbar_insert_space(GTK_TOOLBAR(toolbar), -1); |
311 gtk_toolbar_insert_space(GTK_TOOLBAR(toolbar), -1); |
| 278 |
312 |
| 279 /* Pause */ |
313 /* Pause */ |
| 280 image = gtk_image_new_from_stock(GAIM_STOCK_PAUSE, GTK_ICON_SIZE_MENU); |
314 image = gtk_image_new_from_stock(GAIM_STOCK_PAUSE, GTK_ICON_SIZE_MENU); |
| 281 button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), |
315 button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), |
| 282 GTK_TOOLBAR_CHILD_TOGGLEBUTTON, |
316 GTK_TOOLBAR_CHILD_TOGGLEBUTTON, |
| 283 NULL, _("Pause"), NULL, NULL, |
317 NULL, _("Pause"), NULL, |
| 284 image, G_CALLBACK(pause_cb), win); |
318 NULL, image, |
| |
319 G_CALLBACK(pause_cb), win); |
| 285 |
320 |
| 286 /* Timestamps */ |
321 /* Timestamps */ |
| 287 button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), |
322 button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), |
| 288 GTK_TOOLBAR_CHILD_TOGGLEBUTTON, |
323 GTK_TOOLBAR_CHILD_TOGGLEBUTTON, |
| 289 NULL, _("Timestamps"), NULL, NULL, |
324 NULL, _("Timestamps"), |
| 290 NULL, G_CALLBACK(timestamps_cb), |
325 NULL, NULL, NULL, |
| 291 win); |
326 G_CALLBACK(timestamps_cb), |
| |
327 win); |
| 292 |
328 |
| 293 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), |
329 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), |
| 294 gaim_prefs_get_bool("/core/debug/timestamps")); |
330 gaim_prefs_get_bool("/core/debug/timestamps")); |
| 295 |
331 |
| 296 gaim_prefs_connect_callback(gaim_gtk_debug_get_handle(), "/core/debug/timestamps", |
332 gaim_prefs_connect_callback(gaim_gtk_debug_get_handle(), |
| 297 timestamps_pref_cb, button); |
333 "/core/debug/timestamps", |
| |
334 timestamps_pref_cb, button); |
| |
335 |
| |
336 button = gtk_check_button_new_with_label(_("Filter")); |
| |
337 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(filter_cb), win); |
| |
338 button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), |
| |
339 GTK_TOOLBAR_CHILD_WIDGET, |
| |
340 button, NULL, NULL, NULL, |
| |
341 NULL, NULL, NULL); |
| |
342 |
| |
343 button = gtk_scrolled_window_new(NULL, NULL); |
| |
344 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(button), |
| |
345 GTK_POLICY_NEVER, |
| |
346 GTK_POLICY_AUTOMATIC); |
| |
347 |
| |
348 liststore = gtk_list_store_new(1, G_TYPE_STRING); |
| |
349 win->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore)); |
| |
350 renderer = gtk_cell_renderer_text_new(); |
| |
351 column = gtk_tree_view_column_new_with_attributes(_("Filter"), renderer, "text", 0, NULL); |
| |
352 |
| |
353 gtk_tree_view_append_column(GTK_TREE_VIEW(win->treeview), column); |
| |
354 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(win->treeview), FALSE); |
| |
355 gtk_tree_view_set_fixed_height_mode(GTK_TREE_VIEW(win->treeview), TRUE); |
| |
356 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(liststore), 0, GTK_SORT_ASCENDING); |
| |
357 |
| |
358 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(win->treeview)); |
| |
359 gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE); |
| |
360 |
| |
361 g_hash_table_foreach(debug_categories, (GHFunc)debug_liststore_append, &liststore); |
| |
362 |
| |
363 gtk_container_add(GTK_CONTAINER(button), win->treeview); |
| |
364 button = gtk_toolbar_append_element(GTK_TOOLBAR(toolbar), |
| |
365 GTK_TOOLBAR_CHILD_WIDGET, |
| |
366 button, NULL, NULL, |
| |
367 NULL, NULL, NULL, NULL); |
| 298 } |
368 } |
| 299 |
369 |
| 300 /* Add the gtkimhtml */ |
370 /* Add the gtkimhtml */ |
| 301 frame = gaim_gtk_create_imhtml(FALSE, &win->text, NULL); |
371 frame = gaim_gtk_create_imhtml(FALSE, &win->text, NULL); |
| 302 gtk_imhtml_set_format_functions(GTK_IMHTML(win->text), |
372 gtk_imhtml_set_format_functions(GTK_IMHTML(win->text), |
| 435 debug_window_destroy(NULL, NULL, NULL); |
515 debug_window_destroy(NULL, NULL, NULL); |
| 436 } |
516 } |
| 437 } |
517 } |
| 438 |
518 |
| 439 static void |
519 static void |
| |
520 create_debug_selected_categories(GtkTreeModel *model, GtkTreePath *path, |
| |
521 GtkTreeIter *iter, gpointer data) |
| |
522 { |
| |
523 GHashTable **hashtable = (GHashTable **)data; |
| |
524 char *text = NULL; |
| |
525 |
| |
526 gtk_tree_model_get(model, iter, 0, &text, -1); |
| |
527 |
| |
528 g_hash_table_insert(*hashtable, text, NULL); |
| |
529 } |
| |
530 |
| |
531 static gboolean |
| |
532 debug_is_filtered_out(const char *category) |
| |
533 { |
| |
534 GtkTreeSelection *selection = NULL; |
| |
535 GHashTable *hashtable = NULL; |
| |
536 gboolean found = FALSE; |
| |
537 |
| |
538 if (category == NULL) |
| |
539 return FALSE; |
| |
540 |
| |
541 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(debug_win->treeview)); |
| |
542 hashtable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, |
| |
543 NULL); |
| |
544 |
| |
545 gtk_tree_selection_selected_foreach(selection, |
| |
546 create_debug_selected_categories, |
| |
547 &hashtable); |
| |
548 |
| |
549 if (filter_enabled) { |
| |
550 if (g_hash_table_lookup_extended(hashtable, category, NULL, NULL)) |
| |
551 found = FALSE; |
| |
552 else |
| |
553 found = TRUE; |
| |
554 } |
| |
555 |
| |
556 g_hash_table_destroy(hashtable); |
| |
557 return found; |
| |
558 } |
| |
559 |
| |
560 static void |
| 440 gaim_gtk_debug_print(GaimDebugLevel level, const char *category, |
561 gaim_gtk_debug_print(GaimDebugLevel level, const char *category, |
| 441 const char *format, va_list args) |
562 const char *format, va_list args) |
| 442 { |
563 { |
| 443 gboolean timestamps; |
564 gboolean timestamps; |
| 444 gchar *arg_s, *ts_s; |
565 gchar *arg_s, *ts_s; |
| 445 gchar *esc_s, *cat_s, *tmp, *s; |
566 gchar *esc_s, *cat_s, *tmp, *s; |
| 446 |
567 |
| 447 if (!gaim_prefs_get_bool("/gaim/gtk/debug/enabled") || |
568 if (!gaim_prefs_get_bool("/gaim/gtk/debug/enabled") || |
| 448 (debug_win == NULL) || debug_win->paused) { |
569 (debug_win == NULL) || debug_win->paused || |
| |
570 debug_is_filtered_out(category)) { |
| 449 return; |
571 return; |
| 450 } |
572 } |
| 451 |
573 |
| 452 timestamps = gaim_prefs_get_bool("/core/debug/timestamps"); |
574 timestamps = gaim_prefs_get_bool("/core/debug/timestamps"); |
| 453 |
575 |
| 454 arg_s = g_strdup_vprintf(format, args); |
576 arg_s = g_strdup_vprintf(format, args); |
| 455 |
577 |
| 456 /* |
578 /* |
| 457 * For some reason we only print the timestamp if category is |
579 * For some reason we only print the timestamp if category is |
| 458 * not NULL. Why the hell do we do that? --Mark |
580 * not NULL. Why the hell do we do that? --Mark |
| 459 */ |
581 */ |
| 460 if ((category != NULL) && (timestamps)) { |
582 if ((category != NULL) && (timestamps)) { |
| 461 gchar mdate[64]; |
583 gchar mdate[64]; |
| 462 |
584 |
| 463 time_t mtime = time(NULL); |
585 time_t mtime = time(NULL); |
| 496 gtk_imhtml_append_text(GTK_IMHTML(debug_win->text), s, 0); |
618 gtk_imhtml_append_text(GTK_IMHTML(debug_win->text), s, 0); |
| 497 |
619 |
| 498 g_free(s); |
620 g_free(s); |
| 499 } |
621 } |
| 500 |
622 |
| |
623 static void |
| |
624 gaim_gtk_debug_register_category(const char *category) |
| |
625 { |
| |
626 /* XXX I'd like to be able to put this creation in _init, but that |
| |
627 * would require that this be init:ed before anything that wants to |
| |
628 * register a category, and I'm not sure I can count on this coming |
| |
629 * first */ |
| |
630 if (debug_categories == NULL) |
| |
631 debug_categories = g_hash_table_new_full(g_str_hash, |
| |
632 g_str_equal, |
| |
633 g_free, NULL); |
| |
634 |
| |
635 if (!g_hash_table_lookup_extended(debug_categories, category, NULL, NULL)) { |
| |
636 g_hash_table_insert(debug_categories, g_strdup(category), NULL); |
| |
637 |
| |
638 if (debug_win != NULL && debug_win->treeview != NULL) { |
| |
639 GtkTreeModel *model = NULL; |
| |
640 GtkTreeIter iter; |
| |
641 |
| |
642 model = gtk_tree_view_get_model(GTK_TREE_VIEW(debug_win->treeview)); |
| |
643 |
| |
644 gtk_list_store_append(GTK_LIST_STORE(model), &iter); |
| |
645 gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0, |
| |
646 category, -1); |
| |
647 } |
| |
648 } |
| |
649 } |
| |
650 |
| |
651 static gboolean |
| |
652 find_and_remove_category(GtkTreeModel *model, GtkTreePath *path, |
| |
653 GtkTreeIter *iter, gpointer data) |
| |
654 { |
| |
655 GValue value = {0}; |
| |
656 |
| |
657 gtk_tree_model_get_value(model, iter, 0, &value); |
| |
658 |
| |
659 if (strcmp(g_value_get_string(&value), data) == 0) { |
| |
660 gtk_list_store_remove(GTK_LIST_STORE(model), iter); |
| |
661 |
| |
662 return TRUE; |
| |
663 } |
| |
664 |
| |
665 return FALSE; |
| |
666 } |
| |
667 |
| |
668 static void |
| |
669 gaim_gtk_debug_unregister_category(const char *category) |
| |
670 { |
| |
671 GtkTreeModel *model = NULL; |
| |
672 |
| |
673 model = gtk_tree_view_get_model(GTK_TREE_VIEW(debug_win->treeview)); |
| |
674 |
| |
675 gtk_tree_model_foreach(model, |
| |
676 (GtkTreeModelForeachFunc)find_and_remove_category, |
| |
677 (char *)category); |
| |
678 |
| |
679 g_hash_table_remove(debug_categories, category); |
| |
680 } |
| |
681 |
| 501 static GaimDebugUiOps ops = |
682 static GaimDebugUiOps ops = |
| 502 { |
683 { |
| 503 gaim_gtk_debug_print |
684 gaim_gtk_debug_print, |
| |
685 gaim_gtk_debug_register_category, |
| |
686 gaim_gtk_debug_unregister_category |
| 504 }; |
687 }; |
| 505 |
688 |
| 506 GaimDebugUiOps * |
689 GaimDebugUiOps * |
| 507 gaim_gtk_debug_get_ui_ops(void) |
690 gaim_gtk_debug_get_ui_ops(void) |
| 508 { |
691 { |