pidgin/gtkconv.c

changeset 18868
bad2f3f3d15a
parent 18300
666a39f800eb
parent 18867
ccdc920ec008
child 18873
c978846c9c2c
equal deleted inserted replaced
18300:666a39f800eb 18868:bad2f3f3d15a
81 PIDGIN_CONV_SMILEY_THEME = 1 << 5, 81 PIDGIN_CONV_SMILEY_THEME = 1 << 5,
82 PIDGIN_CONV_COLORIZE_TITLE = 1 << 6 82 PIDGIN_CONV_COLORIZE_TITLE = 1 << 6
83 }PidginConvFields; 83 }PidginConvFields;
84 84
85 enum { 85 enum {
86 ICON_COLUMN, 86 CONV_ICON_COLUMN,
87 TEXT_COLUMN, 87 CONV_TEXT_COLUMN,
88 NUM_COLUMNS 88 CONV_EMBLEM_COLUMN,
89 CONV_NUM_COLUMNS
89 } PidginInfopaneColumns; 90 } PidginInfopaneColumns;
90 91
91 #define PIDGIN_CONV_ALL ((1 << 7) - 1) 92 #define PIDGIN_CONV_ALL ((1 << 7) - 1)
92 93
93 #define SEND_COLOR "#204a87" 94 #define SEND_COLOR "#204a87"
182 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background); 183 static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background);
183 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); 184 static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast);
184 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); 185 static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields);
185 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); 186 static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win);
186 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); 187 static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv);
187 static gboolean infopane_release_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv);
188 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv); 188 static gboolean infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *conv);
189 189
190 static GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) { 190 static GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) {
191 static GdkColor col; 191 static GdkColor col;
192 GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml); 192 GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml);
254 * size of the last resized new window. */ 254 * size of the last resized new window. */
255 /* I think that the above justification is not the majority, and that the new tab resizing should 255 /* I think that the above justification is not the majority, and that the new tab resizing should
256 * negate it anyway. --luke */ 256 * negate it anyway. --luke */
257 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 257 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
258 { 258 {
259 if (w == gtkconv->imhtml) {
260 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width", allocation->width);
261 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height", allocation->height);
262 }
263 if (w == gtkconv->lower_hbox) 259 if (w == gtkconv->lower_hbox)
264 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height", allocation->height); 260 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height", allocation->height);
265 } 261 }
266 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) 262 else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
267 { 263 {
268 if (w == gtkconv->imhtml) {
269 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width", allocation->width);
270 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height", allocation->height);
271 }
272 if (w == gtkconv->lower_hbox) 264 if (w == gtkconv->lower_hbox)
273 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height", allocation->height); 265 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height", allocation->height);
274 } 266 }
275 267
276 return FALSE; 268 return FALSE;
345 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL)); 337 PURPLE_MESSAGE_NO_LOG|PURPLE_MESSAGE_ERROR, time(NULL));
346 return PURPLE_CMD_STATUS_OK; 338 return PURPLE_CMD_STATUS_OK;
347 } 339 }
348 } 340 }
349 341
342 static void clear_conversation_scrollback(PurpleConversation *conv)
343 {
344 PidginConversation *gtkconv = NULL;
345
346 gtkconv = PIDGIN_CONVERSATION(conv);
347
348 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml));
349 }
350
350 static PurpleCmdRet 351 static PurpleCmdRet
351 clear_command_cb(PurpleConversation *conv, 352 clear_command_cb(PurpleConversation *conv,
352 const char *cmd, char **args, char **error, void *data) 353 const char *cmd, char **args, char **error, void *data)
353 { 354 {
354 PidginConversation *gtkconv = NULL; 355 clear_conversation_scrollback(conv);
355 356 return PURPLE_CMD_STATUS_OK;
356 gtkconv = PIDGIN_CONVERSATION(conv); 357 }
357 358
358 gtk_imhtml_clear(GTK_IMHTML(gtkconv->imhtml)); 359 static PurpleCmdRet
360 clearall_command_cb(PurpleConversation *conv,
361 const char *cmd, char **args, char **error, void *data)
362 {
363 purple_conversation_foreach(clear_conversation_scrollback);
359 return PURPLE_CMD_STATUS_OK; 364 return PURPLE_CMD_STATUS_OK;
360 } 365 }
361 366
362 static PurpleCmdRet 367 static PurpleCmdRet
363 help_command_cb(PurpleConversation *conv, 368 help_command_cb(PurpleConversation *conv,
526 PurpleMessageFlags flags = 0; 531 PurpleMessageFlags flags = 0;
527 char *buf, *clean; 532 char *buf, *clean;
528 533
529 account = purple_conversation_get_account(conv); 534 account = purple_conversation_get_account(conv);
530 535
531 if (!purple_account_is_connected(account))
532 return;
533
534 if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) &&
535 purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)))
536 return;
537
538 if (check_for_and_do_command(conv)) { 536 if (check_for_and_do_command(conv)) {
539 if (gtkconv->entry_growing) { 537 if (gtkconv->entry_growing) {
540 reset_default_size(gtkconv); 538 reset_default_size(gtkconv);
541 gtkconv->entry_growing = FALSE; 539 gtkconv->entry_growing = FALSE;
542 } 540 }
543 gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry)); 541 gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry));
544 return; 542 return;
545 } 543 }
544
545 if ((purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) &&
546 purple_conv_chat_has_left(PURPLE_CONV_CHAT(conv)))
547 return;
548
549 if (!purple_account_is_connected(account))
550 return;
546 551
547 buf = gtk_imhtml_get_markup(GTK_IMHTML(gtkconv->entry)); 552 buf = gtk_imhtml_get_markup(GTK_IMHTML(gtkconv->entry));
548 clean = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL); 553 clean = gtk_imhtml_get_text(GTK_IMHTML(gtkconv->entry), NULL, NULL);
549 554
550 gtk_widget_grab_focus(gtkconv->entry); 555 gtk_widget_grab_focus(gtkconv->entry);
1734 if (path == NULL) 1739 if (path == NULL)
1735 return FALSE; 1740 return FALSE;
1736 1741
1737 gtk_tree_selection_select_path(GTK_TREE_SELECTION( 1742 gtk_tree_selection_select_path(GTK_TREE_SELECTION(
1738 gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list))), path); 1743 gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list))), path);
1744 gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtkchat->list),
1745 path, NULL, FALSE);
1746 gtk_widget_grab_focus(GTK_WIDGET(gtkchat->list));
1739 1747
1740 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path); 1748 gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
1741 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1); 1749 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
1742 1750
1743 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { 1751 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
2326 static void 2334 static void
2327 update_tab_icon(PurpleConversation *conv) 2335 update_tab_icon(PurpleConversation *conv)
2328 { 2336 {
2329 PidginConversation *gtkconv; 2337 PidginConversation *gtkconv;
2330 PidginWindow *win; 2338 PidginWindow *win;
2339 PurpleBuddy *b;
2331 GList *l; 2340 GList *l;
2332 GdkPixbuf *status = NULL; 2341 GdkPixbuf *status = NULL;
2342 GdkPixbuf *emblem = NULL;
2333 2343
2334 g_return_if_fail(conv != NULL); 2344 g_return_if_fail(conv != NULL);
2335 2345
2336 gtkconv = PIDGIN_CONVERSATION(conv); 2346 gtkconv = PIDGIN_CONVERSATION(conv);
2337 win = gtkconv->win; 2347 win = gtkconv->win;
2338 if (conv != gtkconv->active_conv) 2348 if (conv != gtkconv->active_conv)
2339 return; 2349 return;
2340 2350
2351
2341 status = pidgin_conv_get_tab_icon(conv, TRUE); 2352 status = pidgin_conv_get_tab_icon(conv, TRUE);
2353 b = purple_find_buddy(conv->account, conv->name);
2354 if (b)
2355 emblem = pidgin_blist_get_emblem((PurpleBlistNode*)b);
2342 2356
2343 g_return_if_fail(status != NULL); 2357 g_return_if_fail(status != NULL);
2344 2358
2345 gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->icon), status); 2359 gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->icon), status);
2346 gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->menu_icon), status); 2360 gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->menu_icon), status);
2347 2361
2348 gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model), 2362 gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model),
2349 &(gtkconv->infopane_iter), 2363 &(gtkconv->infopane_iter),
2350 ICON_COLUMN, status, -1); 2364 CONV_ICON_COLUMN, status, -1);
2365
2366 gtk_list_store_set(GTK_LIST_STORE(gtkconv->infopane_model),
2367 &(gtkconv->infopane_iter),
2368 CONV_EMBLEM_COLUMN, emblem, -1);
2369
2351 2370
2352 if (status != NULL) 2371 if (status != NULL)
2353 g_object_unref(status); 2372 g_object_unref(status);
2354 2373
2355 if (pidgin_conv_window_is_active_conversation(conv) && 2374 if (pidgin_conv_window_is_active_conversation(conv) &&
2395 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl); 2414 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(account->gc->prpl);
2396 } else { 2415 } else {
2397 gtkconv->u.im->icon_timer = 0; 2416 gtkconv->u.im->icon_timer = 0;
2398 return FALSE; 2417 return FALSE;
2399 } 2418 }
2400
2401 gtkconv->auto_resize = TRUE;
2402 g_idle_add(reset_auto_resize_cb, gtkconv);
2403 2419
2404 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); 2420 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL);
2405 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); 2421 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter);
2406 2422
2407 scale_width = gdk_pixbuf_get_width(buf); 2423 scale_width = gdk_pixbuf_get_width(buf);
3669 pixbuf = get_chat_buddy_status_icon(chat, name, flags); 3685 pixbuf = get_chat_buddy_status_icon(chat, name, flags);
3670 3686
3671 if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name))) 3687 if (!strcmp(chat->nick, purple_normalize(conv->account, old_name != NULL ? old_name : name)))
3672 is_me = TRUE; 3688 is_me = TRUE;
3673 3689
3674 is_buddy = (purple_find_buddy(conv->account, name) != NULL); 3690 is_buddy = cb->buddy;
3675 3691
3676 tmp = g_utf8_casefold(alias, -1); 3692 tmp = g_utf8_casefold(alias, -1);
3677 alias_key = g_utf8_collate_key(tmp, -1); 3693 alias_key = g_utf8_collate_key(tmp, -1);
3678 g_free(tmp); 3694 g_free(tmp);
3679 3695
3877 gtk_tree_model_get(model, &iter, 3893 gtk_tree_model_get(model, &iter,
3878 CHAT_USERS_NAME_COLUMN, &name, 3894 CHAT_USERS_NAME_COLUMN, &name,
3879 CHAT_USERS_ALIAS_COLUMN, &alias, 3895 CHAT_USERS_ALIAS_COLUMN, &alias,
3880 -1); 3896 -1);
3881 3897
3882 if (strcmp(name, alias)) 3898 if (name && alias && strcmp(name, alias))
3883 tab_complete_process_item(&most_matched, entered, &partial, nick_partial, 3899 tab_complete_process_item(&most_matched, entered, &partial, nick_partial,
3884 &matches, FALSE, alias); 3900 &matches, FALSE, alias);
3885 g_free(name); 3901 g_free(name);
3886 g_free(alias); 3902 g_free(alias);
3887 3903
4246 4262
4247 gtk_widget_size_request(gtkconv->lower_hbox, &sr); 4263 gtk_widget_size_request(gtkconv->lower_hbox, &sr);
4248 if (sr.height < height + PIDGIN_HIG_BOX_SPACE) { 4264 if (sr.height < height + PIDGIN_HIG_BOX_SPACE) {
4249 gtkconv->auto_resize = TRUE; 4265 gtkconv->auto_resize = TRUE;
4250 gtkconv->entry_growing = TRUE; 4266 gtkconv->entry_growing = TRUE;
4251 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height + PIDGIN_HIG_BOX_SPACE); 4267 gtk_widget_set_size_request(gtkconv->entry, -1, height);
4252 g_idle_add(reset_auto_resize_cb, gtkconv); 4268 g_idle_add(reset_auto_resize_cb, gtkconv);
4253 } 4269 }
4254 } 4270 }
4255 4271
4256 static void 4272 static void
4403 gtk_widget_show(gtkconv->infopane_hbox); 4419 gtk_widget_show(gtkconv->infopane_hbox);
4404 gtk_widget_add_events(event_box, 4420 gtk_widget_add_events(event_box,
4405 GDK_BUTTON1_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK); 4421 GDK_BUTTON1_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK);
4406 g_signal_connect(G_OBJECT(event_box), "button_press_event", 4422 g_signal_connect(G_OBJECT(event_box), "button_press_event",
4407 G_CALLBACK(infopane_press_cb), gtkconv); 4423 G_CALLBACK(infopane_press_cb), gtkconv);
4408 g_signal_connect(G_OBJECT(event_box), "button_release_event",
4409 G_CALLBACK(infopane_release_cb), gtkconv);
4410 4424
4411 4425
4412 gtkconv->infopane = gtk_cell_view_new(); 4426 gtkconv->infopane = gtk_cell_view_new();
4413 gtkconv->infopane_model = gtk_list_store_new(NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING); 4427 gtkconv->infopane_model = gtk_list_store_new(CONV_NUM_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING, GDK_TYPE_PIXBUF);
4414 gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane), 4428 gtk_cell_view_set_model(GTK_CELL_VIEW(gtkconv->infopane),
4415 GTK_TREE_MODEL(gtkconv->infopane_model)); 4429 GTK_TREE_MODEL(gtkconv->infopane_model));
4416 gtk_list_store_append(gtkconv->infopane_model, &(gtkconv->infopane_iter)); 4430 gtk_list_store_append(gtkconv->infopane_model, &(gtkconv->infopane_iter));
4417 gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox), gtkconv->infopane, TRUE, TRUE, 0); 4431 gtk_box_pack_start(GTK_BOX(gtkconv->infopane_hbox), gtkconv->infopane, TRUE, TRUE, 0);
4418 path = gtk_tree_path_new_from_string("0"); 4432 path = gtk_tree_path_new_from_string("0");
4421 gtk_widget_set_size_request(gtkconv->infopane, -1, 32); 4435 gtk_widget_set_size_request(gtkconv->infopane, -1, 32);
4422 gtk_widget_show(gtkconv->infopane); 4436 gtk_widget_show(gtkconv->infopane);
4423 4437
4424 rend = gtk_cell_renderer_pixbuf_new(); 4438 rend = gtk_cell_renderer_pixbuf_new();
4425 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE); 4439 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE);
4426 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", ICON_COLUMN, NULL); 4440 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_ICON_COLUMN, NULL);
4427 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL); 4441 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL);
4428 4442
4429 rend = gtk_cell_renderer_text_new(); 4443 rend = gtk_cell_renderer_text_new();
4430 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, TRUE); 4444 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, TRUE);
4431 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "markup", TEXT_COLUMN, NULL); 4445 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "markup", CONV_TEXT_COLUMN, NULL);
4432 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL); 4446 g_object_set(rend, "ypad", 0, "yalign", 0.5, NULL);
4433 4447
4434 #if GTK_CHECK_VERSION(2, 6, 0) 4448 #if GTK_CHECK_VERSION(2, 6, 0)
4435 g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL); 4449 g_object_set(rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
4436 #endif 4450 #endif
4451
4452 rend = gtk_cell_renderer_pixbuf_new();
4453 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(gtkconv->infopane), rend, FALSE);
4454 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(gtkconv->infopane), rend, "pixbuf", CONV_EMBLEM_COLUMN, NULL);
4455 g_object_set(rend, "xalign", 0.0, "xpad", 6, "ypad", 0, NULL);
4437 4456
4438 /* Setup the gtkimhtml widget */ 4457 /* Setup the gtkimhtml widget */
4439 frame = pidgin_create_imhtml(FALSE, &gtkconv->imhtml, NULL, &imhtml_sw); 4458 frame = pidgin_create_imhtml(FALSE, &gtkconv->imhtml, NULL, &imhtml_sw);
4440 if (chat) { 4459 if (chat) {
4441 GtkWidget *hpaned; 4460 GtkWidget *hpaned;
4461 4480
4462 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), 4481 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
4463 &imhtml_sw_hscroll, NULL); 4482 &imhtml_sw_hscroll, NULL);
4464 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), 4483 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
4465 imhtml_sw_hscroll, GTK_POLICY_ALWAYS); 4484 imhtml_sw_hscroll, GTK_POLICY_ALWAYS);
4466
4467 gtk_widget_set_size_request(gtkconv->imhtml,
4468 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width") :
4469 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"),
4470 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height") :
4471 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height"));
4472
4473 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
4474 G_CALLBACK(size_allocate_cb), gtkconv);
4475 4485
4476 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", 4486 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
4477 G_CALLBACK(entry_stop_rclick_cb), NULL); 4487 G_CALLBACK(entry_stop_rclick_cb), NULL);
4478 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", 4488 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
4479 G_CALLBACK(refocus_entry_cb), gtkconv); 4489 G_CALLBACK(refocus_entry_cb), gtkconv);
4792 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")) 4802 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar"))
4793 gtk_widget_show(gtkconv->toolbar); 4803 gtk_widget_show(gtkconv->toolbar);
4794 else 4804 else
4795 gtk_widget_hide(gtkconv->toolbar); 4805 gtk_widget_hide(gtkconv->toolbar);
4796 4806
4807 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons"))
4808 gtk_widget_show(gtkconv->infopane_hbox);
4809 else
4810 gtk_widget_hide(gtkconv->infopane_hbox);
4811
4797 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), 4812 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),
4798 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps")); 4813 purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_timestamps"));
4799 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml), 4814 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->imhtml),
4800 purple_account_get_protocol_name(conv->account)); 4815 purple_account_get_protocol_name(conv->account));
4801 4816
4859 { 4874 {
4860 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); 4875 PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
4861 4876
4862 gtkconv->convs = g_list_remove(gtkconv->convs, conv); 4877 gtkconv->convs = g_list_remove(gtkconv->convs, conv);
4863 /* Don't destroy ourselves until all our convos are gone */ 4878 /* Don't destroy ourselves until all our convos are gone */
4864 if (gtkconv->convs) 4879 if (gtkconv->convs) {
4880 /* Make sure the destroyed conversation is not the active one */
4881 if (gtkconv->active_conv == conv) {
4882 gtkconv->active_conv = gtkconv->convs->data;
4883 purple_conversation_update(gtkconv->active_conv, PURPLE_CONV_UPDATE_FEATURES);
4884 }
4865 return; 4885 return;
4886 }
4866 4887
4867 pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv); 4888 pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv);
4868 4889
4869 /* If the "Save Conversation" or "Save Icon" dialogs are open then close them */ 4890 /* If the "Save Conversation" or "Save Icon" dialogs are open then close them */
4870 purple_request_close_with_handle(gtkconv); 4891 purple_request_close_with_handle(gtkconv);
5561 if (!purple_conv_chat_find_user(chat, old_name)) 5582 if (!purple_conv_chat_find_user(chat, old_name))
5562 return; 5583 return;
5563 5584
5564 g_return_if_fail(new_alias != NULL); 5585 g_return_if_fail(new_alias != NULL);
5565 5586
5566 cbuddy = purple_conv_chat_cb_new(new_name, new_alias, flags); 5587 cbuddy = purple_conv_chat_cb_find(chat, new_name);
5567 5588
5568 add_chat_buddy_common(conv, cbuddy, old_name); 5589 add_chat_buddy_common(conv, cbuddy, old_name);
5569 } 5590 }
5570 5591
5571 static void 5592 static void
6190 markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE); 6211 markup = pidgin_blist_get_name_markup(buddy, FALSE, FALSE);
6191 else 6212 else
6192 markup = title; 6213 markup = title;
6193 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { 6214 } else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) {
6194 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv); 6215 PurpleConvChat *chat = PURPLE_CONV_CHAT(conv);
6195 markup = g_strdup_printf("%s\n<span color='%s' size='smaller'>%s</span>", 6216 const char *topic = purple_conv_chat_get_topic(chat);
6217 markup = g_strdup_printf("%s%s<span color='%s' size='smaller'>%s</span>",
6196 purple_conversation_get_title(conv), 6218 purple_conversation_get_title(conv),
6219 topic ? "\n" : "",
6197 pidgin_get_dim_grey_string(gtkconv->infopane), 6220 pidgin_get_dim_grey_string(gtkconv->infopane),
6198 purple_conv_chat_get_topic(chat)); 6221 topic ? topic : "");
6199 } 6222 }
6200 gtk_list_store_set(gtkconv->infopane_model, &(gtkconv->infopane_iter), 6223 gtk_list_store_set(gtkconv->infopane_model, &(gtkconv->infopane_iter),
6201 TEXT_COLUMN, markup, -1); 6224 CONV_TEXT_COLUMN, markup, -1);
6202 6225
6203 if (title != markup) 6226 if (title != markup)
6204 g_free(markup); 6227 g_free(markup);
6205 6228
6206 *style = '\0'; 6229 *style = '\0';
6763 { 6786 {
6764 GList *l; 6787 GList *l;
6765 6788
6766 for (l = purple_get_conversations(); l != NULL; l = l->next) { 6789 for (l = purple_get_conversations(); l != NULL; l = l->next) {
6767 PurpleConversation *conv = l->data; 6790 PurpleConversation *conv = l->data;
6768 6791 if (GPOINTER_TO_INT(value))
6769 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) 6792 gtk_widget_show(PIDGIN_CONVERSATION(conv)->infopane_hbox);
6793 else
6794 gtk_widget_hide(PIDGIN_CONVERSATION(conv)->infopane_hbox);
6795
6796 if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM) {
6770 pidgin_conv_update_buddy_icon(conv); 6797 pidgin_conv_update_buddy_icon(conv);
6798 }
6771 } 6799 }
6772 } 6800 }
6773 6801
6774 static void 6802 static void
6775 conv_placement_usetabs_cb(const char *name, PurplePrefType type, 6803 conv_placement_usetabs_cb(const char *name, PurplePrefType type,
7055 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/font_face", ""); 7083 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/font_face", "");
7056 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/font_size", 3); 7084 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/font_size", 3);
7057 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/tabs", TRUE); 7085 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/tabs", TRUE);
7058 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/tab_side", GTK_POS_TOP); 7086 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/tab_side", GTK_POS_TOP);
7059 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/scrollback_lines", 4000); 7087 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/scrollback_lines", 4000);
7088 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/x", 0);
7089 purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/y", 0);
7060 7090
7061 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font", TRUE); 7091 purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font", TRUE);
7062 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/custom_font", ""); 7092 purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/custom_font", "");
7063 7093
7064 /* Conversations -> Chat */ 7094 /* Conversations -> Chat */
7200 PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM, NULL, 7230 PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM, NULL,
7201 debug_command_cb, _("debug &lt;option&gt;: Send various debug information to the current conversation."), NULL); 7231 debug_command_cb, _("debug &lt;option&gt;: Send various debug information to the current conversation."), NULL);
7202 purple_cmd_register("clear", "", PURPLE_CMD_P_DEFAULT, 7232 purple_cmd_register("clear", "", PURPLE_CMD_P_DEFAULT,
7203 PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM, NULL, 7233 PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM, NULL,
7204 clear_command_cb, _("clear: Clears the conversation scrollback."), NULL); 7234 clear_command_cb, _("clear: Clears the conversation scrollback."), NULL);
7235 purple_cmd_register("clearall", "", PURPLE_CMD_P_DEFAULT,
7236 PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM, NULL,
7237 clearall_command_cb, _("clear: Clears all conversation scrollbacks."), NULL);
7205 purple_cmd_register("help", "w", PURPLE_CMD_P_DEFAULT, 7238 purple_cmd_register("help", "w", PURPLE_CMD_P_DEFAULT,
7206 PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, NULL, 7239 PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, NULL,
7207 help_command_cb, _("help &lt;command&gt;: Help on a specific command."), NULL); 7240 help_command_cb, _("help &lt;command&gt;: Help on a specific command."), NULL);
7208 7241
7209 /********************************************************************** 7242 /**********************************************************************
7610 static gboolean 7643 static gboolean
7611 infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) 7644 infopane_press_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
7612 { 7645 {
7613 int nb_x, nb_y; 7646 int nb_x, nb_y;
7614 7647
7615 if (e->button != 1 || e->type != GDK_BUTTON_PRESS) 7648 if (e->type != GDK_BUTTON_PRESS)
7616 return FALSE; 7649 return FALSE;
7617 7650
7651 if (e->button == 3) {
7652 /* Right click was pressed. Popup the Send To menu. */
7653 GtkWidget *menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to));
7654 if (menu)
7655 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time);
7656 else
7657 return FALSE;
7658 return TRUE;
7659 } else if (e->button != 1) {
7660 return FALSE;
7661 }
7662
7618 if (gtkconv->win->in_drag) { 7663 if (gtkconv->win->in_drag) {
7619 purple_debug(PURPLE_DEBUG_WARNING, "gtkconv", 7664 purple_debug(PURPLE_DEBUG_WARNING, "gtkconv",
7620 "Already in the middle of a window drag at tab_press_cb\n"); 7665 "Already in the middle of a window drag at tab_press_cb\n");
7621 return TRUE; 7666 return TRUE;
7622 } 7667 }
7623 7668
7624 gtkconv->win->in_predrag = TRUE; 7669 gtkconv->win->in_predrag = TRUE;
7625 gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont); 7670 gtkconv->win->drag_tab = gtk_notebook_page_num(GTK_NOTEBOOK(gtkconv->win->notebook), gtkconv->tab_cont);
7626 7671
7627 gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y); 7672 gdk_window_get_origin(gtkconv->infopane_hbox->window, &nb_x, &nb_y);
7628 7673
7629 gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x; 7674 gtkconv->win->drag_min_x = gtkconv->infopane_hbox->allocation.x + nb_x;
7630 gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y; 7675 gtkconv->win->drag_min_y = gtkconv->infopane_hbox->allocation.y + nb_y;
7631 gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x; 7676 gtkconv->win->drag_max_x = gtkconv->infopane_hbox->allocation.width + gtkconv->win->drag_min_x;
7632 gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y; 7677 gtkconv->win->drag_max_y = gtkconv->infopane_hbox->allocation.height + gtkconv->win->drag_min_y;
7633
7634 7678
7635 /* Connect the new motion signals. */ 7679 /* Connect the new motion signals. */
7636 gtkconv->win->drag_motion_signal = 7680 gtkconv->win->drag_motion_signal =
7637 g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event", 7681 g_signal_connect(G_OBJECT(gtkconv->win->notebook), "motion_notify_event",
7638 G_CALLBACK(notebook_motion_cb), gtkconv->win); 7682 G_CALLBACK(notebook_motion_cb), gtkconv->win);
7639 7683
7640 gtkconv->win->drag_leave_signal = 7684 gtkconv->win->drag_leave_signal =
7641 g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event", 7685 g_signal_connect(G_OBJECT(gtkconv->win->notebook), "leave_notify_event",
7642 G_CALLBACK(notebook_leave_cb), gtkconv->win); 7686 G_CALLBACK(notebook_leave_cb), gtkconv->win);
7643 7687
7644 return FALSE; 7688 return FALSE;
7645 7689
7646 } 7690 }
7647 7691
7729 win->drag_leave_signal = 7773 win->drag_leave_signal =
7730 g_signal_connect(G_OBJECT(widget), "leave_notify_event", 7774 g_signal_connect(G_OBJECT(widget), "leave_notify_event",
7731 G_CALLBACK(notebook_leave_cb), win); 7775 G_CALLBACK(notebook_leave_cb), win);
7732 7776
7733 return FALSE; 7777 return FALSE;
7734 }
7735
7736 static gboolean
7737 infopane_release_cb(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv)
7738 {
7739 } 7778 }
7740 7779
7741 static gboolean 7780 static gboolean
7742 notebook_release_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win) 7781 notebook_release_cb(GtkWidget *widget, GdkEventButton *e, PidginWindow *win)
7743 { 7782 {
8067 if (!GTK_WIDGET_VISIBLE(gtkconv->tab_label)) { 8106 if (!GTK_WIDGET_VISIBLE(gtkconv->tab_label)) {
8068 /* There's already an entry for alias. Let's not create another one. */ 8107 /* There's already an entry for alias. Let's not create another one. */
8069 return FALSE; 8108 return FALSE;
8070 } 8109 }
8071 8110
8111 if (!purple_account_is_connected(gtkconv->active_conv->account)) {
8112 /* Do not allow aliasing someone on a disconnected account. */
8113 return FALSE;
8114 }
8115
8072 /* alias label */ 8116 /* alias label */
8073 entry = gtk_entry_new(); 8117 entry = gtk_entry_new();
8074 gtk_entry_set_has_frame(GTK_ENTRY(entry), FALSE); 8118 gtk_entry_set_has_frame(GTK_ENTRY(entry), FALSE);
8075 gtk_entry_set_width_chars(GTK_ENTRY(entry), 10); 8119 gtk_entry_set_width_chars(GTK_ENTRY(entry), 10);
8076 #if GTK_CHECK_VERSION(2,4,0) 8120 #if GTK_CHECK_VERSION(2,4,0)
8195 plugin_changed_cb(PurplePlugin *p, gpointer data) 8239 plugin_changed_cb(PurplePlugin *p, gpointer data)
8196 { 8240 {
8197 regenerate_plugins_items(data); 8241 regenerate_plugins_items(data);
8198 } 8242 }
8199 8243
8244 static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
8245 int x, y;
8246
8247 if (GTK_WIDGET_VISIBLE(w))
8248 gtk_window_get_position(GTK_WINDOW(w), &x, &y);
8249 else
8250 return FALSE; /* carry on normally */
8251
8252 /* Workaround for GTK+ bug # 169811 - "configure_event" is fired
8253 * when the window is being maximized */
8254 if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED)
8255 return FALSE;
8256
8257 /* don't save if nothing changed */
8258 if (x == purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/x") &&
8259 y == purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/y") &&
8260 event->width == purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width") &&
8261 event->height == purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height"))
8262 return FALSE; /* carry on normally */
8263
8264 /* don't save off-screen positioning */
8265 if (x + event->width < 0 ||
8266 y + event->height < 0 ||
8267 x > gdk_screen_width() ||
8268 y > gdk_screen_height())
8269 return FALSE; /* carry on normally */
8270
8271 /* store the position */
8272 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/x", x);
8273 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/y", y);
8274 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/width", event->width);
8275 purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/height", event->height);
8276
8277 /* continue to handle event normally */
8278 return FALSE;
8279
8280 }
8281
8200 PidginWindow * 8282 PidginWindow *
8201 pidgin_conv_window_new() 8283 pidgin_conv_window_new()
8202 { 8284 {
8203 PidginWindow *win; 8285 PidginWindow *win;
8204 GtkPositionType pos; 8286 GtkPositionType pos;
8209 8291
8210 window_list = g_list_append(window_list, win); 8292 window_list = g_list_append(window_list, win);
8211 8293
8212 /* Create the window. */ 8294 /* Create the window. */
8213 win->window = pidgin_create_window(NULL, 0, "conversation", TRUE); 8295 win->window = pidgin_create_window(NULL, 0, "conversation", TRUE);
8214 GTK_WINDOW(win->window)->allow_shrink = TRUE; 8296 gtk_window_set_default_size(GTK_WINDOW(win->window), purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/width"),
8297 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/height"));
8215 8298
8216 if (available_list == NULL) { 8299 if (available_list == NULL) {
8217 create_icon_lists(win->window); 8300 create_icon_lists(win->window);
8218 } 8301 }
8219 8302
8220 g_signal_connect(G_OBJECT(win->window), "delete_event", 8303 g_signal_connect(G_OBJECT(win->window), "delete_event",
8221 G_CALLBACK(close_win_cb), win); 8304 G_CALLBACK(close_win_cb), win);
8222 8305 g_signal_connect(G_OBJECT(win->window), "configure_event",
8306 G_CALLBACK(gtk_conv_configure_cb), NULL);
8223 g_signal_connect(G_OBJECT(win->window), "focus_in_event", 8307 g_signal_connect(G_OBJECT(win->window), "focus_in_event",
8224 G_CALLBACK(focus_win_cb), win); 8308 G_CALLBACK(focus_win_cb), win);
8225 8309
8226 /* Create the notebook. */ 8310 /* Create the notebook. */
8227 win->notebook = gtk_notebook_new(); 8311 win->notebook = gtk_notebook_new();
8276 8360
8277 8361
8278 #ifdef _WIN32 8362 #ifdef _WIN32
8279 g_signal_connect(G_OBJECT(win->window), "show", 8363 g_signal_connect(G_OBJECT(win->window), "show",
8280 G_CALLBACK(winpidgin_ensure_onscreen), win->window); 8364 G_CALLBACK(winpidgin_ensure_onscreen), win->window);
8365
8366 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/win32/minimize_new_convs"))
8367 gtk_window_iconify(GTK_WINDOW(win->window));
8281 #endif 8368 #endif
8282 8369
8283 return win; 8370 return win;
8284 } 8371 }
8285 8372
8552 } 8639 }
8553 8640
8554 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv); 8641 win->gtkconvs = g_list_remove(win->gtkconvs, gtkconv);
8555 8642
8556 if (!win->gtkconvs || !win->gtkconvs->next) 8643 if (!win->gtkconvs || !win->gtkconvs->next)
8557 gtk_notebook_set_show_tabs(win->notebook, FALSE); 8644 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE);
8558 8645
8559 if (!win->gtkconvs && win != hidden_convwin) 8646 if (!win->gtkconvs && win != hidden_convwin)
8560 pidgin_conv_window_destroy(win); 8647 pidgin_conv_window_destroy(win);
8561 } 8648 }
8562 8649

mercurial