comparison pidgin/gtkconv.c @ 27746:e13759a83714

propagate from branch 'im.pidgin.pidgin' (head cff05fbceab1d88163770d13a4c7a6116bdeb8ee) to branch 'im.pidgin.pidgin.yaz' (head 4c2ca466febbc129edc2012fd6ce5769696116d0)
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Sat, 15 Dec 2007 05:15:31 +0000
parents b9197011ddd6 a53f4b1813df
children 2be2eec7d273
comparison
equal deleted inserted replaced
27745:b9197011ddd6 27746:e13759a83714
127 } InviteBuddyInfo; 127 } InviteBuddyInfo;
128 128
129 static GtkWidget *invite_dialog = NULL; 129 static GtkWidget *invite_dialog = NULL;
130 static GtkWidget *warn_close_dialog = NULL; 130 static GtkWidget *warn_close_dialog = NULL;
131 131
132 static PidginWindow *hidden_convwin = NULL;
132 static GList *window_list = NULL; 133 static GList *window_list = NULL;
133 134
134 /* Lists of status icons at all available sizes for use as window icons */ 135 /* Lists of status icons at all available sizes for use as window icons */
135 static GList *available_list = NULL; 136 static GList *available_list = NULL;
136 static GList *away_list = NULL; 137 static GList *away_list = NULL;
1377 if (timer) 1378 if (timer)
1378 purple_timeout_remove(timer); 1379 purple_timeout_remove(timer);
1379 timer = purple_timeout_add_seconds(CLOSE_CONV_TIMEOUT_SECS, close_already, conv); 1380 timer = purple_timeout_add_seconds(CLOSE_CONV_TIMEOUT_SECS, close_already, conv);
1380 purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(timer)); 1381 purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(timer));
1381 } 1382 }
1383 #if 0
1384 /* I will miss you */
1382 purple_conversation_set_ui_ops(conv, NULL); 1385 purple_conversation_set_ui_ops(conv, NULL);
1386 #else
1387 pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
1388 pidgin_conv_window_add_gtkconv(hidden_convwin, gtkconv);
1389 #endif
1383 } 1390 }
1384 } 1391 }
1385 1392
1386 static void 1393 static void
1387 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) 1394 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget)
2818 GdkModifierType state; 2825 GdkModifierType state;
2819 2826
2820 if (gtkconv == NULL) { 2827 if (gtkconv == NULL) {
2821 pidgin_conv_attach_to_conversation(conv); 2828 pidgin_conv_attach_to_conversation(conv);
2822 gtkconv = PIDGIN_CONVERSATION(conv); 2829 gtkconv = PIDGIN_CONVERSATION(conv);
2830 } else if (gtkconv->win == hidden_convwin) {
2831 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
2832 pidgin_conv_placement_place(gtkconv);
2823 } 2833 }
2824 2834
2825 pidgin_conv_switch_active_conversation(conv); 2835 pidgin_conv_switch_active_conversation(conv);
2826 /* Switch the tab only if the user initiated the event by pressing 2836 /* Switch the tab only if the user initiated the event by pressing
2827 * a button or hitting a key. */ 2837 * a button or hitting a key. */
2850 2860
2851 for (; l != NULL && (max_count == 0 || c < max_count); l = l->next) { 2861 for (; l != NULL && (max_count == 0 || c < max_count); l = l->next) {
2852 PurpleConversation *conv = (PurpleConversation*)l->data; 2862 PurpleConversation *conv = (PurpleConversation*)l->data;
2853 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 2863 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
2854 2864
2855 if (gtkconv != NULL && gtkconv->active_conv != conv) 2865 if(gtkconv == NULL || gtkconv->active_conv != conv)
2856 continue; 2866 continue;
2857 if (gtkconv == NULL) { 2867
2858 if (!purple_conversation_get_data(conv, "unseen-count") || 2868 if (gtkconv->unseen_state >= min_state
2859 !purple_conversation_get_data(conv, "unseen-state") || 2869 && (!hidden_only ||
2860 GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state"))<min_state) 2870 (hidden_only && gtkconv->win == hidden_convwin))) {
2861 continue; 2871
2862 r = g_list_prepend(r, conv); 2872 r = g_list_prepend(r, conv);
2863 c++; 2873 c++;
2864 } else {
2865 if (gtkconv->unseen_state >= min_state && !hidden_only) {
2866 r = g_list_prepend(r, conv);
2867 c++;
2868 }
2869 } 2874 }
2870 } 2875 }
2871 2876
2872 return r; 2877 return r;
2873 } 2878 }
2906 2911
2907 GtkWidget *icon = gtk_image_new(); 2912 GtkWidget *icon = gtk_image_new();
2908 GdkPixbuf *pbuf = pidgin_conv_get_icon(conv, icon, PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC); 2913 GdkPixbuf *pbuf = pidgin_conv_get_icon(conv, icon, PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC);
2909 GtkWidget *item; 2914 GtkWidget *item;
2910 gchar *text = g_strdup_printf("%s (%d)", 2915 gchar *text = g_strdup_printf("%s (%d)",
2911 gtkconv ? gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)) : purple_conversation_get_name(conv), 2916 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)),
2912 gtkconv ? gtkconv->unseen_count : GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))); 2917 gtkconv->unseen_count);
2913 2918
2914 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf); 2919 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf);
2915 g_object_unref(pbuf); 2920 g_object_unref(pbuf);
2916 2921
2917 item = gtk_image_menu_item_new_with_label(text); 2922 item = gtk_image_menu_item_new_with_label(text);
3181 GList *list; 3186 GList *list;
3182 PidginConversation *gtkconv; 3187 PidginConversation *gtkconv;
3183 PurpleConversation *conv; 3188 PurpleConversation *conv;
3184 GtkWidget *item; 3189 GtkWidget *item;
3185 3190
3186 if (win->window == NULL) 3191 if (win->window == NULL || win == hidden_convwin)
3187 return; 3192 return;
3188 3193
3189 gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3194 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3190 if (gtkconv == NULL) 3195 if (gtkconv == NULL)
3191 return; 3196 return;
4421 4426
4422 pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry)); 4427 pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry));
4423 pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry)); 4428 pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry));
4424 pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry)); 4429 pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry));
4425 4430
4426 height = (oneline.height + pad_top + pad_bottom) * lines; 4431 height = (oneline.height + pad_top + pad_bottom) * MAX(lines, 2);
4427 height += (oneline.height + pad_inside) * (wrapped_lines - lines); 4432 height += (oneline.height + pad_inside) * (wrapped_lines - lines);
4428 4433
4429 gtkconv->auto_resize = TRUE; 4434 gtkconv->auto_resize = TRUE;
4430 g_idle_add(reset_auto_resize_cb, gtkconv); 4435 g_idle_add(reset_auto_resize_cb, gtkconv);
4431 4436
4453 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); 4458 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
4454 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) 4459 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC)
4455 { 4460 {
4456 GtkWidget *hbox, *label; 4461 GtkWidget *hbox, *label;
4457 PidginChatPane *gtkchat = gtkconv->u.chat; 4462 PidginChatPane *gtkchat = gtkconv->u.chat;
4458 4463
4459 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 4464 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
4460 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); 4465 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
4461 4466
4462 label = gtk_label_new(_("Topic:")); 4467 label = gtk_label_new(_("Topic:"));
4463 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); 4468 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
4602 g_return_val_if_fail (tooltip.gtkconv == gtkconv, FALSE); 4607 g_return_val_if_fail (tooltip.gtkconv == gtkconv, FALSE);
4603 4608
4604 conv = gtkconv->active_conv; 4609 conv = gtkconv->active_conv;
4605 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 4610 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
4606 node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name)); 4611 node = (PurpleBlistNode*)(purple_blist_find_chat(conv->account, conv->name));
4612 #if 0
4613 /* Using the transient blist nodes to show the tooltip doesn't quite work yet. */
4614 if (!node)
4615 node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_chat");
4616 #endif
4607 } else { 4617 } else {
4608 node = (PurpleBlistNode*)(purple_find_buddy(conv->account, conv->name)); 4618 node = (PurpleBlistNode*)(purple_find_buddy(conv->account, conv->name));
4609 } 4619 #if 0
4610 4620 if (!node)
4611 if (node) 4621 node = g_object_get_data(G_OBJECT(gtkconv->imhtml), "transient_buddy");
4622 #endif
4623 }
4624
4625 if (node)
4612 pidgin_blist_draw_tooltip(node, gtkconv->infopane); 4626 pidgin_blist_draw_tooltip(node, gtkconv->infopane);
4613 return FALSE; 4627 return FALSE;
4614 } 4628 }
4615 4629
4616 static void 4630 static void
4617 pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv) 4631 pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv)
4618 { 4632 {
4619 pidgin_blist_tooltip_destroy(); 4633 pidgin_blist_tooltip_destroy();
4620 reset_tooltip(); 4634 reset_tooltip();
4621 } 4635 }
5048 PurpleConversationType conv_type = purple_conversation_get_type(conv); 5062 PurpleConversationType conv_type = purple_conversation_get_type(conv);
5049 GtkWidget *pane = NULL; 5063 GtkWidget *pane = NULL;
5050 GtkWidget *tab_cont; 5064 GtkWidget *tab_cont;
5051 PurpleBlistNode *convnode; 5065 PurpleBlistNode *convnode;
5052 5066
5053 if (hidden)
5054 return;
5055
5056 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) { 5067 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
5057 conv->ui_data = gtkconv; 5068 conv->ui_data = gtkconv;
5058 if (!g_list_find(gtkconv->convs, conv)) 5069 if (!g_list_find(gtkconv->convs, conv))
5059 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); 5070 gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
5060 pidgin_conv_switch_active_conversation(conv); 5071 pidgin_conv_switch_active_conversation(conv);
5150 5161
5151 g_signal_connect_swapped(G_OBJECT(pane), "focus", 5162 g_signal_connect_swapped(G_OBJECT(pane), "focus",
5152 G_CALLBACK(gtk_widget_grab_focus), 5163 G_CALLBACK(gtk_widget_grab_focus),
5153 gtkconv->entry); 5164 gtkconv->entry);
5154 5165
5155 pidgin_conv_placement_place(gtkconv); 5166 if (hidden)
5167 pidgin_conv_window_add_gtkconv(hidden_convwin, gtkconv);
5168 else
5169 pidgin_conv_placement_place(gtkconv);
5156 5170
5157 if (nick_colors == NULL) { 5171 if (nick_colors == NULL) {
5158 nbr_nick_colors = NUM_NICK_COLORS; 5172 nbr_nick_colors = NUM_NICK_COLORS;
5159 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); 5173 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]);
5160 } 5174 }
5161 } 5175 }
5162 5176
5163 #if 0
5164 static void 5177 static void
5165 pidgin_conv_new_hidden(PurpleConversation *conv) 5178 pidgin_conv_new_hidden(PurpleConversation *conv)
5166 { 5179 {
5167 private_gtkconv_new(conv, TRUE); 5180 private_gtkconv_new(conv, TRUE);
5168 } 5181 }
5169 #endif
5170 5182
5171 void 5183 void
5172 pidgin_conv_new(PurpleConversation *conv) 5184 pidgin_conv_new(PurpleConversation *conv)
5173 { 5185 {
5174 private_gtkconv_new(conv, FALSE); 5186 private_gtkconv_new(conv, FALSE);
5180 static void 5192 static void
5181 received_im_msg_cb(PurpleAccount *account, char *sender, char *message, 5193 received_im_msg_cb(PurpleAccount *account, char *sender, char *message,
5182 PurpleConversation *conv, PurpleMessageFlags flags) 5194 PurpleConversation *conv, PurpleMessageFlags flags)
5183 { 5195 {
5184 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops(); 5196 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops();
5197 gboolean hide = FALSE;
5185 5198
5186 /* create hidden conv if hide_new pref is always */ 5199 /* create hidden conv if hide_new pref is always */
5187 /* or if hide_new pref is away and account is away */ 5200 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0)
5188 if ((strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0) || 5201 hide = TRUE;
5189 (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 && 5202
5190 !purple_status_is_available(purple_account_get_active_status(account)))) { 5203 /* create hidden conv if hide_new pref is away and account is away */
5191 if (!conv) { 5204 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 &&
5192 ui_ops->create_conversation = NULL; 5205 !purple_status_is_available(purple_account_get_active_status(account)))
5193 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); 5206 hide = TRUE;
5194 purple_conversation_set_ui_ops(conv, NULL); 5207
5195 ui_ops->create_conversation = pidgin_conv_new; 5208 if (conv && PIDGIN_IS_PIDGIN_CONVERSATION(conv) && !hide) {
5196 } else { 5209 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
5197 /* TODO: update the unseen_state data on the conv here */ 5210 if (gtkconv->win == hidden_convwin) {
5198 } 5211 pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
5199 } else { 5212 pidgin_conv_placement_place(gtkconv);
5200 /* new message for an IM */ 5213 }
5201 if (conv && conv->type == PURPLE_CONV_TYPE_IM) 5214 return;
5202 pidgin_conv_attach_to_conversation(conv); 5215 }
5216
5217 if (hide) {
5218 ui_ops->create_conversation = pidgin_conv_new_hidden;
5219 purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
5220 ui_ops->create_conversation = pidgin_conv_new;
5203 } 5221 }
5204 } 5222 }
5205 5223
5206 static void 5224 static void
5207 pidgin_conv_destroy(PurpleConversation *conv) 5225 pidgin_conv_destroy(PurpleConversation *conv)
5208 { 5226 {
5209 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 5227 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
5210
5211 if (!gtkconv)
5212 return;
5213 5228
5214 gtkconv->convs = g_list_remove(gtkconv->convs, conv); 5229 gtkconv->convs = g_list_remove(gtkconv->convs, conv);
5215 /* Don't destroy ourselves until all our convos are gone */ 5230 /* Don't destroy ourselves until all our convos are gone */
5216 if (gtkconv->convs) { 5231 if (gtkconv->convs) {
5217 /* Make sure the destroyed conversation is not the active one */ 5232 /* Make sure the destroyed conversation is not the active one */
6551 char *markup = NULL; 6566 char *markup = NULL;
6552 AtkObject *accessibility_obj; 6567 AtkObject *accessibility_obj;
6553 gboolean ellipsis = FALSE; 6568 gboolean ellipsis = FALSE;
6554 /* I think this is a little longer than it needs to be but I'm lazy. */ 6569 /* I think this is a little longer than it needs to be but I'm lazy. */
6555 char *style; 6570 char *style;
6556 gboolean bold = FALSE;
6557 6571
6558 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 6572 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
6559 im = PURPLE_CONV_IM(conv); 6573 im = PURPLE_CONV_IM(conv);
6560 6574
6561 if ((account == NULL) || 6575 if ((account == NULL) ||
6573 markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE); 6587 markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE);
6574 } else { 6588 } else {
6575 markup = title; 6589 markup = title;
6576 } 6590 }
6577 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 6591 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
6578 const char *topic = gtk_entry_get_text(GTK_ENTRY(gtkconv->u.chat->topic_text)); 6592 const char *topic = gtkconv->u.chat->topic_text ? gtk_entry_get_text(GTK_ENTRY(gtkconv->u.chat->topic_text)) : NULL;
6579 char *esc = topic ? g_markup_escape_text(topic, -1) : NULL; 6593 char *esc = NULL;
6594 #if GTK_CHECK_VERSION(2,6,0)
6595 esc = topic ? g_markup_escape_text(topic, -1) : NULL;
6596 #else
6597 /* GTK < 2.6 doesn't have auto ellipsization, so we do a crude
6598 * trucation to prevent forcing the window to be as wide as the topic */
6599 int len = 0;
6600 char *c, *tmp = g_strdup(topic);
6601 c = tmp;
6602 while(*c && len < 72) {
6603 c = g_utf8_next_char(c);
6604 len++;
6605 }
6606 if (len == 72) {
6607 *c = '\0';
6608 c = g_strdup_printf("%s...", tmp);
6609 g_free(tmp);
6610 tmp = c;
6611 }
6612 esc = tmp ? g_markup_escape_text(tmp, -1) : NULL;
6613 g_free(tmp);
6614 #endif
6580 markup = g_strdup_printf("%s%s<span color='%s' size='smaller'>%s</span>", 6615 markup = g_strdup_printf("%s%s<span color='%s' size='smaller'>%s</span>",
6581 purple_conversation_get_title(conv), 6616 purple_conversation_get_title(conv),
6582 esc && *esc ? "\n" : "", 6617 esc && *esc ? "\n" : "",
6583 pidgin_get_dim_grey_string(gtkconv->infopane), 6618 pidgin_get_dim_grey_string(gtkconv->infopane),
6584 esc ? esc : ""); 6619 esc ? esc : "");
6586 } 6621 }
6587 gtk_list_store_set(gtkconv->infopane_model, &(gtkconv->infopane_iter), 6622 gtk_list_store_set(gtkconv->infopane_model, &(gtkconv->infopane_iter),
6588 CONV_TEXT_COLUMN, markup, -1); 6623 CONV_TEXT_COLUMN, markup, -1);
6589 /* XXX seanegan Why do I have to do this? */ 6624 /* XXX seanegan Why do I have to do this? */
6590 gtk_widget_queue_draw(gtkconv->infopane); 6625 gtk_widget_queue_draw(gtkconv->infopane);
6591 6626
6592 if (title != markup) 6627 if (title != markup)
6593 g_free(markup); 6628 g_free(markup);
6594 6629
6595 if (!GTK_WIDGET_REALIZED(gtkconv->tab_label)) 6630 if (!GTK_WIDGET_REALIZED(gtkconv->tab_label))
6596 gtk_widget_realize(gtkconv->tab_label); 6631 gtk_widget_realize(gtkconv->tab_label);
6597 6632
6598 accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont); 6633 accessibility_obj = gtk_widget_get_accessible(gtkconv->tab_cont);
6599 if (im != NULL && 6634 if (im != NULL &&
6600 purple_conv_im_get_typing_state(im) == PURPLE_TYPING) { 6635 purple_conv_im_get_typing_state(im) == PURPLE_TYPING) {
6601 atk_object_set_description(accessibility_obj, _("Typing")); 6636 atk_object_set_description(accessibility_obj, _("Typing"));
6602 style = "color=\"#4e9a06\""; 6637 style = "tab-label-typing";
6603 } else if (im != NULL && 6638 } else if (im != NULL &&
6604 purple_conv_im_get_typing_state(im) == PURPLE_TYPED) { 6639 purple_conv_im_get_typing_state(im) == PURPLE_TYPED) {
6605 atk_object_set_description(accessibility_obj, _("Stopped Typing")); 6640 atk_object_set_description(accessibility_obj, _("Stopped Typing"));
6606 style = "color=\"#c4a000\""; 6641 style = "tab-label-typed";
6607 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) { 6642 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) {
6608 atk_object_set_description(accessibility_obj, _("Nick Said")); 6643 atk_object_set_description(accessibility_obj, _("Nick Said"));
6609 style = "color=\"#204a87\""; 6644 style = "tab-label-attention";
6610 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) { 6645 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) {
6611 atk_object_set_description(accessibility_obj, _("Unread Messages")); 6646 atk_object_set_description(accessibility_obj, _("Unread Messages"));
6612 if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_CHAT) 6647 if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_CHAT)
6613 style = "color=\"#cc0000\""; 6648 style = "tab-label-unreadchat";
6614 else 6649 else
6615 style = "color=\"#204a87\""; 6650 style = "tab-label-attention";
6616 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) { 6651 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) {
6617 atk_object_set_description(accessibility_obj, _("New Event")); 6652 atk_object_set_description(accessibility_obj, _("New Event"));
6618 style = "color=\"#888a85\""; 6653 style = "tab-label-event";
6619 } else { 6654 } else {
6620 style = NULL; 6655 style = NULL;
6621 } 6656 }
6622 6657
6658 gtk_widget_set_name(gtkconv->tab_label, style);
6659 gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title);
6660 gtk_widget_set_state(gtkconv->tab_label, GTK_STATE_ACTIVE);
6661
6623 if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT || 6662 if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT ||
6624 gtkconv->unseen_state == PIDGIN_UNSEEN_NICK || 6663 gtkconv->unseen_state == PIDGIN_UNSEEN_NICK ||
6625 gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) 6664 gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) {
6626 bold = TRUE; 6665 PangoAttrList *list = pango_attr_list_new();
6627 6666 PangoAttribute *attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
6628 if (style || bold) 6667 attr->start_index = 0;
6629 { 6668 attr->end_index = -1;
6630 char *html_title,*label; 6669 pango_attr_list_insert(list, attr);
6631 6670 gtk_label_set_attributes(GTK_LABEL(gtkconv->tab_label), list);
6632 html_title = g_markup_escape_text(title_tmp, -1); 6671 pango_attr_list_unref(list);
6633 label = g_strdup_printf("<span %s %s>%s</span>", 6672 } else
6634 style ? style : "", 6673 gtk_label_set_attributes(GTK_LABEL(gtkconv->tab_label), NULL);
6635 bold ? "weight=\"bold\"" : "",
6636 html_title);
6637 g_free(html_title);
6638 gtk_label_set_markup(GTK_LABEL(gtkconv->tab_label), label);
6639 g_free(label);
6640 }
6641 else
6642 gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title_tmp);
6643 6674
6644 if (pidgin_conv_window_is_active_conversation(conv)) 6675 if (pidgin_conv_window_is_active_conversation(conv))
6645 update_typing_icon(gtkconv); 6676 update_typing_icon(gtkconv);
6646 6677
6647 gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title); 6678 gtk_label_set_text(GTK_LABEL(gtkconv->menu_label), title);
6718 unseen = PIDGIN_UNSEEN_NO_LOG; 6749 unseen = PIDGIN_UNSEEN_NO_LOG;
6719 else 6750 else
6720 unseen = PIDGIN_UNSEEN_TEXT; 6751 unseen = PIDGIN_UNSEEN_TEXT;
6721 6752
6722 conv_set_unseen(conv, unseen); 6753 conv_set_unseen(conv, unseen);
6723 purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
6724 } 6754 }
6725 } 6755 }
6726 6756
6727 static PurpleConversationUiOps conversation_ui_ops = 6757 static PurpleConversationUiOps conversation_ui_ops =
6728 { 6758 {
7242 7272
7243 static void 7273 static void
7244 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus, 7274 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus,
7245 PurpleStatus *newstatus) 7275 PurpleStatus *newstatus)
7246 { 7276 {
7247 #if 0
7248 GList *l; 7277 GList *l;
7249 PurpleConversation *conv = NULL; 7278 PurpleConversation *conv = NULL;
7250 PidginConversation *gtkconv; 7279 PidginConversation *gtkconv;
7251 7280
7252 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0) 7281 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0)
7253 return; 7282 return;
7254 7283
7255 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus)) 7284 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus))
7256 return; 7285 return;
7257 #endif 7286
7287 while ((l = hidden_convwin->gtkconvs) != NULL)
7288 {
7289 gtkconv = l->data;
7290
7291 conv = gtkconv->active_conv;
7292
7293 while(l && !purple_status_is_available(
7294 purple_account_get_active_status(
7295 purple_conversation_get_account(conv))))
7296 l = l->next;
7297 if (!l)
7298 break;
7299
7300 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
7301 pidgin_conv_placement_place(gtkconv);
7302
7303 /* TODO: do we need to do anything for any other conversations that are in the same gtkconv here?
7304 * I'm a little concerned that not doing so will cause the "pending" indicator in the gtkblist not to be cleared. -DAA*/
7305 purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
7306 }
7258 } 7307 }
7259 7308
7260 static void 7309 static void
7261 hide_new_pref_cb(const char *name, PurplePrefType type, 7310 hide_new_pref_cb(const char *name, PurplePrefType type,
7262 gconstpointer value, gpointer data) 7311 gconstpointer value, gpointer data)
7263 { 7312 {
7264 GList *l; 7313 GList *l;
7314 PurpleConversation *conv = NULL;
7315 PidginConversation *gtkconv;
7265 gboolean when_away = FALSE; 7316 gboolean when_away = FALSE;
7317
7318 if(!hidden_convwin)
7319 return;
7266 7320
7267 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0) 7321 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0)
7268 return; 7322 return;
7269 7323
7270 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0) 7324 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0)
7271 when_away = TRUE; 7325 when_away = TRUE;
7272 7326
7273 for (l = purple_get_conversations(); l; l = l->next) 7327 for (l = hidden_convwin->gtkconvs; l; )
7274 { 7328 {
7275 PurpleConversation *conv = l->data; 7329 gtkconv = l->data;
7276 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 7330 l = l->next;
7277 if (gtkconv) 7331
7332 conv = gtkconv->active_conv;
7333
7334 if (conv->type == PURPLE_CONV_TYPE_CHAT ||
7335 gtkconv->unseen_count == 0 ||
7336 (when_away && !purple_status_is_available(
7337 purple_account_get_active_status(
7338 purple_conversation_get_account(conv)))))
7278 continue; 7339 continue;
7279 if(when_away && !purple_status_is_available( 7340
7280 purple_account_get_active_status( 7341 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
7281 purple_conversation_get_account(conv)))) 7342 pidgin_conv_placement_place(gtkconv);
7282 continue;
7283 pidgin_conv_attach_to_conversation(conv);
7284 } 7343 }
7285 } 7344 }
7286 7345
7287 7346
7288 static void 7347 static void
7548 { 7607 {
7549 int timer; 7608 int timer;
7550 purple_conversation_set_data(conv, "unseen-count", NULL); 7609 purple_conversation_set_data(conv, "unseen-count", NULL);
7551 purple_conversation_set_data(conv, "unseen-state", NULL); 7610 purple_conversation_set_data(conv, "unseen-state", NULL);
7552 purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops()); 7611 purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops());
7553 private_gtkconv_new(conv, FALSE); 7612 if (!PIDGIN_CONVERSATION(conv))
7613 private_gtkconv_new(conv, FALSE);
7554 timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer")); 7614 timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer"));
7555 if (timer) 7615 if (timer) {
7556 purple_timeout_remove(timer); 7616 purple_timeout_remove(timer);
7617 purple_conversation_set_data(conv, "close-timer", NULL);
7618 }
7557 } 7619 }
7558 7620
7559 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv) 7621 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv)
7560 { 7622 {
7561 GList *list; 7623 GList *list;
7562 PidginConversation *gtkconv; 7624 PidginConversation *gtkconv;
7563 7625
7564 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) 7626 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) {
7565 return FALSE; 7627 /* This is pretty much always the case now. */
7628 gtkconv = PIDGIN_CONVERSATION(conv);
7629 if (gtkconv->win != hidden_convwin)
7630 return FALSE;
7631 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
7632 pidgin_conv_placement_place(gtkconv);
7633 purple_signal_emit(pidgin_conversations_get_handle(),
7634 "conversation-displayed", gtkconv);
7635 list = gtkconv->convs;
7636 while (list) {
7637 pidgin_conv_attach(list->data);
7638 list = list->next;
7639 }
7640 return TRUE;
7641 }
7566 7642
7567 pidgin_conv_attach(conv); 7643 pidgin_conv_attach(conv);
7568 gtkconv = PIDGIN_CONVERSATION(conv); 7644 gtkconv = PIDGIN_CONVERSATION(conv);
7569 7645
7570 list = purple_conversation_get_message_history(conv); 7646 list = purple_conversation_get_message_history(conv);
7781 purple_value_new(PURPLE_TYPE_SUBTYPE, 7857 purple_value_new(PURPLE_TYPE_SUBTYPE,
7782 PURPLE_SUBTYPE_CONVERSATION), 7858 PURPLE_SUBTYPE_CONVERSATION),
7783 purple_value_new(PURPLE_TYPE_INT)); 7859 purple_value_new(PURPLE_TYPE_INT));
7784 7860
7785 purple_signal_register(handle, "conversation-switched", 7861 purple_signal_register(handle, "conversation-switched",
7786 purple_marshal_VOID__POINTER_POINTER, NULL, 1, 7862 purple_marshal_VOID__POINTER, NULL, 1,
7787 purple_value_new(PURPLE_TYPE_SUBTYPE, 7863 purple_value_new(PURPLE_TYPE_SUBTYPE,
7788 PURPLE_SUBTYPE_CONVERSATION)); 7864 PURPLE_SUBTYPE_CONVERSATION));
7789 7865
7790 purple_signal_register(handle, "conversation-hiding", 7866 purple_signal_register(handle, "conversation-hiding",
7791 purple_marshal_VOID__POINTER_POINTER, NULL, 1, 7867 purple_marshal_VOID__POINTER, NULL, 1,
7792 purple_value_new(PURPLE_TYPE_BOXED, 7868 purple_value_new(PURPLE_TYPE_BOXED,
7793 "PidginConversation *")); 7869 "PidginConversation *"));
7794 7870
7795 purple_signal_register(handle, "conversation-displayed", 7871 purple_signal_register(handle, "conversation-displayed",
7796 purple_marshal_VOID__POINTER_POINTER, NULL, 1, 7872 purple_marshal_VOID__POINTER, NULL, 1,
7797 purple_value_new(PURPLE_TYPE_BOXED, 7873 purple_value_new(PURPLE_TYPE_BOXED,
7798 "PidginConversation *")); 7874 "PidginConversation *"));
7799 7875
7800 /********************************************************************** 7876 /**********************************************************************
7801 * Register commands 7877 * Register commands
7832 7908
7833 purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", 7909 purple_signal_connect(purple_conversations_get_handle(), "received-im-msg",
7834 handle, G_CALLBACK(received_im_msg_cb), NULL); 7910 handle, G_CALLBACK(received_im_msg_cb), NULL);
7835 7911
7836 purple_conversations_set_ui_ops(&conversation_ui_ops); 7912 purple_conversations_set_ui_ops(&conversation_ui_ops);
7913
7914 hidden_convwin = pidgin_conv_window_new();
7915 window_list = g_list_remove(window_list, hidden_convwin);
7837 7916
7838 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", 7917 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed",
7839 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); 7918 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
7840 7919
7841 /* Callbacks to update a conversation */ 7920 /* Callbacks to update a conversation */
7872 PURPLE_SIGNAL_PRIORITY_LOWEST); 7951 PURPLE_SIGNAL_PRIORITY_LOWEST);
7873 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle, 7952 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle,
7874 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); 7953 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL);
7875 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, 7954 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle,
7876 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); 7955 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL);
7956
7957 {
7958 /* Set default tab colors */
7959 GString *str = g_string_new(NULL);
7960 GtkSettings *settings = gtk_settings_get_default();
7961 struct {
7962 const char *stylename;
7963 const char *labelname;
7964 const char *color;
7965 } styles[] = {
7966 {"pidgin_tab_label_typing_default", "tab-label-typing", "#4e9a06"},
7967 {"pidgin_tab_label_typed_default", "tab-label-typed", "#c4a000"},
7968 {"pidgin_tab_label_attention_default", "tab-label-attention", "#006aff"},
7969 {"pidgin_tab_label_unreadchat_default", "tab-label-unreadchat", "#cc0000"},
7970 {"pidgin_tab_label_event_default", "tab-label-event", "#888a85"},
7971 {NULL, NULL, NULL}
7972 };
7973 int iter;
7974 for (iter = 0; styles[iter].stylename; iter++) {
7975 if (!gtk_rc_get_style_by_paths(settings, styles[iter].labelname, NULL, G_TYPE_NONE))
7976 /* Apparently both ACTIVE and NORMAL are required */
7977 g_string_append_printf(str, "style \"%s\" {\n"
7978 "fg[ACTIVE] = \"%s\"\n"
7979 "}\n"
7980 "widget \"*%s\" style \"%s\"\n",
7981 styles[iter].stylename,
7982 styles[iter].color,
7983 styles[iter].labelname, styles[iter].stylename);
7984 }
7985 gtk_rc_parse_string(str->str);
7986 g_string_free(str, TRUE);
7987 #if GTK_CHECK_VERSION(2,4,0)
7988 gtk_rc_reset_styles(settings);
7989 #endif
7990 }
7877 } 7991 }
7878 7992
7879 void 7993 void
7880 pidgin_conversations_uninit(void) 7994 pidgin_conversations_uninit(void)
7881 { 7995 {
8706 if (buddy != NULL) { 8820 if (buddy != NULL) {
8707 purple_blist_alias_buddy(buddy, 8821 purple_blist_alias_buddy(buddy,
8708 gtk_entry_get_text(entry)); 8822 gtk_entry_get_text(entry));
8709 } 8823 }
8710 serv_alias_buddy(buddy); 8824 serv_alias_buddy(buddy);
8711 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 8825 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
8712 gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry)); 8826 gtk_entry_set_text(GTK_ENTRY(gtkconv->u.chat->topic_text), gtk_entry_get_text(entry));
8713 topic_callback(NULL, gtkconv); 8827 topic_callback(NULL, gtkconv);
8714 } 8828 }
8715 remove_edit_entry(user_data, GTK_WIDGET(entry)); 8829 remove_edit_entry(user_data, GTK_WIDGET(entry));
8716 } 8830 }
8717 8831
8718 static gboolean 8832 static gboolean
8719 infopane_entry_activate(PidginConversation *gtkconv) 8833 infopane_entry_activate(PidginConversation *gtkconv)
8720 { 8834 {
8721 GtkWidget *entry = NULL; 8835 GtkWidget *entry = NULL;
8722 PurpleConversation *conv = gtkconv->active_conv; 8836 PurpleConversation *conv = gtkconv->active_conv;
8723 const char *text = NULL; 8837 const char *text = NULL;
8724 8838
8725 if (!GTK_WIDGET_VISIBLE(gtkconv->tab_label)) { 8839 if (!GTK_WIDGET_VISIBLE(gtkconv->tab_label)) {
8726 /* There's already an entry for alias. Let's not create another one. */ 8840 /* There's already an entry for alias. Let's not create another one. */
8727 return FALSE; 8841 return FALSE;
8733 } 8847 }
8734 8848
8735 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { 8849 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
8736 PurpleBuddy *buddy = purple_find_buddy(gtkconv->active_conv->account, gtkconv->active_conv->name); 8850 PurpleBuddy *buddy = purple_find_buddy(gtkconv->active_conv->account, gtkconv->active_conv->name);
8737 if (!buddy) 8851 if (!buddy)
8852 /* This buddy isn't in your buddy list, so we can't alias him */
8738 return FALSE; 8853 return FALSE;
8854
8739 text = purple_buddy_get_contact_alias(buddy); 8855 text = purple_buddy_get_contact_alias(buddy);
8740 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 8856 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
8857 PurpleConnection *gc;
8858 PurplePluginProtocolInfo *prpl_info = NULL;
8859
8860 gc = purple_conversation_get_gc(conv);
8861 if (gc != NULL)
8862 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl);
8863 if (prpl_info && prpl_info->set_chat_topic == NULL)
8864 /* This protocol doesn't support setting the chat room topic */
8865 return FALSE;
8866
8741 text = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv)); 8867 text = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(conv));
8742 } 8868 }
8743 8869
8744 /* alias label */ 8870 /* alias label */
8745 entry = gtk_entry_new(); 8871 entry = gtk_entry_new();
8754 gtk_box_reorder_child(GTK_BOX(gtkconv->infopane_hbox), entry, 0); 8880 gtk_box_reorder_child(GTK_BOX(gtkconv->infopane_hbox), entry, 0);
8755 8881
8756 g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(alias_cb), gtkconv); 8882 g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(alias_cb), gtkconv);
8757 g_signal_connect(G_OBJECT(entry), "focus-out-event", G_CALLBACK(alias_focus_cb), gtkconv); 8883 g_signal_connect(G_OBJECT(entry), "focus-out-event", G_CALLBACK(alias_focus_cb), gtkconv);
8758 g_signal_connect(G_OBJECT(entry), "key-press-event", G_CALLBACK(alias_key_press_cb), gtkconv); 8884 g_signal_connect(G_OBJECT(entry), "key-press-event", G_CALLBACK(alias_key_press_cb), gtkconv);
8759 8885
8760 8886 if (text != NULL)
8761 8887 gtk_entry_set_text(GTK_ENTRY(entry), text);
8762 gtk_entry_set_text(GTK_ENTRY(entry), text);
8763 gtk_widget_show(entry); 8888 gtk_widget_show(entry);
8764 gtk_widget_hide(gtkconv->infopane); 8889 gtk_widget_hide(gtkconv->infopane);
8765 gtk_widget_grab_focus(entry); 8890 gtk_widget_grab_focus(entry);
8766 8891
8767 return TRUE; 8892 return TRUE;
9047 9172
9048 /* Close the "Find" dialog if it's open */ 9173 /* Close the "Find" dialog if it's open */
9049 if (win->dialogs.search) 9174 if (win->dialogs.search)
9050 gtk_widget_destroy(win->dialogs.search); 9175 gtk_widget_destroy(win->dialogs.search);
9051 9176
9052 gtk_widget_hide_all(win->window);
9053
9054 if (win->gtkconvs) { 9177 if (win->gtkconvs) {
9055 while (win->gtkconvs) { 9178 while (win->gtkconvs) {
9056 gboolean last = (win->gtkconvs->next == NULL); 9179 gboolean last = (win->gtkconvs->next == NULL);
9057 close_conv_cb(NULL, NULL, win->gtkconvs->data); 9180 close_conv_cb(NULL, NULL, win->gtkconvs->data);
9058 if (last) 9181 if (last)
9102 static GdkCursor *ptr = NULL; 9225 static GdkCursor *ptr = NULL;
9103 if (ptr == NULL) { 9226 if (ptr == NULL) {
9104 ptr = gdk_cursor_new(GDK_LEFT_PTR); 9227 ptr = gdk_cursor_new(GDK_LEFT_PTR);
9105 } 9228 }
9106 9229
9107 gtk_label_set_markup(label, "×"); 9230 gtk_label_set_markup(label, "×");
9108 gdk_window_set_cursor(event->window, ptr); 9231 gdk_window_set_cursor(event->window, ptr);
9109 return FALSE; 9232 return FALSE;
9110 } 9233 }
9111 9234
9112 static gboolean 9235 static gboolean
9115 static GdkCursor *hand = NULL; 9238 static GdkCursor *hand = NULL;
9116 if (hand == NULL) { 9239 if (hand == NULL) {
9117 hand = gdk_cursor_new(GDK_HAND2); 9240 hand = gdk_cursor_new(GDK_HAND2);
9118 } 9241 }
9119 9242
9120 gtk_label_set_markup(label, "<u>×</u>"); 9243 gtk_label_set_markup(label, "<u>×</u>");
9121 gdk_window_set_cursor(event->window, hand); 9244 gdk_window_set_cursor(event->window, hand);
9122 return FALSE; 9245 return FALSE;
9123 } 9246 }
9124 9247
9125 void 9248 void
9145 gtkconv->close = gtk_event_box_new(); 9268 gtkconv->close = gtk_event_box_new();
9146 #if GTK_CHECK_VERSION(2,4,0) 9269 #if GTK_CHECK_VERSION(2,4,0)
9147 gtk_event_box_set_visible_window(GTK_EVENT_BOX(gtkconv->close), FALSE); 9270 gtk_event_box_set_visible_window(GTK_EVENT_BOX(gtkconv->close), FALSE);
9148 #endif 9271 #endif
9149 gtk_widget_set_events(gtkconv->close, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); 9272 gtk_widget_set_events(gtkconv->close, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
9150 close_image = gtk_label_new("×"); 9273 close_image = gtk_label_new("×");
9151 g_signal_connect(G_OBJECT(gtkconv->close), "enter-notify-event", G_CALLBACK(close_button_entered_cb), close_image); 9274 g_signal_connect(G_OBJECT(gtkconv->close), "enter-notify-event", G_CALLBACK(close_button_entered_cb), close_image);
9152 g_signal_connect(G_OBJECT(gtkconv->close), "leave-notify-event", G_CALLBACK(close_button_left_cb), close_image); 9275 g_signal_connect(G_OBJECT(gtkconv->close), "leave-notify-event", G_CALLBACK(close_button_left_cb), close_image);
9153 gtk_widget_show(close_image); 9276 gtk_widget_show(close_image);
9154 gtk_container_add(GTK_CONTAINER(gtkconv->close), close_image); 9277 gtk_container_add(GTK_CONTAINER(gtkconv->close), close_image);
9155 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close, 9278 gtk_tooltips_set_tip(gtkconv->tooltips, gtkconv->close,
9174 gtk_widget_show(gtkconv->icon); 9297 gtk_widget_show(gtkconv->icon);
9175 update_tab_icon(conv); 9298 update_tab_icon(conv);
9176 9299
9177 /* Tab label. */ 9300 /* Tab label. */
9178 gtkconv->tab_label = gtk_label_new(tmp_lab = purple_conversation_get_title(conv)); 9301 gtkconv->tab_label = gtk_label_new(tmp_lab = purple_conversation_get_title(conv));
9302 gtk_widget_set_name(gtkconv->tab_label, "tab-label");
9179 9303
9180 gtkconv->menu_tabby = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); 9304 gtkconv->menu_tabby = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
9181 gtkconv->menu_label = gtk_label_new(tmp_lab); 9305 gtkconv->menu_label = gtk_label_new(tmp_lab);
9182 gtk_box_pack_start(GTK_BOX(gtkconv->menu_tabby), gtkconv->menu_icon, FALSE, FALSE, 0); 9306 gtk_box_pack_start(GTK_BOX(gtkconv->menu_tabby), gtkconv->menu_icon, FALSE, FALSE, 0);
9183 9307
9333 0, 0, NULL, NULL, gtkconv); 9457 0, 0, NULL, NULL, gtkconv);
9334 9458
9335 if (win->gtkconvs && win->gtkconvs->next == NULL) 9459 if (win->gtkconvs && win->gtkconvs->next == NULL)
9336 pidgin_conv_tab_pack(win, win->gtkconvs->data); 9460 pidgin_conv_tab_pack(win, win->gtkconvs->data);
9337 9461
9338 if (!win->gtkconvs) 9462 if (!win->gtkconvs && win != hidden_convwin)
9339 pidgin_conv_window_destroy(win); 9463 pidgin_conv_window_destroy(win);
9340 } 9464 }
9341 9465
9342 PidginConversation * 9466 PidginConversation *
9343 pidgin_conv_window_get_gtkconv_at_index(const PidginWindow *win, int index) 9467 pidgin_conv_window_get_gtkconv_at_index(const PidginWindow *win, int index)
9872 } 9996 }
9873 9997
9874 gboolean 9998 gboolean
9875 pidgin_conv_is_hidden(PidginConversation *gtkconv) 9999 pidgin_conv_is_hidden(PidginConversation *gtkconv)
9876 { 10000 {
9877 return (gtkconv == NULL); 10001 g_return_val_if_fail(gtkconv != NULL, FALSE);
10002
10003 return (gtkconv->win == hidden_convwin);
9878 } 10004 }
9879 10005
9880 10006
9881 /* Algorithm from http://www.w3.org/TR/AERT#color-contrast */ 10007 /* Algorithm from http://www.w3.org/TR/AERT#color-contrast */
9882 static gboolean 10008 static gboolean
9973 *color_count = i; 10099 *color_count = i;
9974 } 10100 }
9975 10101
9976 return colors; 10102 return colors;
9977 } 10103 }
9978
9979