pidgin/gtkconv.c

branch
release-2.3.1
changeset 21721
721e4b54de86
parent 21656
acb7fa0ac03d
child 21722
8b275923f914
equal deleted inserted replaced
21720:235394d5c7f4 21721:721e4b54de86
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;
1376 if (timer) 1377 if (timer)
1377 purple_timeout_remove(timer); 1378 purple_timeout_remove(timer);
1378 timer = purple_timeout_add_seconds(CLOSE_CONV_TIMEOUT_SECS, close_already, conv); 1379 timer = purple_timeout_add_seconds(CLOSE_CONV_TIMEOUT_SECS, close_already, conv);
1379 purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(timer)); 1380 purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(timer));
1380 } 1381 }
1382 #if 0
1383 /* I will miss you */
1381 purple_conversation_set_ui_ops(conv, NULL); 1384 purple_conversation_set_ui_ops(conv, NULL);
1385 #else
1386 pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
1387 pidgin_conv_window_add_gtkconv(hidden_convwin, gtkconv);
1388 #endif
1382 } 1389 }
1383 } 1390 }
1384 1391
1385 static void 1392 static void
1386 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) 1393 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget)
2814 pidgin_conv_present_conversation(PurpleConversation *conv) 2821 pidgin_conv_present_conversation(PurpleConversation *conv)
2815 { 2822 {
2816 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 2823 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
2817 GdkModifierType state; 2824 GdkModifierType state;
2818 2825
2819 if (gtkconv == NULL) { 2826 if(gtkconv->win==hidden_convwin) {
2820 pidgin_conv_attach_to_conversation(conv); 2827 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
2821 gtkconv = PIDGIN_CONVERSATION(conv); 2828 pidgin_conv_placement_place(gtkconv);
2822 } 2829 }
2823 2830
2824 pidgin_conv_switch_active_conversation(conv); 2831 pidgin_conv_switch_active_conversation(conv);
2825 /* Switch the tab only if the user initiated the event by pressing 2832 /* Switch the tab only if the user initiated the event by pressing
2826 * a button or hitting a key. */ 2833 * a button or hitting a key. */
2849 2856
2850 for (; l != NULL && (max_count == 0 || c < max_count); l = l->next) { 2857 for (; l != NULL && (max_count == 0 || c < max_count); l = l->next) {
2851 PurpleConversation *conv = (PurpleConversation*)l->data; 2858 PurpleConversation *conv = (PurpleConversation*)l->data;
2852 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 2859 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
2853 2860
2854 if (gtkconv != NULL && gtkconv->active_conv != conv) 2861 if(gtkconv == NULL || gtkconv->active_conv != conv)
2855 continue; 2862 continue;
2856 if (gtkconv == NULL) { 2863 if (gtkconv == NULL) {
2857 if (!purple_conversation_get_data(conv, "unseen-count") || 2864 if (!purple_conversation_get_data(conv, "unseen-count") ||
2858 !purple_conversation_get_data(conv, "unseen-state") || 2865 !purple_conversation_get_data(conv, "unseen-state") ||
2859 GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state"))<min_state) 2866 GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state"))<min_state)
2860 continue; 2867 continue;
2861 r = g_list_prepend(r, conv); 2868 r = g_list_prepend(r, conv);
2862 c++; 2869 c++;
2863 } else {
2864 if (gtkconv->unseen_state >= min_state && !hidden_only) {
2865 r = g_list_prepend(r, conv);
2866 c++;
2867 }
2868 } 2870 }
2869 } 2871 }
2870 2872
2871 return r; 2873 return r;
2872 } 2874 }
3167 GList *list; 3169 GList *list;
3168 PidginConversation *gtkconv; 3170 PidginConversation *gtkconv;
3169 PurpleConversation *conv; 3171 PurpleConversation *conv;
3170 GtkWidget *item; 3172 GtkWidget *item;
3171 3173
3172 if (win->window == NULL) 3174 if (win->window == NULL || win == hidden_convwin)
3173 return; 3175 return;
3174 3176
3175 gtkconv = pidgin_conv_window_get_active_gtkconv(win); 3177 gtkconv = pidgin_conv_window_get_active_gtkconv(win);
3176 if (gtkconv == NULL) 3178 if (gtkconv == NULL)
3177 return; 3179 return;
5023 PurpleConversationType conv_type = purple_conversation_get_type(conv); 5025 PurpleConversationType conv_type = purple_conversation_get_type(conv);
5024 GtkWidget *pane = NULL; 5026 GtkWidget *pane = NULL;
5025 GtkWidget *tab_cont; 5027 GtkWidget *tab_cont;
5026 PurpleBlistNode *convnode; 5028 PurpleBlistNode *convnode;
5027 5029
5028 if (hidden)
5029 return;
5030
5031 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) { 5030 if (conv_type == PURPLE_CONV_TYPE_IM && (gtkconv = pidgin_conv_find_gtkconv(conv))) {
5032 conv->ui_data = gtkconv; 5031 conv->ui_data = gtkconv;
5033 if (!g_list_find(gtkconv->convs, conv)) 5032 if (!g_list_find(gtkconv->convs, conv))
5034 gtkconv->convs = g_list_prepend(gtkconv->convs, conv); 5033 gtkconv->convs = g_list_prepend(gtkconv->convs, conv);
5035 pidgin_conv_switch_active_conversation(conv); 5034 pidgin_conv_switch_active_conversation(conv);
5124 5123
5125 g_signal_connect_swapped(G_OBJECT(pane), "focus", 5124 g_signal_connect_swapped(G_OBJECT(pane), "focus",
5126 G_CALLBACK(gtk_widget_grab_focus), 5125 G_CALLBACK(gtk_widget_grab_focus),
5127 gtkconv->entry); 5126 gtkconv->entry);
5128 5127
5129 pidgin_conv_placement_place(gtkconv); 5128 if (hidden)
5129 pidgin_conv_window_add_gtkconv(hidden_convwin, gtkconv);
5130 else
5131 pidgin_conv_placement_place(gtkconv);
5130 5132
5131 if (nick_colors == NULL) { 5133 if (nick_colors == NULL) {
5132 nbr_nick_colors = NUM_NICK_COLORS; 5134 nbr_nick_colors = NUM_NICK_COLORS;
5133 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); 5135 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]);
5134 } 5136 }
5135 } 5137 }
5136 5138
5137 #if 0
5138 static void 5139 static void
5139 pidgin_conv_new_hidden(PurpleConversation *conv) 5140 pidgin_conv_new_hidden(PurpleConversation *conv)
5140 { 5141 {
5141 private_gtkconv_new(conv, TRUE); 5142 private_gtkconv_new(conv, TRUE);
5142 } 5143 }
5143 #endif
5144 5144
5145 void 5145 void
5146 pidgin_conv_new(PurpleConversation *conv) 5146 pidgin_conv_new(PurpleConversation *conv)
5147 { 5147 {
5148 private_gtkconv_new(conv, FALSE); 5148 private_gtkconv_new(conv, FALSE);
5154 static void 5154 static void
5155 received_im_msg_cb(PurpleAccount *account, char *sender, char *message, 5155 received_im_msg_cb(PurpleAccount *account, char *sender, char *message,
5156 PurpleConversation *conv, PurpleMessageFlags flags) 5156 PurpleConversation *conv, PurpleMessageFlags flags)
5157 { 5157 {
5158 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops(); 5158 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops();
5159 gboolean hide = FALSE;
5159 5160
5160 /* create hidden conv if hide_new pref is always */ 5161 /* create hidden conv if hide_new pref is always */
5161 /* or if hide_new pref is away and account is away */ 5162 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0)
5162 if ((strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0) || 5163 hide = TRUE;
5163 (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 && 5164
5164 !purple_status_is_available(purple_account_get_active_status(account)))) { 5165 /* create hidden conv if hide_new pref is away and account is away */
5165 if (!conv) { 5166 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 &&
5166 ui_ops->create_conversation = NULL; 5167 !purple_status_is_available(purple_account_get_active_status(account)))
5167 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); 5168 hide = TRUE;
5168 purple_conversation_set_ui_ops(conv, NULL); 5169
5169 ui_ops->create_conversation = pidgin_conv_new; 5170 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv) && !hide) {
5170 } else { 5171 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
5171 /* TODO: update the unseen_state data on the conv here */ 5172 if (gtkconv->win == hidden_convwin) {
5172 } 5173 pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
5173 } else { 5174 pidgin_conv_placement_place(gtkconv);
5174 /* new message for an IM */ 5175 }
5175 if (conv && conv->type == PURPLE_CONV_TYPE_IM) 5176 return;
5176 pidgin_conv_attach_to_conversation(conv); 5177 }
5178
5179 if (hide) {
5180 ui_ops->create_conversation = pidgin_conv_new_hidden;
5181 purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender);
5182 ui_ops->create_conversation = pidgin_conv_new;
5177 } 5183 }
5178 } 5184 }
5179 5185
5180 static void 5186 static void
5181 pidgin_conv_destroy(PurpleConversation *conv) 5187 pidgin_conv_destroy(PurpleConversation *conv)
7194 7200
7195 static void 7201 static void
7196 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus, 7202 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus,
7197 PurpleStatus *newstatus) 7203 PurpleStatus *newstatus)
7198 { 7204 {
7199 #if 0
7200 GList *l; 7205 GList *l;
7201 PurpleConversation *conv = NULL; 7206 PurpleConversation *conv = NULL;
7202 PidginConversation *gtkconv; 7207 PidginConversation *gtkconv;
7203 7208
7204 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0) 7209 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0)
7205 return; 7210 return;
7206 7211
7207 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus)) 7212 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus))
7208 return; 7213 return;
7209 #endif 7214
7215 while ((l = hidden_convwin->gtkconvs) != NULL)
7216 {
7217 gtkconv = l->data;
7218
7219 conv = gtkconv->active_conv;
7220
7221 while(l && !purple_status_is_available(
7222 purple_account_get_active_status(
7223 purple_conversation_get_account(conv))))
7224 l = l->next;
7225 if (!l)
7226 break;
7227
7228 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
7229 pidgin_conv_placement_place(gtkconv);
7230
7231 /* TODO: do we need to do anything for any other conversations that are in the same gtkconv here?
7232 * I'm a little concerned that not doing so will cause the "pending" indicator in the gtkblist not to be cleared. -DAA*/
7233 purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN);
7234 }
7210 } 7235 }
7211 7236
7212 static void 7237 static void
7213 hide_new_pref_cb(const char *name, PurplePrefType type, 7238 hide_new_pref_cb(const char *name, PurplePrefType type,
7214 gconstpointer value, gpointer data) 7239 gconstpointer value, gpointer data)
7215 { 7240 {
7216 GList *l; 7241 GList *l;
7242 PurpleConversation *conv = NULL;
7243 PidginConversation *gtkconv;
7217 gboolean when_away = FALSE; 7244 gboolean when_away = FALSE;
7245
7246 if(!hidden_convwin)
7247 return;
7218 7248
7219 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0) 7249 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0)
7220 return; 7250 return;
7221 7251
7222 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0) 7252 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0)
7223 when_away = TRUE; 7253 when_away = TRUE;
7224 7254
7225 for (l = purple_get_conversations(); l; l = l->next) 7255 while ((l = hidden_convwin->gtkconvs) != NULL)
7226 { 7256 {
7227 PurpleConversation *conv = l->data; 7257 gtkconv = l->data;
7228 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 7258
7229 if (gtkconv) 7259 conv = gtkconv->active_conv;
7230 continue; 7260
7231 if(when_away && !purple_status_is_available( 7261 if(when_away && !purple_status_is_available(
7232 purple_account_get_active_status( 7262 purple_account_get_active_status(
7233 purple_conversation_get_account(conv)))) 7263 purple_conversation_get_account(conv))))
7234 continue; 7264 continue;
7235 pidgin_conv_attach_to_conversation(conv); 7265
7266 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
7267 pidgin_conv_placement_place(gtkconv);
7236 } 7268 }
7237 } 7269 }
7238 7270
7239 7271
7240 static void 7272 static void
7511 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv) 7543 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv)
7512 { 7544 {
7513 GList *list; 7545 GList *list;
7514 PidginConversation *gtkconv; 7546 PidginConversation *gtkconv;
7515 7547
7516 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) 7548 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) {
7517 return FALSE; 7549 gtkconv = PIDGIN_CONVERSATION(conv);
7550 if (gtkconv->win != hidden_convwin)
7551 return FALSE;
7552 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv);
7553 pidgin_conv_placement_place(gtkconv);
7554 return TRUE;
7555 }
7518 7556
7519 pidgin_conv_attach(conv); 7557 pidgin_conv_attach(conv);
7520 gtkconv = PIDGIN_CONVERSATION(conv); 7558 gtkconv = PIDGIN_CONVERSATION(conv);
7521 7559
7522 list = purple_conversation_get_message_history(conv); 7560 list = purple_conversation_get_message_history(conv);
7782 7820
7783 purple_signal_connect(purple_conversations_get_handle(), "received-im-msg", 7821 purple_signal_connect(purple_conversations_get_handle(), "received-im-msg",
7784 handle, G_CALLBACK(received_im_msg_cb), NULL); 7822 handle, G_CALLBACK(received_im_msg_cb), NULL);
7785 7823
7786 purple_conversations_set_ui_ops(&conversation_ui_ops); 7824 purple_conversations_set_ui_ops(&conversation_ui_ops);
7825
7826 hidden_convwin = pidgin_conv_window_new();
7827 window_list = g_list_remove(window_list, hidden_convwin);
7787 7828
7788 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", 7829 purple_signal_connect(purple_accounts_get_handle(), "account-status-changed",
7789 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL); 7830 handle, PURPLE_CALLBACK(account_status_changed_cb), NULL);
7790 7831
7791 /* Callbacks to update a conversation */ 7832 /* Callbacks to update a conversation */
7830 pidgin_conversations_uninit(void) 7871 pidgin_conversations_uninit(void)
7831 { 7872 {
7832 purple_prefs_disconnect_by_handle(pidgin_conversations_get_handle()); 7873 purple_prefs_disconnect_by_handle(pidgin_conversations_get_handle());
7833 purple_signals_disconnect_by_handle(pidgin_conversations_get_handle()); 7874 purple_signals_disconnect_by_handle(pidgin_conversations_get_handle());
7834 purple_signals_unregister_by_instance(pidgin_conversations_get_handle()); 7875 purple_signals_unregister_by_instance(pidgin_conversations_get_handle());
7876 pidgin_conv_window_destroy(hidden_convwin);
7877 hidden_convwin=NULL;
7835 } 7878 }
7836 7879
7837 7880
7838 7881
7839 7882
9283 0, 0, NULL, NULL, gtkconv); 9326 0, 0, NULL, NULL, gtkconv);
9284 9327
9285 if (win->gtkconvs && win->gtkconvs->next == NULL) 9328 if (win->gtkconvs && win->gtkconvs->next == NULL)
9286 pidgin_conv_tab_pack(win, win->gtkconvs->data); 9329 pidgin_conv_tab_pack(win, win->gtkconvs->data);
9287 9330
9288 if (!win->gtkconvs) 9331 if (!win->gtkconvs && win != hidden_convwin)
9289 pidgin_conv_window_destroy(win); 9332 pidgin_conv_window_destroy(win);
9290 } 9333 }
9291 9334
9292 PidginConversation * 9335 PidginConversation *
9293 pidgin_conv_window_get_gtkconv_at_index(const PidginWindow *win, int index) 9336 pidgin_conv_window_get_gtkconv_at_index(const PidginWindow *win, int index)
9822 } 9865 }
9823 9866
9824 gboolean 9867 gboolean
9825 pidgin_conv_is_hidden(PidginConversation *gtkconv) 9868 pidgin_conv_is_hidden(PidginConversation *gtkconv)
9826 { 9869 {
9827 return (gtkconv == NULL); 9870 g_return_val_if_fail(gtkconv != NULL, FALSE);
9871
9872 return (gtkconv->win == hidden_convwin);
9828 } 9873 }
9829 9874
9830 9875
9831 /* Algorithm from http://www.w3.org/TR/AERT#color-contrast */ 9876 /* Algorithm from http://www.w3.org/TR/AERT#color-contrast */
9832 static gboolean 9877 static gboolean

mercurial