| 159 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); |
160 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); |
| 160 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); |
161 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); |
| 161 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); |
162 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); |
| 162 static gboolean pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv); |
163 static gboolean pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv); |
| 163 static void pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv); |
164 static void pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv); |
| |
165 static void hide_conv(PidginConversation *gtkconv, gboolean closetimer); |
| 164 |
166 |
| 165 static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y, |
167 static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y, |
| 166 int width, int height); |
168 int width, int height); |
| 167 |
169 |
| 168 static GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) { |
170 static GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) { |
| 206 /************************************************************************** |
208 /************************************************************************** |
| 207 * Callbacks |
209 * Callbacks |
| 208 **************************************************************************/ |
210 **************************************************************************/ |
| 209 |
211 |
| 210 static gboolean |
212 static gboolean |
| 211 close_conv_cb(GtkWidget *w, GdkEventButton *event, PidginConversation *gtkconv) |
213 close_this_sucker(gpointer data) |
| 212 { |
214 { |
| |
215 PidginConversation *gtkconv = data; |
| 213 GList *list = g_list_copy(gtkconv->convs); |
216 GList *list = g_list_copy(gtkconv->convs); |
| 214 |
|
| 215 g_list_foreach(list, (GFunc)purple_conversation_destroy, NULL); |
217 g_list_foreach(list, (GFunc)purple_conversation_destroy, NULL); |
| 216 g_list_free(list); |
218 g_list_free(list); |
| |
219 return FALSE; |
| |
220 } |
| |
221 |
| |
222 static gboolean |
| |
223 close_conv_cb(GtkWidget *w, GdkEventButton *dontuse, PidginConversation *gtkconv) |
| |
224 { |
| |
225 /* We are going to destroy the conversations immediately only if the 'close immediately' |
| |
226 * preference is selected. Otherwise, close the conversation after a reasonable timeout |
| |
227 * (I am going to consider 10 minutes as a 'reasonable timeout' here. |
| |
228 * For chats, close immediately if the chat is not in the buddylist, or if the chat is |
| |
229 * not marked 'Persistent' */ |
| |
230 PurpleConversation *conv = gtkconv->active_conv; |
| |
231 PurpleAccount *account = purple_conversation_get_account(conv); |
| |
232 const char *name = purple_conversation_get_name(conv); |
| |
233 |
| |
234 switch (purple_conversation_get_type(conv)) { |
| |
235 case PURPLE_CONV_TYPE_IM: |
| |
236 { |
| |
237 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/close_immediately")) |
| |
238 close_this_sucker(gtkconv); |
| |
239 else |
| |
240 hide_conv(gtkconv, TRUE); |
| |
241 break; |
| |
242 } |
| |
243 case PURPLE_CONV_TYPE_CHAT: |
| |
244 { |
| |
245 PurpleChat *chat = purple_blist_find_chat(account, name); |
| |
246 if (!chat || |
| |
247 !purple_blist_node_get_bool(&chat->node, "gtk-persistent")) |
| |
248 close_this_sucker(gtkconv); |
| |
249 else |
| |
250 hide_conv(gtkconv, FALSE); |
| |
251 break; |
| |
252 } |
| |
253 default: |
| |
254 ; |
| |
255 } |
| 217 |
256 |
| 218 return TRUE; |
257 return TRUE; |
| 219 } |
258 } |
| 220 |
259 |
| 221 static gboolean |
260 static gboolean |
| 335 } |
374 } |
| 336 |
375 |
| 337 static void clear_conversation_scrollback(PurpleConversation *conv) |
376 static void clear_conversation_scrollback(PurpleConversation *conv) |
| 338 { |
377 { |
| 339 PidginConversation *gtkconv = NULL; |
378 PidginConversation *gtkconv = NULL; |
| |
379 GList *iter; |
| 340 |
380 |
| 341 gtkconv = PIDGIN_CONVERSATION(conv); |
381 gtkconv = PIDGIN_CONVERSATION(conv); |
| 342 |
382 |
| 343 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); |
383 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); |
| |
384 for (iter = gtkconv->convs; iter; iter = iter->next) |
| |
385 purple_conversation_clear_message_history(iter->data); |
| 344 } |
386 } |
| 345 |
387 |
| 346 static PurpleCmdRet |
388 static PurpleCmdRet |
| 347 clear_command_cb(PurpleConversation *conv, |
389 clear_command_cb(PurpleConversation *conv, |
| 348 const char *cmd, char **args, char **error, void *data) |
390 const char *cmd, char **args, char **error, void *data) |
| 349 { |
391 { |
| 350 clear_conversation_scrollback(conv); |
392 clear_conversation_scrollback(conv); |
| 351 purple_conversation_clear_message_history(conv); |
|
| 352 return PURPLE_CMD_STATUS_OK; |
393 return PURPLE_CMD_STATUS_OK; |
| 353 } |
394 } |
| 354 |
395 |
| 355 static PurpleCmdRet |
396 static PurpleCmdRet |
| 356 clearall_command_cb(PurpleConversation *conv, |
397 clearall_command_cb(PurpleConversation *conv, |
| 1313 conv = pidgin_conv_window_get_active_conversation(win); |
1351 conv = pidgin_conv_window_get_active_conversation(win); |
| 1314 |
1352 |
| 1315 add_remove_cb(NULL, PIDGIN_CONVERSATION(conv)); |
1353 add_remove_cb(NULL, PIDGIN_CONVERSATION(conv)); |
| 1316 } |
1354 } |
| 1317 |
1355 |
| 1318 #if 0 |
1356 static gboolean |
| 1319 static void |
1357 close_already(gpointer data) |
| 1320 menu_hide_conv_cb(gpointer data, guint action, GtkWidget *widget) |
1358 { |
| 1321 { |
1359 purple_conversation_destroy(data); |
| 1322 PidginWindow *win = data; |
1360 return FALSE; |
| 1323 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win); |
1361 } |
| 1324 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); |
1362 |
| |
1363 static void |
| |
1364 hide_conv(PidginConversation *gtkconv, gboolean closetimer) |
| |
1365 { |
| |
1366 GList *list; |
| |
1367 |
| 1325 purple_signal_emit(pidgin_conversations_get_handle(), |
1368 purple_signal_emit(pidgin_conversations_get_handle(), |
| 1326 "conversation-hiding", gtkconv); |
1369 "conversation-hiding", gtkconv); |
| 1327 purple_conversation_set_ui_ops(conv, NULL); |
1370 |
| 1328 } |
1371 for (list = g_list_copy(gtkconv->convs); list; list = g_list_delete_link(list, list)) { |
| 1329 #endif |
1372 PurpleConversation *conv = list->data; |
| |
1373 if (closetimer) { |
| |
1374 guint timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer")); |
| |
1375 if (timer) |
| |
1376 purple_timeout_remove(timer); |
| |
1377 timer = purple_timeout_add_seconds(CLOSE_CONV_TIMEOUT_SECS, close_already, conv); |
| |
1378 purple_conversation_set_data(conv, "close-timer", GINT_TO_POINTER(timer)); |
| |
1379 } |
| |
1380 purple_conversation_set_ui_ops(conv, NULL); |
| |
1381 } |
| |
1382 } |
| 1330 |
1383 |
| 1331 static void |
1384 static void |
| 1332 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) |
1385 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) |
| 1333 { |
1386 { |
| 1334 PidginWindow *win = data; |
1387 PidginWindow *win = data; |
| 2341 } |
2394 } |
| 2342 |
2395 |
| 2343 return get_prpl_icon_list(account); |
2396 return get_prpl_icon_list(account); |
| 2344 } |
2397 } |
| 2345 |
2398 |
| 2346 GdkPixbuf * |
2399 static GdkPixbuf * |
| 2347 pidgin_conv_get_tab_icon(PurpleConversation *conv, gboolean small_icon) |
2400 pidgin_conv_get_icon(PurpleConversation *conv, GtkWidget *parent, const char *icon_size) |
| 2348 { |
2401 { |
| 2349 PurpleAccount *account = NULL; |
2402 PurpleAccount *account = NULL; |
| 2350 const char *name = NULL; |
2403 const char *name = NULL; |
| 2351 GdkPixbuf *status = NULL; |
2404 GdkPixbuf *status = NULL; |
| 2352 PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); |
2405 PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); |
| 2353 const char *icon_size = small_icon ? PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC : PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL; |
2406 g_return_val_if_fail(conv != NULL, NULL); |
| 2354 g_return_val_if_fail(conv != NULL, NULL); |
2407 |
| 2355 |
2408 account = purple_conversation_get_account(conv); |
| 2356 account = purple_conversation_get_account(conv); |
2409 name = purple_conversation_get_name(conv); |
| 2357 name = purple_conversation_get_name(conv); |
2410 |
| 2358 |
2411 g_return_val_if_fail(account != NULL, NULL); |
| 2359 g_return_val_if_fail(account != NULL, NULL); |
2412 g_return_val_if_fail(name != NULL, NULL); |
| 2360 g_return_val_if_fail(name != NULL, NULL); |
2413 |
| 2361 |
2414 /* Use the buddy icon, if possible */ |
| 2362 /* Use the buddy icon, if possible */ |
2415 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 2363 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
2416 PurpleBuddy *b = purple_find_buddy(account, name); |
| 2364 PurpleBuddy *b = purple_find_buddy(account, name); |
2417 if (b != NULL) { |
| 2365 if (b != NULL) { |
|
| 2366 PurplePresence *p = purple_buddy_get_presence(b); |
2418 PurplePresence *p = purple_buddy_get_presence(b); |
| 2367 /* I hate this hack. It fixes a bug where the pending message icon |
2419 /* I hate this hack. It fixes a bug where the pending message icon |
| 2368 * displays in the conv tab even though it shouldn't. |
2420 * displays in the conv tab even though it shouldn't. |
| 2369 * A better solution would be great. */ |
2421 * A better solution would be great. */ |
| 2370 if (ops && ops->update) |
2422 if (ops && ops->update) |
| 2371 ops->update(NULL, (PurpleBlistNode*)b); |
2423 ops->update(NULL, (PurpleBlistNode*)b); |
| 2372 |
2424 |
| 2373 /* XXX Seanegan: We really need a util function to return a pixbuf for a Presence to avoid all this switching */ |
2425 /* XXX Seanegan: We really need a util function to return a pixbuf for a Presence to avoid all this switching */ |
| 2374 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY)) |
2426 if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AWAY)) |
| 2375 status = pidgin_create_status_icon(PURPLE_STATUS_AWAY, PIDGIN_CONVERSATION(conv)->icon, icon_size); |
2427 status = pidgin_create_status_icon(PURPLE_STATUS_AWAY, parent, icon_size); |
| 2376 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY)) |
2428 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_EXTENDED_AWAY)) |
| 2377 status = pidgin_create_status_icon(PURPLE_STATUS_EXTENDED_AWAY, PIDGIN_CONVERSATION(conv)->icon, icon_size); |
2429 status = pidgin_create_status_icon(PURPLE_STATUS_EXTENDED_AWAY, parent, icon_size); |
| 2378 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_OFFLINE)) |
2430 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_OFFLINE)) |
| 2379 status = pidgin_create_status_icon(PURPLE_STATUS_OFFLINE, PIDGIN_CONVERSATION(conv)->icon, icon_size); |
2431 status = pidgin_create_status_icon(PURPLE_STATUS_OFFLINE, parent, icon_size); |
| 2380 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AVAILABLE)) |
2432 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AVAILABLE)) |
| 2381 status = pidgin_create_status_icon(PURPLE_STATUS_AVAILABLE, PIDGIN_CONVERSATION(conv)->icon, icon_size); |
2433 status = pidgin_create_status_icon(PURPLE_STATUS_AVAILABLE, parent, icon_size); |
| 2382 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_INVISIBLE)) |
2434 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_INVISIBLE)) |
| 2383 status = pidgin_create_status_icon(PURPLE_STATUS_INVISIBLE, PIDGIN_CONVERSATION(conv)->icon, icon_size); |
2435 status = pidgin_create_status_icon(PURPLE_STATUS_INVISIBLE, parent, icon_size); |
| 2384 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE)) |
2436 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE)) |
| 2385 status = pidgin_create_status_icon(PURPLE_STATUS_UNAVAILABLE, PIDGIN_CONVERSATION(conv)->icon, icon_size); |
2437 status = pidgin_create_status_icon(PURPLE_STATUS_UNAVAILABLE, parent, icon_size); |
| 2386 } |
2438 } |
| 2387 } |
2439 } |
| 2388 |
2440 |
| 2389 /* If they don't have a buddy icon, then use the PRPL icon */ |
2441 /* If they don't have a buddy icon, then use the PRPL icon */ |
| 2390 if (status == NULL) { |
2442 if (status == NULL) { |
| 2391 GtkIconSize size = gtk_icon_size_from_name(icon_size); |
2443 GtkIconSize size = gtk_icon_size_from_name(icon_size); |
| 2392 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
2444 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 2393 status = gtk_widget_render_icon (PIDGIN_CONVERSATION(conv)->icon, PIDGIN_STOCK_STATUS_PERSON, |
2445 status = gtk_widget_render_icon (parent, PIDGIN_STOCK_STATUS_PERSON, |
| 2394 size, "GtkWidget"); |
2446 size, "GtkWidget"); |
| 2395 } else { |
2447 } else { |
| 2396 status = gtk_widget_render_icon (PIDGIN_CONVERSATION(conv)->icon, PIDGIN_STOCK_STATUS_CHAT, |
2448 status = gtk_widget_render_icon (parent, PIDGIN_STOCK_STATUS_CHAT, |
| 2397 size, "GtkWidget"); |
2449 size, "GtkWidget"); |
| 2398 } |
2450 } |
| 2399 } |
2451 } |
| 2400 return status; |
2452 return status; |
| |
2453 } |
| |
2454 |
| |
2455 GdkPixbuf * |
| |
2456 pidgin_conv_get_tab_icon(PurpleConversation *conv, gboolean small_icon) |
| |
2457 { |
| |
2458 const char *icon_size = small_icon ? PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC : PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL; |
| |
2459 return pidgin_conv_get_icon(conv, PIDGIN_CONVERSATION(conv)->icon, icon_size); |
| 2401 } |
2460 } |
| 2402 |
2461 |
| 2403 |
2462 |
| 2404 static void |
2463 static void |
| 2405 update_tab_icon(PurpleConversation *conv) |
2464 update_tab_icon(PurpleConversation *conv) |
| 2832 for (l = convs; l != NULL ; l = l->next) { |
2895 for (l = convs; l != NULL ; l = l->next) { |
| 2833 PurpleConversation *conv = (PurpleConversation*)l->data; |
2896 PurpleConversation *conv = (PurpleConversation*)l->data; |
| 2834 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
2897 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
| 2835 |
2898 |
| 2836 GtkWidget *icon = gtk_image_new(); |
2899 GtkWidget *icon = gtk_image_new(); |
| 2837 GdkPixbuf *pbuf = pidgin_conv_get_tab_icon(conv, TRUE); |
2900 GdkPixbuf *pbuf = pidgin_conv_get_icon(conv, icon, PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC); |
| 2838 GtkWidget *item; |
2901 GtkWidget *item; |
| 2839 gchar *text = g_strdup_printf("%s (%d)", |
2902 gchar *text = g_strdup_printf("%s (%d)", |
| 2840 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)), |
2903 gtkconv ? gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)) : purple_conversation_get_name(conv), |
| 2841 gtkconv->unseen_count); |
2904 gtkconv ? gtkconv->unseen_count : GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))); |
| 2842 |
2905 |
| 2843 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf); |
2906 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf); |
| 2844 g_object_unref(pbuf); |
2907 g_object_unref(pbuf); |
| 2845 |
2908 |
| 2846 item = gtk_image_menu_item_new_with_label(text); |
2909 item = gtk_image_menu_item_new_with_label(text); |
| 5040 |
5106 |
| 5041 g_signal_connect_swapped(G_OBJECT(pane), "focus", |
5107 g_signal_connect_swapped(G_OBJECT(pane), "focus", |
| 5042 G_CALLBACK(gtk_widget_grab_focus), |
5108 G_CALLBACK(gtk_widget_grab_focus), |
| 5043 gtkconv->entry); |
5109 gtkconv->entry); |
| 5044 |
5110 |
| 5045 if (hidden) |
5111 pidgin_conv_placement_place(gtkconv); |
| 5046 pidgin_conv_window_add_gtkconv(hidden_convwin, gtkconv); |
|
| 5047 else |
|
| 5048 pidgin_conv_placement_place(gtkconv); |
|
| 5049 |
5112 |
| 5050 if (nick_colors == NULL) { |
5113 if (nick_colors == NULL) { |
| 5051 nbr_nick_colors = NUM_NICK_COLORS; |
5114 nbr_nick_colors = NUM_NICK_COLORS; |
| 5052 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); |
5115 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); |
| 5053 } |
5116 } |
| 5054 } |
5117 } |
| 5055 |
5118 |
| |
5119 #if 0 |
| 5056 static void |
5120 static void |
| 5057 pidgin_conv_new_hidden(PurpleConversation *conv) |
5121 pidgin_conv_new_hidden(PurpleConversation *conv) |
| 5058 { |
5122 { |
| 5059 private_gtkconv_new(conv, TRUE); |
5123 private_gtkconv_new(conv, TRUE); |
| 5060 } |
5124 } |
| |
5125 #endif |
| 5061 |
5126 |
| 5062 void |
5127 void |
| 5063 pidgin_conv_new(PurpleConversation *conv) |
5128 pidgin_conv_new(PurpleConversation *conv) |
| 5064 { |
5129 { |
| 5065 private_gtkconv_new(conv, FALSE); |
5130 private_gtkconv_new(conv, FALSE); |
| 5068 static void |
5133 static void |
| 5069 received_im_msg_cb(PurpleAccount *account, char *sender, char *message, |
5134 received_im_msg_cb(PurpleAccount *account, char *sender, char *message, |
| 5070 PurpleConversation *conv, PurpleMessageFlags flags) |
5135 PurpleConversation *conv, PurpleMessageFlags flags) |
| 5071 { |
5136 { |
| 5072 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops(); |
5137 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops(); |
| 5073 if (conv != NULL) |
5138 |
| |
5139 /* create hidden conv if hide_new pref is always */ |
| |
5140 /* or if hide_new pref is away and account is away */ |
| |
5141 if ((strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0) || |
| |
5142 (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 && |
| |
5143 !purple_status_is_available(purple_account_get_active_status(account)))) { |
| |
5144 if (!conv) { |
| |
5145 ui_ops->create_conversation = NULL; |
| |
5146 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); |
| |
5147 purple_conversation_set_ui_ops(conv, NULL); |
| |
5148 ui_ops->create_conversation = pidgin_conv_new; |
| |
5149 } |
| |
5150 } else { |
| |
5151 /* new message for an IM */ |
| |
5152 if (conv && conv->type == PURPLE_CONV_TYPE_IM) |
| |
5153 pidgin_conv_attach_to_conversation(conv); |
| |
5154 } |
| |
5155 } |
| |
5156 |
| |
5157 static void |
| |
5158 pidgin_conv_destroy(PurpleConversation *conv) |
| |
5159 { |
| |
5160 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
| |
5161 |
| |
5162 if (!gtkconv) |
| 5074 return; |
5163 return; |
| 5075 |
|
| 5076 /* create hidden conv if hide_new pref is always */ |
|
| 5077 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0) |
|
| 5078 { |
|
| 5079 ui_ops->create_conversation = pidgin_conv_new_hidden; |
|
| 5080 purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); |
|
| 5081 ui_ops->create_conversation = pidgin_conv_new; |
|
| 5082 return; |
|
| 5083 } |
|
| 5084 |
|
| 5085 /* create hidden conv if hide_new pref is away and account is away */ |
|
| 5086 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 && |
|
| 5087 !purple_status_is_available(purple_account_get_active_status(account))) |
|
| 5088 { |
|
| 5089 ui_ops->create_conversation = pidgin_conv_new_hidden; |
|
| 5090 purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); |
|
| 5091 ui_ops->create_conversation = pidgin_conv_new; |
|
| 5092 return; |
|
| 5093 } |
|
| 5094 } |
|
| 5095 |
|
| 5096 static void |
|
| 5097 pidgin_conv_destroy(PurpleConversation *conv) |
|
| 5098 { |
|
| 5099 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
|
| 5100 |
5164 |
| 5101 gtkconv->convs = g_list_remove(gtkconv->convs, conv); |
5165 gtkconv->convs = g_list_remove(gtkconv->convs, conv); |
| 5102 /* Don't destroy ourselves until all our convos are gone */ |
5166 /* Don't destroy ourselves until all our convos are gone */ |
| 5103 if (gtkconv->convs) { |
5167 if (gtkconv->convs) { |
| 5104 /* Make sure the destroyed conversation is not the active one */ |
5168 /* Make sure the destroyed conversation is not the active one */ |
| 7070 |
7147 |
| 7071 static void |
7148 static void |
| 7072 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus, |
7149 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus, |
| 7073 PurpleStatus *newstatus) |
7150 PurpleStatus *newstatus) |
| 7074 { |
7151 { |
| |
7152 #if 0 |
| 7075 GList *l; |
7153 GList *l; |
| 7076 PurpleConversation *conv = NULL; |
7154 PurpleConversation *conv = NULL; |
| 7077 PidginConversation *gtkconv; |
7155 PidginConversation *gtkconv; |
| 7078 |
7156 |
| 7079 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0) |
7157 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0) |
| 7080 return; |
7158 return; |
| 7081 |
7159 |
| 7082 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus)) |
7160 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus)) |
| 7083 return; |
7161 return; |
| 7084 |
7162 #endif |
| 7085 while ((l = hidden_convwin->gtkconvs) != NULL) |
|
| 7086 { |
|
| 7087 gtkconv = l->data; |
|
| 7088 |
|
| 7089 conv = gtkconv->active_conv; |
|
| 7090 |
|
| 7091 while(l && !purple_status_is_available( |
|
| 7092 purple_account_get_active_status( |
|
| 7093 purple_conversation_get_account(conv)))) |
|
| 7094 l = l->next; |
|
| 7095 if (!l) |
|
| 7096 break; |
|
| 7097 |
|
| 7098 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv); |
|
| 7099 pidgin_conv_placement_place(gtkconv); |
|
| 7100 |
|
| 7101 /* TODO: do we need to do anything for any other conversations that are in the same gtkconv here? |
|
| 7102 * I'm a little concerned that not doing so will cause the "pending" indicator in the gtkblist not to be cleared. -DAA*/ |
|
| 7103 purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN); |
|
| 7104 } |
|
| 7105 } |
7163 } |
| 7106 |
7164 |
| 7107 static void |
7165 static void |
| 7108 hide_new_pref_cb(const char *name, PurplePrefType type, |
7166 hide_new_pref_cb(const char *name, PurplePrefType type, |
| 7109 gconstpointer value, gpointer data) |
7167 gconstpointer value, gpointer data) |
| 7110 { |
7168 { |
| 7111 GList *l; |
7169 GList *l; |
| 7112 PurpleConversation *conv = NULL; |
|
| 7113 PidginConversation *gtkconv; |
|
| 7114 gboolean when_away = FALSE; |
7170 gboolean when_away = FALSE; |
| 7115 |
|
| 7116 if(!hidden_convwin) |
|
| 7117 return; |
|
| 7118 |
7171 |
| 7119 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0) |
7172 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0) |
| 7120 return; |
7173 return; |
| 7121 |
7174 |
| 7122 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0) |
7175 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0) |
| 7123 when_away = TRUE; |
7176 when_away = TRUE; |
| 7124 |
7177 |
| 7125 while ((l = hidden_convwin->gtkconvs) != NULL) |
7178 for (l = purple_get_conversations(); l; l = l->next) |
| 7126 { |
7179 { |
| 7127 gtkconv = l->data; |
7180 PurpleConversation *conv = l->data; |
| 7128 |
7181 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
| 7129 conv = gtkconv->active_conv; |
7182 if (gtkconv) |
| 7130 |
7183 continue; |
| 7131 if(when_away && !purple_status_is_available( |
7184 if(when_away && !purple_status_is_available( |
| 7132 purple_account_get_active_status( |
7185 purple_account_get_active_status( |
| 7133 purple_conversation_get_account(conv)))) |
7186 purple_conversation_get_account(conv)))) |
| 7134 continue; |
7187 continue; |
| 7135 |
7188 pidgin_conv_attach_to_conversation(conv); |
| 7136 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv); |
|
| 7137 pidgin_conv_placement_place(gtkconv); |
|
| 7138 } |
7189 } |
| 7139 } |
7190 } |
| 7140 |
7191 |
| 7141 |
7192 |
| 7142 static void |
7193 static void |
| 7188 * one of the contacts containing the buddy corresponding to |
7239 * one of the contacts containing the buddy corresponding to |
| 7189 * a conversation. It's easier to just update them all. */ |
7240 * a conversation. It's easier to just update them all. */ |
| 7190 /* if (purple_conversation_get_account(conv) == account) */ |
7241 /* if (purple_conversation_get_account(conv) == account) */ |
| 7191 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | |
7242 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | |
| 7192 PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE); |
7243 PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE); |
| |
7244 |
| |
7245 if (PURPLE_CONNECTION_IS_CONNECTED(gc) && |
| |
7246 conv->type == PURPLE_CONV_TYPE_CHAT && |
| |
7247 conv->account == gc->account && |
| |
7248 purple_conversation_get_data(conv, "want-to-rejoin")) { |
| |
7249 GHashTable *comps = NULL; |
| |
7250 PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name); |
| |
7251 if (chat == NULL) { |
| |
7252 if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) |
| |
7253 comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, conv->name); |
| |
7254 } else { |
| |
7255 comps = chat->components; |
| |
7256 } |
| |
7257 serv_join_chat(gc, comps); |
| |
7258 if (chat == NULL && comps != NULL) |
| |
7259 g_hash_table_destroy(comps); |
| |
7260 } |
| 7193 } |
7261 } |
| 7194 } |
7262 } |
| 7195 |
7263 |
| 7196 static gboolean |
7264 static gboolean |
| 7197 update_buddy_status_timeout(PurpleBuddy *buddy) |
7265 update_buddy_status_timeout(PurpleBuddy *buddy) |
| 7315 add_message_history_to_gtkconv(gpointer data) |
7383 add_message_history_to_gtkconv(gpointer data) |
| 7316 { |
7384 { |
| 7317 PidginConversation *gtkconv = data; |
7385 PidginConversation *gtkconv = data; |
| 7318 int count = 0; |
7386 int count = 0; |
| 7319 int timer = gtkconv->attach.timer; |
7387 int timer = gtkconv->attach.timer; |
| |
7388 time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time")); |
| |
7389 |
| 7320 gtkconv->attach.timer = 0; |
7390 gtkconv->attach.timer = 0; |
| 7321 while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ |
7391 while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ |
| 7322 PurpleConvMessage *msg = gtkconv->attach.current->data; |
7392 PurpleConvMessage *msg = gtkconv->attach.current->data; |
| |
7393 if (when && when < msg->when) { |
| |
7394 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0); |
| |
7395 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
| |
7396 } |
| 7323 pidgin_conv_write_conv(gtkconv->active_conv, msg->who, msg->who, msg->what, msg->flags, msg->when); |
7397 pidgin_conv_write_conv(gtkconv->active_conv, msg->who, msg->who, msg->what, msg->flags, msg->when); |
| 7324 gtkconv->attach.current = gtkconv->attach.current->prev; |
7398 gtkconv->attach.current = gtkconv->attach.current->prev; |
| 7325 count++; |
7399 count++; |
| 7326 } |
7400 } |
| 7327 gtkconv->attach.timer = timer; |
7401 gtkconv->attach.timer = timer; |
| 7328 if (gtkconv->attach.current) |
7402 if (gtkconv->attach.current) |
| 7329 return TRUE; |
7403 return TRUE; |
| 7330 |
7404 |
| |
7405 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
| 7331 purple_signal_emit(pidgin_conversations_get_handle(), |
7406 purple_signal_emit(pidgin_conversations_get_handle(), |
| 7332 "conversation-displayed", gtkconv); |
7407 "conversation-displayed", gtkconv); |
| 7333 g_source_remove(gtkconv->attach.timer); |
7408 g_source_remove(gtkconv->attach.timer); |
| 7334 gtkconv->attach.timer = 0; |
7409 gtkconv->attach.timer = 0; |
| 7335 return FALSE; |
7410 return FALSE; |
| 7337 |
7412 |
| 7338 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv) |
7413 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv) |
| 7339 { |
7414 { |
| 7340 GList *list; |
7415 GList *list; |
| 7341 PidginConversation *gtkconv; |
7416 PidginConversation *gtkconv; |
| |
7417 int timer; |
| 7342 |
7418 |
| 7343 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) |
7419 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) |
| 7344 return FALSE; |
7420 return FALSE; |
| 7345 |
7421 |
| |
7422 purple_conversation_set_data(conv, "unseen-count", NULL); |
| 7346 purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops()); |
7423 purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops()); |
| 7347 private_gtkconv_new(conv, FALSE); |
7424 private_gtkconv_new(conv, FALSE); |
| 7348 gtkconv = PIDGIN_CONVERSATION(conv); |
7425 gtkconv = PIDGIN_CONVERSATION(conv); |
| 7349 |
7426 |
| 7350 list = purple_conversation_get_message_history(conv); |
7427 list = purple_conversation_get_message_history(conv); |
| 7351 if (list) { |
7428 if (list) { |
| 7352 list = g_list_last(list); |
7429 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", |
| 7353 gtkconv->attach.current = list; |
7430 GINT_TO_POINTER(((PurpleConvMessage*)(list->data))->when)); |
| |
7431 gtkconv->attach.current = g_list_last(list); |
| 7354 gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv); |
7432 gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv); |
| 7355 } else { |
7433 } else { |
| 7356 purple_signal_emit(pidgin_conversations_get_handle(), |
7434 purple_signal_emit(pidgin_conversations_get_handle(), |
| 7357 "conversation-displayed", gtkconv); |
7435 "conversation-displayed", gtkconv); |
| 7358 } |
7436 } |
| 7626 purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", handle, |
7705 purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", handle, |
| 7627 PURPLE_CALLBACK(update_chat_topic), NULL); |
7706 PURPLE_CALLBACK(update_chat_topic), NULL); |
| 7628 purple_signal_connect_priority(purple_conversations_get_handle(), "conversation-updated", handle, |
7707 purple_signal_connect_priority(purple_conversations_get_handle(), "conversation-updated", handle, |
| 7629 PURPLE_CALLBACK(pidgin_conv_updated), NULL, |
7708 PURPLE_CALLBACK(pidgin_conv_updated), NULL, |
| 7630 PURPLE_SIGNAL_PRIORITY_LOWEST); |
7709 PURPLE_SIGNAL_PRIORITY_LOWEST); |
| |
7710 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle, |
| |
7711 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
| |
7712 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, |
| |
7713 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
| 7631 } |
7714 } |
| 7632 |
7715 |
| 7633 void |
7716 void |
| 7634 pidgin_conversations_uninit(void) |
7717 pidgin_conversations_uninit(void) |
| 7635 { |
7718 { |
| 7636 purple_prefs_disconnect_by_handle(pidgin_conversations_get_handle()); |
7719 purple_prefs_disconnect_by_handle(pidgin_conversations_get_handle()); |
| 7637 purple_signals_disconnect_by_handle(pidgin_conversations_get_handle()); |
7720 purple_signals_disconnect_by_handle(pidgin_conversations_get_handle()); |
| 7638 purple_signals_unregister_by_instance(pidgin_conversations_get_handle()); |
7721 purple_signals_unregister_by_instance(pidgin_conversations_get_handle()); |
| 7639 pidgin_conv_window_destroy(hidden_convwin); |
|
| 7640 hidden_convwin=NULL; |
|
| 7641 } |
7722 } |
| 7642 |
7723 |
| 7643 |
7724 |
| 7644 |
7725 |
| 7645 |
7726 |