pidgin/gtkconv.c

changeset 22064
8b35fd51087d
parent 22033
fed7e98db23f
child 22069
841d24b3a2bc
child 22078
296fd9a4ae86
equal deleted inserted replaced
22063:857aa10338af 22064:8b35fd51087d
65 #include "gtkprefs.h" 65 #include "gtkprefs.h"
66 #include "gtkprivacy.h" 66 #include "gtkprivacy.h"
67 #include "gtkthemes.h" 67 #include "gtkthemes.h"
68 #include "gtkutils.h" 68 #include "gtkutils.h"
69 #include "pidginstock.h" 69 #include "pidginstock.h"
70 #include "pidgintooltip.h"
70 71
71 #include "gtknickcolors.h" 72 #include "gtknickcolors.h"
72 73
73 #define CLOSE_CONV_TIMEOUT_SECS (10 * 60) 74 #define CLOSE_CONV_TIMEOUT_SECS (10 * 60)
74 75
162 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 163 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
163 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); 164 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
164 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); 165 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win);
165 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); 166 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv);
166 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); 167 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv);
167 static gboolean pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv);
168 static gboolean pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv);
169 static void hide_conv(PidginConversation *gtkconv, gboolean closetimer); 168 static void hide_conv(PidginConversation *gtkconv, gboolean closetimer);
170 169
171 static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y, 170 static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y,
172 int width, int height); 171 int width, int height);
173 172
4432 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", 4431 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event",
4433 G_CALLBACK(entry_key_press_cb), gtkconv); 4432 G_CALLBACK(entry_key_press_cb), gtkconv);
4434 } 4433 }
4435 } 4434 }
4436 4435
4436 static gboolean
4437 pidgin_conv_userlist_create_tooltip(GtkWidget *tipwindow, GtkTreePath *path,
4438 gpointer userdata, int *w, int *h)
4439 {
4440 PidginConversation *gtkconv = userdata;
4441 GtkTreeIter iter;
4442 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkconv->u.chat->list));
4443 PurpleConversation *conv = gtkconv->active_conv;
4444 PurpleBlistNode *node;
4445 PurplePluginProtocolInfo *prpl_info;
4446 PurpleAccount *account = purple_conversation_get_account(conv);
4447 char *who = NULL;
4448
4449 if (account->gc == NULL)
4450 return FALSE;
4451
4452 if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path))
4453 return FALSE;
4454
4455 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
4456
4457 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
4458 node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who));
4459 if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME))
4460 pidgin_blist_draw_tooltip(node, gtkconv->infopane);
4461
4462 g_free(who);
4463 return FALSE;
4464 }
4465
4437 static void 4466 static void
4438 setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned) 4467 setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned)
4439 { 4468 {
4440 PidginChatPane *gtkchat = gtkconv->u.chat; 4469 PidginChatPane *gtkchat = gtkconv->u.chat;
4441 GtkWidget *lbox, *sw, *list; 4470 GtkWidget *lbox, *sw, *list;
4486 if (ul_width == 0) 4515 if (ul_width == 0)
4487 gtk_paned_set_position(GTK_PANED(hpaned), 999999); 4516 gtk_paned_set_position(GTK_PANED(hpaned), 999999);
4488 4517
4489 g_signal_connect(G_OBJECT(list), "button_press_event", 4518 g_signal_connect(G_OBJECT(list), "button_press_event",
4490 G_CALLBACK(right_click_chat_cb), gtkconv); 4519 G_CALLBACK(right_click_chat_cb), gtkconv);
4491 g_signal_connect(G_OBJECT(list), "motion-notify-event",
4492 G_CALLBACK(pidgin_userlist_motion_cb), gtkconv);
4493 g_signal_connect(G_OBJECT(list), "leave-notify-event",
4494 G_CALLBACK(pidgin_conv_leave_cb), gtkconv);
4495 g_signal_connect(G_OBJECT(list), "popup-menu", 4520 g_signal_connect(G_OBJECT(list), "popup-menu",
4496 G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv); 4521 G_CALLBACK(gtkconv_chat_popup_menu_cb), gtkconv);
4497 g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv); 4522 g_signal_connect(G_OBJECT(lbox), "size-allocate", G_CALLBACK(lbox_size_allocate_cb), gtkconv);
4523
4524 pidgin_tooltip_setup_for_treeview(list, gtkconv,
4525 pidgin_conv_userlist_create_tooltip, NULL);
4498 4526
4499 rend = gtk_cell_renderer_text_new(); 4527 rend = gtk_cell_renderer_text_new();
4500 g_object_set(rend, 4528 g_object_set(rend,
4501 "foreground-set", TRUE, 4529 "foreground-set", TRUE,
4502 "weight-set", TRUE, 4530 "weight-set", TRUE,
4529 gtkchat->list = list; 4557 gtkchat->list = list;
4530 4558
4531 gtk_container_add(GTK_CONTAINER(sw), list); 4559 gtk_container_add(GTK_CONTAINER(sw), list);
4532 } 4560 }
4533 4561
4534 /* Stuff used to display tooltips on the infopane */
4535 static struct {
4536 int timeout;
4537 PidginConversation *gtkconv; /* This is the Pidgin conversation that
4538 triggered the tooltip */
4539 int userlistx;
4540 int userlisty;
4541 } tooltip;
4542
4543 static void
4544 reset_tooltip()
4545 {
4546 if (tooltip.timeout != 0) {
4547 g_source_remove(tooltip.timeout);
4548 tooltip.timeout = 0;
4549 }
4550 tooltip.gtkconv = NULL;
4551 }
4552
4553 static gboolean 4562 static gboolean
4554 pidgin_conv_tooltip_timeout(PidginConversation *gtkconv) 4563 pidgin_conv_create_tooltip(GtkWidget *tipwindow, gpointer userdata, int *w, int *h)
4555 { 4564 {
4556 PurpleBlistNode *node = NULL; 4565 PurpleBlistNode *node = NULL;
4557 PurpleConversation *conv; 4566 PurpleConversation *conv;
4558 4567 PidginConversation *gtkconv = userdata;
4559 g_return_val_if_fail (tooltip.gtkconv == gtkconv, FALSE);
4560 4568
4561 conv = gtkconv->active_conv; 4569 conv = gtkconv->active_conv;
4562 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 4570 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
4563 node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name)); 4571 node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name));
4564 #if 0 4572 #if 0
4577 if (node) 4585 if (node)
4578 pidgin_blist_draw_tooltip(node, gtkconv->infopane); 4586 pidgin_blist_draw_tooltip(node, gtkconv->infopane);
4579 return FALSE; 4587 return FALSE;
4580 } 4588 }
4581 4589
4582 static gboolean
4583 pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv)
4584 {
4585 pidgin_blist_tooltip_destroy();
4586 reset_tooltip();
4587 return FALSE;
4588 }
4589
4590 static gboolean
4591 pidgin_conv_motion_cb (GtkWidget *infopane, GdkEventMotion *event, PidginConversation *gtkconv)
4592 {
4593 int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay");
4594
4595 pidgin_blist_tooltip_destroy();
4596 if (delay == 0)
4597 return FALSE;
4598
4599 if (tooltip.timeout != 0)
4600 g_source_remove(tooltip.timeout);
4601
4602 tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_conv_tooltip_timeout, gtkconv);
4603 tooltip.gtkconv = gtkconv;
4604 return FALSE;
4605 }
4606
4607 static gboolean
4608 pidgin_userlist_tooltip_timeout(PidginConversation *gtkconv)
4609 {
4610 PurplePluginProtocolInfo *prpl_info;
4611 PurpleConversation *conv = gtkconv->active_conv;
4612 PidginChatPane *gtkchat;
4613 PurpleBlistNode *node = NULL;
4614 PurpleAccount *account;
4615 GtkTreePath *path;
4616 GtkTreeIter iter;
4617 GtkTreeModel *model;
4618 GtkTreeViewColumn *column;
4619 gchar *who;
4620 int x, y;
4621
4622 gtkchat = gtkconv->u.chat;
4623 account = purple_conversation_get_account(conv);
4624
4625 if (account->gc == NULL)
4626 return FALSE;
4627
4628 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
4629
4630 model = gtk_tree_view_get_model(GTK_TREE_VIEW(gtkchat->list));
4631
4632 if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(gtkchat->list),
4633 tooltip.userlistx, tooltip.userlisty, &path, &column, &x, &y))
4634 return FALSE;
4635
4636 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
4637 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
4638
4639 node = (PurpleBlistNode*)(purple_find_buddy(conv->account, who));
4640 if (node && prpl_info && (prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME))
4641 pidgin_blist_draw_tooltip(node, gtkconv->infopane);
4642
4643 g_free(who);
4644 gtk_tree_path_free(path);
4645
4646
4647 return FALSE;
4648 }
4649
4650 static gboolean
4651 pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv)
4652 {
4653 PurpleConversation *conv;
4654 PurpleAccount *account;
4655 int delay = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/blist/tooltip_delay");
4656
4657 pidgin_blist_tooltip_destroy();
4658 if (delay == 0)
4659 return FALSE;
4660
4661 if (tooltip.timeout != 0)
4662 g_source_remove(tooltip.timeout);
4663 tooltip.timeout = 0;
4664
4665 conv = gtkconv->active_conv;
4666 account = purple_conversation_get_account(conv);
4667
4668 if (account->gc == NULL)
4669 return FALSE;
4670
4671 tooltip.timeout = g_timeout_add(delay, (GSourceFunc)pidgin_userlist_tooltip_timeout, gtkconv);
4672 tooltip.gtkconv = gtkconv;
4673 tooltip.userlistx = event->x;
4674 tooltip.userlisty = event->y;
4675
4676 return FALSE;
4677 }
4678
4679 static GtkWidget * 4590 static GtkWidget *
4680 setup_common_pane(PidginConversation *gtkconv) 4591 setup_common_pane(PidginConversation *gtkconv)
4681 { 4592 {
4682 GtkWidget *vbox, *frame, *imhtml_sw, *event_box; 4593 GtkWidget *vbox, *frame, *imhtml_sw, *event_box;
4683 GtkCellRenderer *rend; 4594 GtkCellRenderer *rend;
4703 gtk_widget_add_events(event_box, 4614 gtk_widget_add_events(event_box,
4704 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); 4615 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
4705 g_signal_connect(G_OBJECT(event_box), "button-press-event", 4616 g_signal_connect(G_OBJECT(event_box), "button-press-event",
4706 G_CALLBACK(infopane_press_cb), gtkconv); 4617 G_CALLBACK(infopane_press_cb), gtkconv);
4707 4618
4708 g_signal_connect(G_OBJECT(event_box), "motion-notify-event", 4619 pidgin_tooltip_setup_for_widget(event_box, gtkconv,
4709 G_CALLBACK(pidgin_conv_motion_cb), gtkconv); 4620 pidgin_conv_create_tooltip, NULL);
4710 g_signal_connect(G_OBJECT(event_box), "leave-notify-event",
4711 G_CALLBACK(pidgin_conv_leave_cb), gtkconv);
4712 4621
4713 gtkconv->infopane = gtk_cell_view_new(); 4622 gtkconv->infopane = gtk_cell_view_new();
4714 gtkconv->infopane_model = gtk_list_store_new(CONV_NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF); 4623 gtkconv->infopane_model = gtk_list_store_new(CONV_NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF, GDK_TYPE_PIXBUF);
4715 gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane), 4624 gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane),
4716 GTK_TREE_MODEL(gtkconv->infopane_model)); 4625 GTK_TREE_MODEL(gtkconv->infopane_model));
5211 g_list_free(gtkconv->send_history); 5120 g_list_free(gtkconv->send_history);
5212 5121
5213 if (gtkconv->attach.timer) { 5122 if (gtkconv->attach.timer) {
5214 g_source_remove(gtkconv->attach.timer); 5123 g_source_remove(gtkconv->attach.timer);
5215 } 5124 }
5216
5217 if (tooltip.gtkconv == gtkconv)
5218 reset_tooltip();
5219 5125
5220 g_free(gtkconv); 5126 g_free(gtkconv);
5221 } 5127 }
5222 5128
5223 5129
6923 #endif 6829 #endif
6924 gtk_widget_add_events(event, 6830 gtk_widget_add_events(event,
6925 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); 6831 GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
6926 g_signal_connect(G_OBJECT(event), "button-press-event", 6832 g_signal_connect(G_OBJECT(event), "button-press-event",
6927 G_CALLBACK(icon_menu), gtkconv); 6833 G_CALLBACK(icon_menu), gtkconv);
6928 g_signal_connect(G_OBJECT(event), "motion-notify-event", 6834
6929 G_CALLBACK(pidgin_conv_motion_cb), gtkconv); 6835 pidgin_tooltip_setup_for_widget(event, gtkconv, pidgin_conv_create_tooltip, NULL);
6930 g_signal_connect(G_OBJECT(event), "leave-notify-event",
6931 G_CALLBACK(pidgin_conv_leave_cb), gtkconv);
6932 gtk_widget_show(event); 6836 gtk_widget_show(event);
6933 6837
6934 gtkconv->u.im->icon = gtk_image_new_from_pixbuf(scale); 6838 gtkconv->u.im->icon = gtk_image_new_from_pixbuf(scale);
6935 gtk_container_add(GTK_CONTAINER(event), gtkconv->u.im->icon); 6839 gtk_container_add(GTK_CONTAINER(event), gtkconv->u.im->icon);
6936 gtk_widget_show(gtkconv->u.im->icon); 6840 gtk_widget_show(gtkconv->u.im->icon);

mercurial