| 145 static void gray_stuff_out(PidginConversation *gtkconv); |
146 static void gray_stuff_out(PidginConversation *gtkconv); |
| 146 static GList *generate_invite_user_names(PurpleConnection *gc); |
147 static GList *generate_invite_user_names(PurpleConnection *gc); |
| 147 static void add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name); |
148 static void add_chat_buddy_common(PurpleConversation *conv, PurpleConvChatBuddy *cb, const char *old_name); |
| 148 static gboolean tab_complete(PurpleConversation *conv); |
149 static gboolean tab_complete(PurpleConversation *conv); |
| 149 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type); |
150 static void pidgin_conv_updated(PurpleConversation *conv, PurpleConvUpdateType type); |
| |
151 static void conv_set_unseen(PurpleConversation *gtkconv, PidginUnseenState state); |
| 150 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state); |
152 static void gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state); |
| 151 static void update_typing_icon(PidginConversation *gtkconv); |
153 static void update_typing_icon(PidginConversation *gtkconv); |
| 152 static const char *item_factory_translate_func (const char *path, gpointer func_data); |
154 static const char *item_factory_translate_func (const char *path, gpointer func_data); |
| 153 gboolean pidgin_conv_has_focus(PurpleConversation *conv); |
155 gboolean pidgin_conv_has_focus(PurpleConversation *conv); |
| 154 static void pidgin_conv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data); |
156 static void pidgin_conv_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data); |
| 159 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); |
161 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); |
| 160 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); |
162 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); |
| 161 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); |
163 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); |
| 162 static gboolean pidgin_userlist_motion_cb (GtkWidget *w, GdkEventMotion *event, PidginConversation *gtkconv); |
164 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); |
165 static void pidgin_conv_leave_cb (GtkWidget *w, GdkEventCrossing *e, PidginConversation *gtkconv); |
| |
166 static void hide_conv(PidginConversation *gtkconv, gboolean closetimer); |
| 164 |
167 |
| 165 static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y, |
168 static void pidgin_conv_set_position_size(PidginWindow *win, int x, int y, |
| 166 int width, int height); |
169 int width, int height); |
| 167 |
170 |
| 168 static GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) { |
171 static GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) { |
| 206 /************************************************************************** |
209 /************************************************************************** |
| 207 * Callbacks |
210 * Callbacks |
| 208 **************************************************************************/ |
211 **************************************************************************/ |
| 209 |
212 |
| 210 static gboolean |
213 static gboolean |
| 211 close_conv_cb(GtkWidget *w, GdkEventButton *event, PidginConversation *gtkconv) |
214 close_this_sucker(gpointer data) |
| 212 { |
215 { |
| |
216 PidginConversation *gtkconv = data; |
| 213 GList *list = g_list_copy(gtkconv->convs); |
217 GList *list = g_list_copy(gtkconv->convs); |
| 214 |
|
| 215 g_list_foreach(list, (GFunc)purple_conversation_destroy, NULL); |
218 g_list_foreach(list, (GFunc)purple_conversation_destroy, NULL); |
| 216 g_list_free(list); |
219 g_list_free(list); |
| |
220 return FALSE; |
| |
221 } |
| |
222 |
| |
223 static gboolean |
| |
224 close_conv_cb(GtkWidget *w, GdkEventButton *dontuse, PidginConversation *gtkconv) |
| |
225 { |
| |
226 /* We are going to destroy the conversations immediately only if the 'close immediately' |
| |
227 * preference is selected. Otherwise, close the conversation after a reasonable timeout |
| |
228 * (I am going to consider 10 minutes as a 'reasonable timeout' here. |
| |
229 * For chats, close immediately if the chat is not in the buddylist, or if the chat is |
| |
230 * not marked 'Persistent' */ |
| |
231 PurpleConversation *conv = gtkconv->active_conv; |
| |
232 PurpleAccount *account = purple_conversation_get_account(conv); |
| |
233 const char *name = purple_conversation_get_name(conv); |
| |
234 |
| |
235 switch (purple_conversation_get_type(conv)) { |
| |
236 case PURPLE_CONV_TYPE_IM: |
| |
237 { |
| |
238 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/close_immediately")) |
| |
239 close_this_sucker(gtkconv); |
| |
240 else |
| |
241 hide_conv(gtkconv, TRUE); |
| |
242 break; |
| |
243 } |
| |
244 case PURPLE_CONV_TYPE_CHAT: |
| |
245 { |
| |
246 PurpleChat *chat = purple_blist_find_chat(account, name); |
| |
247 if (!chat || |
| |
248 !purple_blist_node_get_bool(&chat->node, "gtk-persistent")) |
| |
249 close_this_sucker(gtkconv); |
| |
250 else |
| |
251 hide_conv(gtkconv, FALSE); |
| |
252 break; |
| |
253 } |
| |
254 default: |
| |
255 ; |
| |
256 } |
| 217 |
257 |
| 218 return TRUE; |
258 return TRUE; |
| 219 } |
259 } |
| 220 |
260 |
| 221 static gboolean |
261 static gboolean |
| 335 } |
375 } |
| 336 |
376 |
| 337 static void clear_conversation_scrollback(PurpleConversation *conv) |
377 static void clear_conversation_scrollback(PurpleConversation *conv) |
| 338 { |
378 { |
| 339 PidginConversation *gtkconv = NULL; |
379 PidginConversation *gtkconv = NULL; |
| |
380 GList *iter; |
| 340 |
381 |
| 341 gtkconv = PIDGIN_CONVERSATION(conv); |
382 gtkconv = PIDGIN_CONVERSATION(conv); |
| 342 |
383 |
| 343 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); |
384 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); |
| |
385 for (iter = gtkconv->convs; iter; iter = iter->next) |
| |
386 purple_conversation_clear_message_history(iter->data); |
| 344 } |
387 } |
| 345 |
388 |
| 346 static PurpleCmdRet |
389 static PurpleCmdRet |
| 347 clear_command_cb(PurpleConversation *conv, |
390 clear_command_cb(PurpleConversation *conv, |
| 348 const char *cmd, char **args, char **error, void *data) |
391 const char *cmd, char **args, char **error, void *data) |
| 349 { |
392 { |
| 350 clear_conversation_scrollback(conv); |
393 clear_conversation_scrollback(conv); |
| 351 purple_conversation_clear_message_history(conv); |
|
| 352 return PURPLE_CMD_STATUS_OK; |
394 return PURPLE_CMD_STATUS_OK; |
| 353 } |
395 } |
| 354 |
396 |
| 355 static PurpleCmdRet |
397 static PurpleCmdRet |
| 356 clearall_command_cb(PurpleConversation *conv, |
398 clearall_command_cb(PurpleConversation *conv, |
| 1313 conv = pidgin_conv_window_get_active_conversation(win); |
1352 conv = pidgin_conv_window_get_active_conversation(win); |
| 1314 |
1353 |
| 1315 add_remove_cb(NULL, PIDGIN_CONVERSATION(conv)); |
1354 add_remove_cb(NULL, PIDGIN_CONVERSATION(conv)); |
| 1316 } |
1355 } |
| 1317 |
1356 |
| 1318 #if 0 |
1357 static gboolean |
| 1319 static void |
1358 close_already(gpointer data) |
| 1320 menu_hide_conv_cb(gpointer data, guint action, GtkWidget *widget) |
1359 { |
| 1321 { |
1360 purple_conversation_destroy(data); |
| 1322 PidginWindow *win = data; |
1361 return FALSE; |
| 1323 PidginConversation *gtkconv = pidgin_conv_window_get_active_gtkconv(win); |
1362 } |
| 1324 PurpleConversation *conv = pidgin_conv_window_get_active_conversation(win); |
1363 |
| |
1364 static void |
| |
1365 hide_conv(PidginConversation *gtkconv, gboolean closetimer) |
| |
1366 { |
| |
1367 GList *list; |
| |
1368 |
| 1325 purple_signal_emit(pidgin_conversations_get_handle(), |
1369 purple_signal_emit(pidgin_conversations_get_handle(), |
| 1326 "conversation-hiding", gtkconv); |
1370 "conversation-hiding", gtkconv); |
| 1327 purple_conversation_set_ui_ops(conv, NULL); |
1371 |
| 1328 } |
1372 for (list = g_list_copy(gtkconv->convs); list; list = g_list_delete_link(list, list)) { |
| 1329 #endif |
1373 PurpleConversation *conv = list->data; |
| |
1374 if (closetimer) { |
| |
1375 guint timer = GPOINTER_TO_INT(purple_conversation_get_data(conv, "close-timer")); |
| |
1376 if (timer) |
| |
1377 purple_timeout_remove(timer); |
| |
1378 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 } |
| |
1381 purple_conversation_set_ui_ops(conv, NULL); |
| |
1382 } |
| |
1383 } |
| 1330 |
1384 |
| 1331 static void |
1385 static void |
| 1332 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) |
1386 menu_close_conv_cb(gpointer data, guint action, GtkWidget *widget) |
| 1333 { |
1387 { |
| 1334 PidginWindow *win = data; |
1388 PidginWindow *win = data; |
| 2341 } |
2395 } |
| 2342 |
2396 |
| 2343 return get_prpl_icon_list(account); |
2397 return get_prpl_icon_list(account); |
| 2344 } |
2398 } |
| 2345 |
2399 |
| 2346 GdkPixbuf * |
2400 static GdkPixbuf * |
| 2347 pidgin_conv_get_tab_icon(PurpleConversation *conv, gboolean small_icon) |
2401 pidgin_conv_get_icon(PurpleConversation *conv, GtkWidget *parent, const char *icon_size) |
| 2348 { |
2402 { |
| 2349 PurpleAccount *account = NULL; |
2403 PurpleAccount *account = NULL; |
| 2350 const char *name = NULL; |
2404 const char *name = NULL; |
| 2351 GdkPixbuf *status = NULL; |
2405 GdkPixbuf *status = NULL; |
| 2352 PurpleBlistUiOps *ops = purple_blist_get_ui_ops(); |
2406 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; |
2407 g_return_val_if_fail(conv != NULL, NULL); |
| 2354 g_return_val_if_fail(conv != NULL, NULL); |
2408 |
| 2355 |
2409 account = purple_conversation_get_account(conv); |
| 2356 account = purple_conversation_get_account(conv); |
2410 name = purple_conversation_get_name(conv); |
| 2357 name = purple_conversation_get_name(conv); |
2411 |
| 2358 |
2412 g_return_val_if_fail(account != NULL, NULL); |
| 2359 g_return_val_if_fail(account != NULL, NULL); |
2413 g_return_val_if_fail(name != NULL, NULL); |
| 2360 g_return_val_if_fail(name != NULL, NULL); |
2414 |
| 2361 |
2415 /* Use the buddy icon, if possible */ |
| 2362 /* Use the buddy icon, if possible */ |
2416 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 2363 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
2417 PurpleBuddy *b = purple_find_buddy(account, name); |
| 2364 PurpleBuddy *b = purple_find_buddy(account, name); |
2418 if (b != NULL) { |
| 2365 if (b != NULL) { |
|
| 2366 PurplePresence *p = purple_buddy_get_presence(b); |
2419 PurplePresence *p = purple_buddy_get_presence(b); |
| 2367 /* I hate this hack. It fixes a bug where the pending message icon |
2420 /* I hate this hack. It fixes a bug where the pending message icon |
| 2368 * displays in the conv tab even though it shouldn't. |
2421 * displays in the conv tab even though it shouldn't. |
| 2369 * A better solution would be great. */ |
2422 * A better solution would be great. */ |
| 2370 if (ops && ops->update) |
2423 if (ops && ops->update) |
| 2371 ops->update(NULL, (PurpleBlistNode*)b); |
2424 ops->update(NULL, (PurpleBlistNode*)b); |
| 2372 |
2425 |
| 2373 /* XXX Seanegan: We really need a util function to return a pixbuf for a Presence to avoid all this switching */ |
2426 /* 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)) |
2427 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); |
2428 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)) |
2429 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); |
2430 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)) |
2431 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); |
2432 status = pidgin_create_status_icon(PURPLE_STATUS_OFFLINE, parent, icon_size); |
| 2380 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_AVAILABLE)) |
2433 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); |
2434 status = pidgin_create_status_icon(PURPLE_STATUS_AVAILABLE, parent, icon_size); |
| 2382 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_INVISIBLE)) |
2435 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); |
2436 status = pidgin_create_status_icon(PURPLE_STATUS_INVISIBLE, parent, icon_size); |
| 2384 else if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_UNAVAILABLE)) |
2437 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); |
2438 status = pidgin_create_status_icon(PURPLE_STATUS_UNAVAILABLE, parent, icon_size); |
| 2386 } |
2439 } |
| 2387 } |
2440 } |
| 2388 |
2441 |
| 2389 /* If they don't have a buddy icon, then use the PRPL icon */ |
2442 /* If they don't have a buddy icon, then use the PRPL icon */ |
| 2390 if (status == NULL) { |
2443 if (status == NULL) { |
| 2391 GtkIconSize size = gtk_icon_size_from_name(icon_size); |
2444 GtkIconSize size = gtk_icon_size_from_name(icon_size); |
| 2392 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
2445 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) { |
| 2393 status = gtk_widget_render_icon (PIDGIN_CONVERSATION(conv)->icon, PIDGIN_STOCK_STATUS_PERSON, |
2446 status = gtk_widget_render_icon (parent, PIDGIN_STOCK_STATUS_PERSON, |
| 2394 size, "GtkWidget"); |
2447 size, "GtkWidget"); |
| 2395 } else { |
2448 } else { |
| 2396 status = gtk_widget_render_icon (PIDGIN_CONVERSATION(conv)->icon, PIDGIN_STOCK_STATUS_CHAT, |
2449 status = gtk_widget_render_icon (parent, PIDGIN_STOCK_STATUS_CHAT, |
| 2397 size, "GtkWidget"); |
2450 size, "GtkWidget"); |
| 2398 } |
2451 } |
| 2399 } |
2452 } |
| 2400 return status; |
2453 return status; |
| |
2454 } |
| |
2455 |
| |
2456 GdkPixbuf * |
| |
2457 pidgin_conv_get_tab_icon(PurpleConversation *conv, gboolean small_icon) |
| |
2458 { |
| |
2459 const char *icon_size = small_icon ? PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC : PIDGIN_ICON_SIZE_TANGO_EXTRA_SMALL; |
| |
2460 return pidgin_conv_get_icon(conv, PIDGIN_CONVERSATION(conv)->icon, icon_size); |
| 2401 } |
2461 } |
| 2402 |
2462 |
| 2403 |
2463 |
| 2404 static void |
2464 static void |
| 2405 update_tab_icon(PurpleConversation *conv) |
2465 update_tab_icon(PurpleConversation *conv) |
| 2837 for (l = convs; l != NULL ; l = l->next) { |
2902 for (l = convs; l != NULL ; l = l->next) { |
| 2838 PurpleConversation *conv = (PurpleConversation*)l->data; |
2903 PurpleConversation *conv = (PurpleConversation*)l->data; |
| 2839 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
2904 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
| 2840 |
2905 |
| 2841 GtkWidget *icon = gtk_image_new(); |
2906 GtkWidget *icon = gtk_image_new(); |
| 2842 GdkPixbuf *pbuf = pidgin_conv_get_tab_icon(conv, TRUE); |
2907 GdkPixbuf *pbuf = pidgin_conv_get_icon(conv, icon, PIDGIN_ICON_SIZE_TANGO_MICROSCOPIC); |
| 2843 GtkWidget *item; |
2908 GtkWidget *item; |
| 2844 gchar *text = g_strdup_printf("%s (%d)", |
2909 gchar *text = g_strdup_printf("%s (%d)", |
| 2845 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)), |
2910 gtkconv ? gtk_label_get_text(GTK_LABEL(gtkconv->tab_label)) : purple_conversation_get_name(conv), |
| 2846 gtkconv->unseen_count); |
2911 gtkconv ? gtkconv->unseen_count : GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count"))); |
| 2847 |
2912 |
| 2848 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf); |
2913 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pbuf); |
| 2849 g_object_unref(pbuf); |
2914 g_object_unref(pbuf); |
| 2850 |
2915 |
| 2851 item = gtk_image_menu_item_new_with_label(text); |
2916 item = gtk_image_menu_item_new_with_label(text); |
| 5054 |
5122 |
| 5055 g_signal_connect_swapped(G_OBJECT(pane), "focus", |
5123 g_signal_connect_swapped(G_OBJECT(pane), "focus", |
| 5056 G_CALLBACK(gtk_widget_grab_focus), |
5124 G_CALLBACK(gtk_widget_grab_focus), |
| 5057 gtkconv->entry); |
5125 gtkconv->entry); |
| 5058 |
5126 |
| 5059 if (hidden) |
5127 pidgin_conv_placement_place(gtkconv); |
| 5060 pidgin_conv_window_add_gtkconv(hidden_convwin, gtkconv); |
|
| 5061 else |
|
| 5062 pidgin_conv_placement_place(gtkconv); |
|
| 5063 |
5128 |
| 5064 if (nick_colors == NULL) { |
5129 if (nick_colors == NULL) { |
| 5065 nbr_nick_colors = NUM_NICK_COLORS; |
5130 nbr_nick_colors = NUM_NICK_COLORS; |
| 5066 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); |
5131 nick_colors = generate_nick_colors(&nbr_nick_colors, gtk_widget_get_style(gtkconv->imhtml)->base[GTK_STATE_NORMAL]); |
| 5067 } |
5132 } |
| 5068 } |
5133 } |
| 5069 |
5134 |
| |
5135 #if 0 |
| 5070 static void |
5136 static void |
| 5071 pidgin_conv_new_hidden(PurpleConversation *conv) |
5137 pidgin_conv_new_hidden(PurpleConversation *conv) |
| 5072 { |
5138 { |
| 5073 private_gtkconv_new(conv, TRUE); |
5139 private_gtkconv_new(conv, TRUE); |
| 5074 } |
5140 } |
| |
5141 #endif |
| 5075 |
5142 |
| 5076 void |
5143 void |
| 5077 pidgin_conv_new(PurpleConversation *conv) |
5144 pidgin_conv_new(PurpleConversation *conv) |
| 5078 { |
5145 { |
| 5079 private_gtkconv_new(conv, FALSE); |
5146 private_gtkconv_new(conv, FALSE); |
| 5085 static void |
5152 static void |
| 5086 received_im_msg_cb(PurpleAccount *account, char *sender, char *message, |
5153 received_im_msg_cb(PurpleAccount *account, char *sender, char *message, |
| 5087 PurpleConversation *conv, PurpleMessageFlags flags) |
5154 PurpleConversation *conv, PurpleMessageFlags flags) |
| 5088 { |
5155 { |
| 5089 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops(); |
5156 PurpleConversationUiOps *ui_ops = pidgin_conversations_get_conv_ui_ops(); |
| 5090 if (conv != NULL) |
5157 |
| |
5158 /* create hidden conv if hide_new pref is always */ |
| |
5159 /* or if hide_new pref is away and account is away */ |
| |
5160 if ((strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0) || |
| |
5161 (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 && |
| |
5162 !purple_status_is_available(purple_account_get_active_status(account)))) { |
| |
5163 if (!conv) { |
| |
5164 ui_ops->create_conversation = NULL; |
| |
5165 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); |
| |
5166 purple_conversation_set_ui_ops(conv, NULL); |
| |
5167 ui_ops->create_conversation = pidgin_conv_new; |
| |
5168 } else { |
| |
5169 /* TODO: update the unseen_state data on the conv here */ |
| |
5170 } |
| |
5171 } else { |
| |
5172 /* new message for an IM */ |
| |
5173 if (conv && conv->type == PURPLE_CONV_TYPE_IM) |
| |
5174 pidgin_conv_attach_to_conversation(conv); |
| |
5175 } |
| |
5176 } |
| |
5177 |
| |
5178 static void |
| |
5179 pidgin_conv_destroy(PurpleConversation *conv) |
| |
5180 { |
| |
5181 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
| |
5182 |
| |
5183 if (!gtkconv) |
| 5091 return; |
5184 return; |
| 5092 |
|
| 5093 /* create hidden conv if hide_new pref is always */ |
|
| 5094 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always") == 0) |
|
| 5095 { |
|
| 5096 ui_ops->create_conversation = pidgin_conv_new_hidden; |
|
| 5097 purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); |
|
| 5098 ui_ops->create_conversation = pidgin_conv_new; |
|
| 5099 return; |
|
| 5100 } |
|
| 5101 |
|
| 5102 /* create hidden conv if hide_new pref is away and account is away */ |
|
| 5103 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away") == 0 && |
|
| 5104 !purple_status_is_available(purple_account_get_active_status(account))) |
|
| 5105 { |
|
| 5106 ui_ops->create_conversation = pidgin_conv_new_hidden; |
|
| 5107 purple_conversation_new(PURPLE_CONV_TYPE_IM, account, sender); |
|
| 5108 ui_ops->create_conversation = pidgin_conv_new; |
|
| 5109 return; |
|
| 5110 } |
|
| 5111 } |
|
| 5112 |
|
| 5113 static void |
|
| 5114 pidgin_conv_destroy(PurpleConversation *conv) |
|
| 5115 { |
|
| 5116 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
|
| 5117 |
5185 |
| 5118 gtkconv->convs = g_list_remove(gtkconv->convs, conv); |
5186 gtkconv->convs = g_list_remove(gtkconv->convs, conv); |
| 5119 /* Don't destroy ourselves until all our convos are gone */ |
5187 /* Don't destroy ourselves until all our convos are gone */ |
| 5120 if (gtkconv->convs) { |
5188 if (gtkconv->convs) { |
| 5121 /* Make sure the destroyed conversation is not the active one */ |
5189 /* Make sure the destroyed conversation is not the active one */ |
| 6507 purple_conv_im_get_typing_state(im) == PURPLE_TYPED) { |
6575 purple_conv_im_get_typing_state(im) == PURPLE_TYPED) { |
| 6508 atk_object_set_description(accessibility_obj, _("Stopped Typing")); |
6576 atk_object_set_description(accessibility_obj, _("Stopped Typing")); |
| 6509 style = "color=\"#c4a000\""; |
6577 style = "color=\"#c4a000\""; |
| 6510 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) { |
6578 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_NICK) { |
| 6511 atk_object_set_description(accessibility_obj, _("Nick Said")); |
6579 atk_object_set_description(accessibility_obj, _("Nick Said")); |
| 6512 style = "color=\"#204a87\""; |
6580 style = "color=\"#cc0000\""; |
| 6513 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) { |
6581 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT) { |
| 6514 atk_object_set_description(accessibility_obj, _("Unread Messages")); |
6582 atk_object_set_description(accessibility_obj, _("Unread Messages")); |
| 6515 style = "color=\"#cc0000\""; |
6583 if (gtkconv->active_conv->type == PURPLE_CONV_TYPE_CHAT) |
| |
6584 style = "color=\"#204a87\""; |
| |
6585 else |
| |
6586 style = "color=\"#cc0000\""; |
| 6516 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) { |
6587 } else if (gtkconv->unseen_state == PIDGIN_UNSEEN_EVENT) { |
| 6517 atk_object_set_description(accessibility_obj, _("New Event")); |
6588 atk_object_set_description(accessibility_obj, _("New Event")); |
| 6518 style = "color=\"#888a85\""; |
6589 style = "color=\"#888a85\""; |
| 6519 } else { |
6590 } else { |
| 6520 style = NULL; |
6591 style = NULL; |
| 6596 { |
6667 { |
| 6597 flags = PIDGIN_CONV_MENU; |
6668 flags = PIDGIN_CONV_MENU; |
| 6598 } |
6669 } |
| 6599 |
6670 |
| 6600 pidgin_conv_update_fields(conv, flags); |
6671 pidgin_conv_update_fields(conv, flags); |
| |
6672 } |
| |
6673 |
| |
6674 static void |
| |
6675 wrote_msg_update_unseen_cb(PurpleAccount *account, const char *who, const char *message, |
| |
6676 PurpleConversation *conv, PurpleMessageFlags flags, gpointer null) |
| |
6677 { |
| |
6678 if (conv == NULL || PIDGIN_IS_PIDGIN_CONVERSATION(conv)) |
| |
6679 return; |
| |
6680 if (flags & (PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_RECV)) { |
| |
6681 PidginUnseenState unseen = PIDGIN_UNSEEN_NONE; |
| |
6682 |
| |
6683 if ((flags & PURPLE_MESSAGE_NICK) == PURPLE_MESSAGE_NICK) |
| |
6684 unseen = PIDGIN_UNSEEN_NICK; |
| |
6685 else if (((flags & PURPLE_MESSAGE_SYSTEM) == PURPLE_MESSAGE_SYSTEM) || |
| |
6686 ((flags & PURPLE_MESSAGE_ERROR) == PURPLE_MESSAGE_ERROR)) |
| |
6687 unseen = PIDGIN_UNSEEN_EVENT; |
| |
6688 else if ((flags & PURPLE_MESSAGE_NO_LOG) == PURPLE_MESSAGE_NO_LOG) |
| |
6689 unseen = PIDGIN_UNSEEN_NO_LOG; |
| |
6690 else |
| |
6691 unseen = PIDGIN_UNSEEN_TEXT; |
| |
6692 |
| |
6693 conv_set_unseen(conv, unseen); |
| |
6694 purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN); |
| |
6695 } |
| 6601 } |
6696 } |
| 6602 |
6697 |
| 6603 static PurpleConversationUiOps conversation_ui_ops = |
6698 static PurpleConversationUiOps conversation_ui_ops = |
| 6604 { |
6699 { |
| 6605 pidgin_conv_new, |
6700 pidgin_conv_new, |
| 7097 |
7192 |
| 7098 static void |
7193 static void |
| 7099 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus, |
7194 account_status_changed_cb(PurpleAccount *account, PurpleStatus *oldstatus, |
| 7100 PurpleStatus *newstatus) |
7195 PurpleStatus *newstatus) |
| 7101 { |
7196 { |
| |
7197 #if 0 |
| 7102 GList *l; |
7198 GList *l; |
| 7103 PurpleConversation *conv = NULL; |
7199 PurpleConversation *conv = NULL; |
| 7104 PidginConversation *gtkconv; |
7200 PidginConversation *gtkconv; |
| 7105 |
7201 |
| 7106 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0) |
7202 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")!=0) |
| 7107 return; |
7203 return; |
| 7108 |
7204 |
| 7109 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus)) |
7205 if(purple_status_is_available(oldstatus) || !purple_status_is_available(newstatus)) |
| 7110 return; |
7206 return; |
| 7111 |
7207 #endif |
| 7112 while ((l = hidden_convwin->gtkconvs) != NULL) |
|
| 7113 { |
|
| 7114 gtkconv = l->data; |
|
| 7115 |
|
| 7116 conv = gtkconv->active_conv; |
|
| 7117 |
|
| 7118 while(l && !purple_status_is_available( |
|
| 7119 purple_account_get_active_status( |
|
| 7120 purple_conversation_get_account(conv)))) |
|
| 7121 l = l->next; |
|
| 7122 if (!l) |
|
| 7123 break; |
|
| 7124 |
|
| 7125 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv); |
|
| 7126 pidgin_conv_placement_place(gtkconv); |
|
| 7127 |
|
| 7128 /* TODO: do we need to do anything for any other conversations that are in the same gtkconv here? |
|
| 7129 * I'm a little concerned that not doing so will cause the "pending" indicator in the gtkblist not to be cleared. -DAA*/ |
|
| 7130 purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN); |
|
| 7131 } |
|
| 7132 } |
7208 } |
| 7133 |
7209 |
| 7134 static void |
7210 static void |
| 7135 hide_new_pref_cb(const char *name, PurplePrefType type, |
7211 hide_new_pref_cb(const char *name, PurplePrefType type, |
| 7136 gconstpointer value, gpointer data) |
7212 gconstpointer value, gpointer data) |
| 7137 { |
7213 { |
| 7138 GList *l; |
7214 GList *l; |
| 7139 PurpleConversation *conv = NULL; |
|
| 7140 PidginConversation *gtkconv; |
|
| 7141 gboolean when_away = FALSE; |
7215 gboolean when_away = FALSE; |
| 7142 |
|
| 7143 if(!hidden_convwin) |
|
| 7144 return; |
|
| 7145 |
7216 |
| 7146 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0) |
7217 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "always")==0) |
| 7147 return; |
7218 return; |
| 7148 |
7219 |
| 7149 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0) |
7220 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/im/hide_new"), "away")==0) |
| 7150 when_away = TRUE; |
7221 when_away = TRUE; |
| 7151 |
7222 |
| 7152 while ((l = hidden_convwin->gtkconvs) != NULL) |
7223 for (l = purple_get_conversations(); l; l = l->next) |
| 7153 { |
7224 { |
| 7154 gtkconv = l->data; |
7225 PurpleConversation *conv = l->data; |
| 7155 |
7226 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); |
| 7156 conv = gtkconv->active_conv; |
7227 if (gtkconv) |
| 7157 |
7228 continue; |
| 7158 if(when_away && !purple_status_is_available( |
7229 if(when_away && !purple_status_is_available( |
| 7159 purple_account_get_active_status( |
7230 purple_account_get_active_status( |
| 7160 purple_conversation_get_account(conv)))) |
7231 purple_conversation_get_account(conv)))) |
| 7161 continue; |
7232 continue; |
| 7162 |
7233 pidgin_conv_attach_to_conversation(conv); |
| 7163 pidgin_conv_window_remove_gtkconv(hidden_convwin, gtkconv); |
|
| 7164 pidgin_conv_placement_place(gtkconv); |
|
| 7165 } |
7234 } |
| 7166 } |
7235 } |
| 7167 |
7236 |
| 7168 |
7237 |
| 7169 static void |
7238 static void |
| 7215 * one of the contacts containing the buddy corresponding to |
7284 * one of the contacts containing the buddy corresponding to |
| 7216 * a conversation. It's easier to just update them all. */ |
7285 * a conversation. It's easier to just update them all. */ |
| 7217 /* if (purple_conversation_get_account(conv) == account) */ |
7286 /* if (purple_conversation_get_account(conv) == account) */ |
| 7218 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | |
7287 pidgin_conv_update_fields(conv, PIDGIN_CONV_TAB_ICON | |
| 7219 PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE); |
7288 PIDGIN_CONV_MENU | PIDGIN_CONV_COLORIZE_TITLE); |
| |
7289 |
| |
7290 if (PURPLE_CONNECTION_IS_CONNECTED(gc) && |
| |
7291 conv->type == PURPLE_CONV_TYPE_CHAT && |
| |
7292 conv->account == gc->account && |
| |
7293 purple_conversation_get_data(conv, "want-to-rejoin")) { |
| |
7294 GHashTable *comps = NULL; |
| |
7295 PurpleChat *chat = purple_blist_find_chat(conv->account, conv->name); |
| |
7296 if (chat == NULL) { |
| |
7297 if (PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults != NULL) |
| |
7298 comps = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl)->chat_info_defaults(gc, conv->name); |
| |
7299 } else { |
| |
7300 comps = chat->components; |
| |
7301 } |
| |
7302 serv_join_chat(gc, comps); |
| |
7303 if (chat == NULL && comps != NULL) |
| |
7304 g_hash_table_destroy(comps); |
| |
7305 } |
| 7220 } |
7306 } |
| 7221 } |
7307 } |
| 7222 |
7308 |
| 7223 static gboolean |
7309 static gboolean |
| 7224 update_buddy_status_timeout(PurpleBuddy *buddy) |
7310 update_buddy_status_timeout(PurpleBuddy *buddy) |
| 7342 add_message_history_to_gtkconv(gpointer data) |
7428 add_message_history_to_gtkconv(gpointer data) |
| 7343 { |
7429 { |
| 7344 PidginConversation *gtkconv = data; |
7430 PidginConversation *gtkconv = data; |
| 7345 int count = 0; |
7431 int count = 0; |
| 7346 int timer = gtkconv->attach.timer; |
7432 int timer = gtkconv->attach.timer; |
| |
7433 time_t when = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->entry), "attach-start-time")); |
| |
7434 |
| 7347 gtkconv->attach.timer = 0; |
7435 gtkconv->attach.timer = 0; |
| 7348 while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ |
7436 while (gtkconv->attach.current && count < 100) { /* XXX: 100 is a random value here */ |
| 7349 PurpleConvMessage *msg = gtkconv->attach.current->data; |
7437 PurpleConvMessage *msg = gtkconv->attach.current->data; |
| |
7438 if (when && when < msg->when) { |
| |
7439 gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "<BR><HR>", 0); |
| |
7440 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
| |
7441 } |
| 7350 pidgin_conv_write_conv(gtkconv->active_conv, msg->who, msg->who, msg->what, msg->flags, msg->when); |
7442 pidgin_conv_write_conv(gtkconv->active_conv, msg->who, msg->who, msg->what, msg->flags, msg->when); |
| 7351 gtkconv->attach.current = gtkconv->attach.current->prev; |
7443 gtkconv->attach.current = gtkconv->attach.current->prev; |
| 7352 count++; |
7444 count++; |
| 7353 } |
7445 } |
| 7354 gtkconv->attach.timer = timer; |
7446 gtkconv->attach.timer = timer; |
| 7355 if (gtkconv->attach.current) |
7447 if (gtkconv->attach.current) |
| 7356 return TRUE; |
7448 return TRUE; |
| 7357 |
7449 |
| |
7450 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", NULL); |
| 7358 purple_signal_emit(pidgin_conversations_get_handle(), |
7451 purple_signal_emit(pidgin_conversations_get_handle(), |
| 7359 "conversation-displayed", gtkconv); |
7452 "conversation-displayed", gtkconv); |
| 7360 g_source_remove(gtkconv->attach.timer); |
7453 g_source_remove(gtkconv->attach.timer); |
| 7361 gtkconv->attach.timer = 0; |
7454 gtkconv->attach.timer = 0; |
| 7362 return FALSE; |
7455 return FALSE; |
| 7364 |
7457 |
| 7365 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv) |
7458 gboolean pidgin_conv_attach_to_conversation(PurpleConversation *conv) |
| 7366 { |
7459 { |
| 7367 GList *list; |
7460 GList *list; |
| 7368 PidginConversation *gtkconv; |
7461 PidginConversation *gtkconv; |
| |
7462 int timer; |
| 7369 |
7463 |
| 7370 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) |
7464 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) |
| 7371 return FALSE; |
7465 return FALSE; |
| 7372 |
7466 |
| |
7467 purple_conversation_set_data(conv, "unseen-count", NULL); |
| |
7468 purple_conversation_set_data(conv, "unseen-state", NULL); |
| 7373 purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops()); |
7469 purple_conversation_set_ui_ops(conv, pidgin_conversations_get_conv_ui_ops()); |
| 7374 private_gtkconv_new(conv, FALSE); |
7470 private_gtkconv_new(conv, FALSE); |
| 7375 gtkconv = PIDGIN_CONVERSATION(conv); |
7471 gtkconv = PIDGIN_CONVERSATION(conv); |
| 7376 |
7472 |
| 7377 list = purple_conversation_get_message_history(conv); |
7473 list = purple_conversation_get_message_history(conv); |
| 7378 if (list) { |
7474 if (list) { |
| 7379 list = g_list_last(list); |
7475 g_object_set_data(G_OBJECT(gtkconv->entry), "attach-start-time", |
| 7380 gtkconv->attach.current = list; |
7476 GINT_TO_POINTER(((PurpleConvMessage*)(list->data))->when)); |
| |
7477 gtkconv->attach.current = g_list_last(list); |
| 7381 gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv); |
7478 gtkconv->attach.timer = g_idle_add(add_message_history_to_gtkconv, gtkconv); |
| 7382 } else { |
7479 } else { |
| 7383 purple_signal_emit(pidgin_conversations_get_handle(), |
7480 purple_signal_emit(pidgin_conversations_get_handle(), |
| 7384 "conversation-displayed", gtkconv); |
7481 "conversation-displayed", gtkconv); |
| 7385 } |
7482 } |
| 7653 purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", handle, |
7751 purple_signal_connect(purple_conversations_get_handle(), "chat-topic-changed", handle, |
| 7654 PURPLE_CALLBACK(update_chat_topic), NULL); |
7752 PURPLE_CALLBACK(update_chat_topic), NULL); |
| 7655 purple_signal_connect_priority(purple_conversations_get_handle(), "conversation-updated", handle, |
7753 purple_signal_connect_priority(purple_conversations_get_handle(), "conversation-updated", handle, |
| 7656 PURPLE_CALLBACK(pidgin_conv_updated), NULL, |
7754 PURPLE_CALLBACK(pidgin_conv_updated), NULL, |
| 7657 PURPLE_SIGNAL_PRIORITY_LOWEST); |
7755 PURPLE_SIGNAL_PRIORITY_LOWEST); |
| |
7756 purple_signal_connect(purple_conversations_get_handle(), "wrote-im-msg", handle, |
| |
7757 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
| |
7758 purple_signal_connect(purple_conversations_get_handle(), "wrote-chat-msg", handle, |
| |
7759 PURPLE_CALLBACK(wrote_msg_update_unseen_cb), NULL); |
| 7658 } |
7760 } |
| 7659 |
7761 |
| 7660 void |
7762 void |
| 7661 pidgin_conversations_uninit(void) |
7763 pidgin_conversations_uninit(void) |
| 7662 { |
7764 { |
| 7663 purple_prefs_disconnect_by_handle(pidgin_conversations_get_handle()); |
7765 purple_prefs_disconnect_by_handle(pidgin_conversations_get_handle()); |
| 7664 purple_signals_disconnect_by_handle(pidgin_conversations_get_handle()); |
7766 purple_signals_disconnect_by_handle(pidgin_conversations_get_handle()); |
| 7665 purple_signals_unregister_by_instance(pidgin_conversations_get_handle()); |
7767 purple_signals_unregister_by_instance(pidgin_conversations_get_handle()); |
| 7666 pidgin_conv_window_destroy(hidden_convwin); |
|
| 7667 hidden_convwin=NULL; |
|
| 7668 } |
7768 } |
| 7669 |
7769 |
| 7670 |
7770 |
| 7671 |
7771 |
| 7672 |
7772 |
| 7833 |
7933 |
| 7834 return TRUE; |
7934 return TRUE; |
| 7835 } |
7935 } |
| 7836 |
7936 |
| 7837 static void |
7937 static void |
| |
7938 conv_set_unseen(PurpleConversation *conv, PidginUnseenState state) |
| |
7939 { |
| |
7940 int unseen_count = 0; |
| |
7941 PidginUnseenState unseen_state = PIDGIN_UNSEEN_NONE; |
| |
7942 |
| |
7943 if(purple_conversation_get_data(conv, "unseen-count")) |
| |
7944 unseen_count = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-count")); |
| |
7945 |
| |
7946 if(purple_conversation_get_data(conv, "unseen-state")) |
| |
7947 unseen_state = GPOINTER_TO_INT(purple_conversation_get_data(conv, "unseen-state")); |
| |
7948 |
| |
7949 if (state == PIDGIN_UNSEEN_NONE) |
| |
7950 { |
| |
7951 unseen_count = 0; |
| |
7952 unseen_state = PIDGIN_UNSEEN_NONE; |
| |
7953 } |
| |
7954 else |
| |
7955 { |
| |
7956 if (state >= PIDGIN_UNSEEN_TEXT) |
| |
7957 unseen_count++; |
| |
7958 |
| |
7959 if (state > unseen_state) |
| |
7960 unseen_state = state; |
| |
7961 } |
| |
7962 |
| |
7963 purple_conversation_set_data(conv, "unseen-count", GINT_TO_POINTER(unseen_count)); |
| |
7964 purple_conversation_set_data(conv, "unseen-state", GINT_TO_POINTER(unseen_state)); |
| |
7965 |
| |
7966 purple_conversation_update(conv, PURPLE_CONV_UPDATE_UNSEEN); |
| |
7967 } |
| |
7968 |
| |
7969 static void |
| 7838 gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state) |
7970 gtkconv_set_unseen(PidginConversation *gtkconv, PidginUnseenState state) |
| 7839 { |
7971 { |
| 7840 if (state == PIDGIN_UNSEEN_NONE) |
7972 if (state == PIDGIN_UNSEEN_NONE) |
| 7841 { |
7973 { |
| 7842 gtkconv->unseen_count = 0; |
7974 gtkconv->unseen_count = 0; |