pidgin/gtkconv.c

changeset 21815
cd9bd951717d
parent 21814
51ea68d3a41a
parent 19809
4f204af3ce9a
child 21816
4d163cc646bc
equal deleted inserted replaced
21814:51ea68d3a41a 21815:cd9bd951717d
123 } InviteBuddyInfo; 123 } InviteBuddyInfo;
124 124
125 static GtkWidget *invite_dialog = NULL; 125 static GtkWidget *invite_dialog = NULL;
126 static GtkWidget *warn_close_dialog = NULL; 126 static GtkWidget *warn_close_dialog = NULL;
127 127
128 static PidginWindow *hidden_convwin = NULL;
128 static GList *window_list = NULL; 129 static GList *window_list = NULL;
129 130
130 /* Lists of status icons at all available sizes for use as window icons */ 131 /* Lists of status icons at all available sizes for use as window icons */
131 static GList *available_list = NULL; 132 static GList *available_list = NULL;
132 static GList *away_list = NULL; 133 static GList *away_list = NULL;
2763 GdkModifierType state; 2764 GdkModifierType state;
2764 2765
2765 if (gtkconv == NULL) { 2766 if (gtkconv == NULL) {
2766 pidgin_conv_attach_to_conversation(conv); 2767 pidgin_conv_attach_to_conversation(conv);
2767 gtkconv = PIDGIN_CONVERSATION(conv); 2768 gtkconv = PIDGIN_CONVERSATION(conv);
2769 } else if (gtkconv->win == hidden_convwin) {
2770 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
2771 pidgin_conv_placement_place(gtkconv);
2768 } 2772 }
2769 2773
2770 pidgin_conv_switch_active_conversation(conv); 2774 pidgin_conv_switch_active_conversation(conv);
2771 /* Switch the tab only if the user initiated the event by pressing 2775 /* Switch the tab only if the user initiated the event by pressing
2772 * a button or hitting a key. */ 2776 * a button or hitting a key. */
2795 2799
2796 for (; l != NULL && (max_count == 0 || c < max_count); l = l->next) { 2800 for (; l != NULL && (max_count == 0 || c < max_count); l = l->next) {
2797 PurpleConversation *conv = (PurpleConversation*)l->data; 2801 PurpleConversation *conv = (PurpleConversation*)l->data;
2798 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 2802 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
2799 2803
2800 if (gtkconv != NULL && gtkconv->active_conv != conv) 2804 if(gtkconv == NULL || gtkconv->active_conv != conv)
2801 continue; 2805 continue;
2802 if (gtkconv == NULL) { 2806
2803 if (!purple_conversation_get_data(conv, "unseen-count") || 2807 if (gtkconv->unseen_state >= min_state
2804 !purple_conversation_get_data(conv, "unseen-state") || 2808 && (!hidden_only ||
2805 GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state"))<min_state) 2809 (hidden_only && gtkconv->win == hidden_convwin))) {
2806 continue; 2810
2807 r = g_list_prepend(r, conv); 2811 r = g_list_prepend(r, conv);
2808 c++; 2812 c++;
2809 } else {
2810 if (gtkconv->unseen_state >= min_state && !hidden_only) {
2811 r = g_list_prepend(r, conv);
2812 c++;
2813 }
2814 } 2813 }
2815 } 2814 }
2816 2815
2817 return r; 2816 return r;
2818 } 2817 }
2851 2850
2852 GtkWidget *icon = gtk_image_new(); 2851 GtkWidget *icon = gtk_image_new();
2853 GdkPixbuf *pbuf = pidgin_conv_get_icon(conv, icon, PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC); 2852 GdkPixbuf *pbuf = pidgin_conv_get_icon(conv, icon, PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC);
2854 GtkWidget *item; 2853 GtkWidget *item;
2855 gchar *text = g_strdup_printf("%s (%d)", 2854 gchar *text = g_strdup_printf("%s (%d)",
2856 gtkconv ? gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)) : purple_conversation_get_name(conv), 2855 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)),
2857 gtkconv ? gtkconv->unseen_count : GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))); 2856 gtkconv->unseen_count);
2858 2857
2859 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf); 2858 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf);
2860 g_object_unref(pbuf); 2859 g_object_unref(pbuf);
2861 2860
2862 item = gtk_image_menu_item_new_with_label(text); 2861 item = gtk_image_menu_item_new_with_label(text);
3113 GList *list; 3112 GList *list;
3114 PidginConversation *gtkconv; 3113 PidginConversation *gtkconv;
3115 PurpleConversation *conv; 3114 PurpleConversation *conv;
3116 GtkWidget *item; 3115 GtkWidget *item;
3117 3116
3118 if (win->window == NULL) 3117 if (win->window == NULL || win->window == hidden_convwin)
3119 return; 3118 return;
3120 3119
3121 gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3120 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3122 if (gtkconv == NULL) 3121 if (gtkconv == NULL)
3123 return; 3122 return;
4945 PurpleConversationType conv_type = purple_conversation_get_type(conv); 4944 PurpleConversationType conv_type = purple_conversation_get_type(conv);
4946 GtkWidget *pane = NULL; 4945 GtkWidget *pane = NULL;
4947 GtkWidget *tab_cont; 4946 GtkWidget *tab_cont;
4948 PurpleBlistNode *convnode; 4947 PurpleBlistNode *convnode;
4949 4948
4950 if (hidden)
4951 return;
4952
4953 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) { 4949 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
4954 conv->ui_data = gtkconv; 4950 conv->ui_data = gtkconv;
4955 if (!g_list_find(gtkconv->convs, conv)) 4951 if (!g_list_find(gtkconv->convs, conv))
4956 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); 4952 gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
4957 pidgin_conv_switch_active_conversation(conv); 4953 pidgin_conv_switch_active_conversation(conv);
5047 5043
5048 g_signal_connect_swapped(G_OBJECT(pane), "focus", 5044 g_signal_connect_swapped(G_OBJECT(pane), "focus",
5049 G_CALLBACK(gtk_widget_grab_focus), 5045 G_CALLBACK(gtk_widget_grab_focus),
5050 gtkconv->entry); 5046 gtkconv->entry);
5051 5047
5052 pidgin_conv_placement_place(gtkconv); 5048 if (hidden)
5049 pidgin_conv_window_add_gtkconv(hidden_convwin, gtkconv);
5050 else
5051 pidgin_conv_placement_place(gtkconv);
5053 5052
5054 if (nick_colors == NULL) { 5053 if (nick_colors == NULL) {
5055 nbr_nick_colors = NUM_NICK_COLORS; 5054 nbr_nick_colors = NUM_NICK_COLORS;
5056 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); 5055 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]);
5057 } 5056 }
5058 } 5057 }
5059 5058
5060 #if 0
5061 static void 5059 static void
5062 pidgin_conv_new_hidden(PurpleConversation *conv) 5060 pidgin_conv_new_hidden(PurpleConversation *conv)
5063 { 5061 {
5064 private_gtkconv_new(conv, TRUE); 5062 private_gtkconv_new(conv, TRUE);
5065 } 5063 }
5066 #endif
5067 5064
5068 void 5065 void
5069 pidgin_conv_new(PurpleConversation *conv) 5066 pidgin_conv_new(PurpleConversation *conv)
5070 { 5067 {
5071 private_gtkconv_new(conv, FALSE); 5068 private_gtkconv_new(conv, FALSE);
5079 PurpleConversation *conv, PurpleMessageFlags flags) 5076 PurpleConversation *conv, PurpleMessageFlags flags)
5080 { 5077 {
5081 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops(); 5078 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops();
5082 5079
5083 /* create hidden conv if hide_new pref is always */ 5080 /* create hidden conv if hide_new pref is always */
5084 /* or if hide_new pref is away and account is away */ 5081 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0)
5085 if ((strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0) || 5082 {
5086 (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 && 5083 ui_ops->create_conversation = pidgin_conv_new_hidden;
5087 !purple_status_is_available(purple_account_get_active_status(account)))) { 5084 purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
5088 if (!conv) { 5085 ui_ops->create_conversation = pidgin_conv_new;
5089 ui_ops->create_conversation = NULL; 5086 return;
5090 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); 5087 }
5091 purple_conversation_set_ui_ops(conv, NULL); 5088
5092 ui_ops->create_conversation = pidgin_conv_new; 5089 /* create hidden conv if hide_new pref is away and account is away */
5093 } else { 5090 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 &&
5094 /* TODO: update the unseen_state data on the conv here */ 5091 !purple_status_is_available(purple_account_get_active_status(account)))
5095 } 5092 {
5096 } else { 5093 ui_ops->create_conversation = pidgin_conv_new_hidden;
5097 /* new message for an IM */ 5094 purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
5098 if (conv && conv->type == PURPLE_CONV_TYPE_IM) 5095 ui_ops->create_conversation = pidgin_conv_new;
5099 pidgin_conv_attach_to_conversation(conv); 5096 return;
5100 } 5097 }
5101 } 5098 }
5102 5099
5103 static void 5100 static void
5104 pidgin_conv_destroy(PurpleConversation *conv) 5101 pidgin_conv_destroy(PurpleConversation *conv)
5105 { 5102 {
5106 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 5103 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
5107
5108 if (!gtkconv)
5109 return;
5110 5104
5111 gtkconv->convs = g_list_remove(gtkconv->convs, conv); 5105 gtkconv->convs = g_list_remove(gtkconv->convs, conv);
5112 /* Don't destroy ourselves until all our convos are gone */ 5106 /* Don't destroy ourselves until all our convos are gone */
5113 if (gtkconv->convs) { 5107 if (gtkconv->convs) {
5114 /* Make sure the destroyed conversation is not the active one */ 5108 /* Make sure the destroyed conversation is not the active one */
7114 7108
7115 static void 7109 static void
7116 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus, 7110 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus,
7117 PurpleStatus *newstatus) 7111 PurpleStatus *newstatus)
7118 { 7112 {
7119 #if 0
7120 GList *l; 7113 GList *l;
7121 PurpleConversation *conv = NULL; 7114 PurpleConversation *conv = NULL;
7122 PidginConversation *gtkconv; 7115 PidginConversation *gtkconv;
7123 7116
7124 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0) 7117 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0)
7125 return; 7118 return;
7126 7119
7127 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus)) 7120 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus))
7128 return; 7121 return;
7129 #endif 7122
7123 while ((l = hidden_convwin->gtkconvs) != NULL)
7124 {
7125 gtkconv = l->data;
7126
7127 conv = gtkconv->active_conv;
7128
7129 while(l && !purple_status_is_available(
7130 purple_account_get_active_status(
7131 purple_conversation_get_account(conv))))
7132 l = l->next;
7133 if (!l)
7134 break;
7135
7136 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
7137 pidgin_conv_placement_place(gtkconv);
7138
7139 /* TODO: do we need to do anything for any other conversations that are in the same gtkconv here?
7140 * I'm a little concerned that not doing so will cause the "pending" indicator in the gtkblist not to be cleared. -DAA*/
7141 purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
7142 }
7130 } 7143 }
7131 7144
7132 static void 7145 static void
7133 hide_new_pref_cb(const char *name, PurplePrefType type, 7146 hide_new_pref_cb(const char *name, PurplePrefType type,
7134 gconstpointer value, gpointer data) 7147 gconstpointer value, gpointer data)
7135 { 7148 {
7136 GList *l; 7149 GList *l;
7150 PurpleConversation *conv = NULL;
7151 PidginConversation *gtkconv;
7137 gboolean when_away = FALSE; 7152 gboolean when_away = FALSE;
7153
7154 if(!hidden_convwin)
7155 return;
7138 7156
7139 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0) 7157 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0)
7140 return; 7158 return;
7141 7159
7142 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0) 7160 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0)
7143 when_away = TRUE; 7161 when_away = TRUE;
7144 7162
7145 for (l = purple_get_conversations(); l; l = l->next) 7163 while ((l = hidden_convwin->gtkconvs) != NULL)
7146 { 7164 {
7147 PurpleConversation *conv = l->data; 7165 gtkconv = l->data;
7148 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 7166
7149 if (gtkconv) 7167 conv = gtkconv->active_conv;
7150 continue; 7168
7151 if(when_away && !purple_status_is_available( 7169 if(when_away && !purple_status_is_available(
7152 purple_account_get_active_status( 7170 purple_account_get_active_status(
7153 purple_conversation_get_account(conv)))) 7171 purple_conversation_get_account(conv))))
7154 continue; 7172 continue;
7155 pidgin_conv_attach_to_conversation(conv); 7173
7174 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
7175 pidgin_conv_placement_place(gtkconv);
7156 } 7176 }
7157 } 7177 }
7158 7178
7159 7179
7160 static void 7180 static void
7701 7721
7702 purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", 7722 purple_signal_connect(purple_conversations_get_handle(), "received-im-msg",
7703 handle, G_CALLBACK(received_im_msg_cb), NULL); 7723 handle, G_CALLBACK(received_im_msg_cb), NULL);
7704 7724
7705 purple_conversations_set_ui_ops(&conversation_ui_ops); 7725 purple_conversations_set_ui_ops(&conversation_ui_ops);
7726
7727 hidden_convwin = pidgin_conv_window_new();
7728 window_list = g_list_remove(window_list, hidden_convwin);
7706 7729
7707 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", 7730 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed",
7708 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); 7731 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
7709 7732
7710 /* Callbacks to update a conversation */ 7733 /* Callbacks to update a conversation */
9237 0, 0, NULL, NULL, gtkconv); 9260 0, 0, NULL, NULL, gtkconv);
9238 9261
9239 if (win->gtkconvs && win->gtkconvs->next == NULL) 9262 if (win->gtkconvs && win->gtkconvs->next == NULL)
9240 pidgin_conv_tab_pack(win, win->gtkconvs->data); 9263 pidgin_conv_tab_pack(win, win->gtkconvs->data);
9241 9264
9242 if (!win->gtkconvs) 9265 if (!win->gtkconvs && win != hidden_convwin)
9243 pidgin_conv_window_destroy(win); 9266 pidgin_conv_window_destroy(win);
9244 } 9267 }
9245 9268
9246 PidginConversation * 9269 PidginConversation *
9247 pidgin_conv_window_get_gtkconv_at_index(const PidginWindow *win, int index) 9270 pidgin_conv_window_get_gtkconv_at_index(const PidginWindow *win, int index)
9776 } 9799 }
9777 9800
9778 gboolean 9801 gboolean
9779 pidgin_conv_is_hidden(PidginConversation *gtkconv) 9802 pidgin_conv_is_hidden(PidginConversation *gtkconv)
9780 { 9803 {
9781 return (gtkconv == NULL); 9804 g_return_val_if_fail(gtkconv != NULL, FALSE);
9805
9806 return (gtkconv->win == hidden_convwin);
9782 } 9807 }
9783 9808
9784 9809
9785 /* Algorithm from http://www.w3.org/TR/AERT#color-contrast */ 9810 /* Algorithm from http://www.w3.org/TR/AERT#color-contrast */
9786 static gboolean 9811 static gboolean
9877 *color_count = i; 9902 *color_count = i;
9878 } 9903 }
9879 9904
9880 return colors; 9905 return colors;
9881 } 9906 }
9882
9883

mercurial