| 270 |
270 |
| 271 static void |
271 static void |
| 272 default_formatize(PidginConversation *c) |
272 default_formatize(PidginConversation *c) |
| 273 { |
273 { |
| 274 PurpleConversation *conv = c->active_conv; |
274 PurpleConversation *conv = c->active_conv; |
| 275 |
275 gtk_imhtml_setup_entry(GTK_IMHTML(c->entry), conv->features); |
| 276 if (conv->features & PURPLE_CONNECTION_HTML) |
|
| 277 { |
|
| 278 char color[8]; |
|
| 279 GdkColor fg_color, bg_color; |
|
| 280 |
|
| 281 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold") != GTK_IMHTML(c->entry)->edit.bold) |
|
| 282 gtk_imhtml_toggle_bold(GTK_IMHTML(c->entry)); |
|
| 283 |
|
| 284 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic") != GTK_IMHTML(c->entry)->edit.italic) |
|
| 285 gtk_imhtml_toggle_italic(GTK_IMHTML(c->entry)); |
|
| 286 |
|
| 287 if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline") != GTK_IMHTML(c->entry)->edit.underline) |
|
| 288 gtk_imhtml_toggle_underline(GTK_IMHTML(c->entry)); |
|
| 289 |
|
| 290 gtk_imhtml_toggle_fontface(GTK_IMHTML(c->entry), |
|
| 291 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/font_face")); |
|
| 292 |
|
| 293 if (!(conv->features & PURPLE_CONNECTION_NO_FONTSIZE)) |
|
| 294 { |
|
| 295 int size = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/font_size"); |
|
| 296 |
|
| 297 /* 3 is the default. */ |
|
| 298 if (size != 3) |
|
| 299 gtk_imhtml_font_set_size(GTK_IMHTML(c->entry), size); |
|
| 300 } |
|
| 301 |
|
| 302 if(strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), "") != 0) |
|
| 303 { |
|
| 304 gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), |
|
| 305 &fg_color); |
|
| 306 g_snprintf(color, sizeof(color), "#%02x%02x%02x", |
|
| 307 fg_color.red / 256, |
|
| 308 fg_color.green / 256, |
|
| 309 fg_color.blue / 256); |
|
| 310 } else |
|
| 311 strcpy(color, ""); |
|
| 312 |
|
| 313 gtk_imhtml_toggle_forecolor(GTK_IMHTML(c->entry), color); |
|
| 314 |
|
| 315 if(!(conv->features & PURPLE_CONNECTION_NO_BGCOLOR) && |
|
| 316 strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), "") != 0) |
|
| 317 { |
|
| 318 gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), |
|
| 319 &bg_color); |
|
| 320 g_snprintf(color, sizeof(color), "#%02x%02x%02x", |
|
| 321 bg_color.red / 256, |
|
| 322 bg_color.green / 256, |
|
| 323 bg_color.blue / 256); |
|
| 324 } else |
|
| 325 strcpy(color, ""); |
|
| 326 |
|
| 327 gtk_imhtml_toggle_background(GTK_IMHTML(c->entry), color); |
|
| 328 |
|
| 329 if (conv->features & PURPLE_CONNECTION_FORMATTING_WBFO) |
|
| 330 gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(c->entry), TRUE); |
|
| 331 else |
|
| 332 gtk_imhtml_set_whole_buffer_formatting_only(GTK_IMHTML(c->entry), FALSE); |
|
| 333 } |
|
| 334 } |
276 } |
| 335 |
277 |
| 336 static void |
278 static void |
| 337 clear_formatting_cb(GtkIMHtml *imhtml, PidginConversation *gtkconv) |
279 clear_formatting_cb(GtkIMHtml *imhtml, PidginConversation *gtkconv) |
| 338 { |
280 { |
| 2271 **************************************************************************/ |
2207 **************************************************************************/ |
| 2272 |
2208 |
| 2273 static GList *get_prpl_icon_list(PurpleAccount *account) |
2209 static GList *get_prpl_icon_list(PurpleAccount *account) |
| 2274 { |
2210 { |
| 2275 GList *l = NULL; |
2211 GList *l = NULL; |
| 2276 GdkPixbuf *pixbuf; |
2212 PurplePlugin *prpl = purple_find_prpl(purple_account_get_protocol_id(account)); |
| 2277 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(purple_find_prpl(purple_account_get_protocol_id(account))); |
2213 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); |
| 2278 const char *prpl = prpl_info->list_icon(account, NULL); |
2214 const char *prplname = prpl_info->list_icon(account, NULL); |
| 2279 char *filename, *path; |
2215 l = g_hash_table_lookup(prpl_lists, prplname); |
| 2280 l = g_hash_table_lookup(prpl_lists, prpl); |
|
| 2281 if (l) |
2216 if (l) |
| 2282 return l; |
2217 return l; |
| 2283 filename = g_strdup_printf("%s.png", prpl); |
2218 |
| 2284 |
2219 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_LARGE)); |
| 2285 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "16", filename, NULL); |
2220 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_MEDIUM)); |
| 2286 pixbuf = gdk_pixbuf_new_from_file(path, NULL); |
2221 l = g_list_prepend(l, pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL)); |
| 2287 if (pixbuf) |
2222 |
| 2288 l = g_list_append(l, pixbuf); |
2223 g_hash_table_insert(prpl_lists, g_strdup(prplname), l); |
| 2289 g_free(path); |
|
| 2290 |
|
| 2291 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "22", filename, NULL); |
|
| 2292 pixbuf = gdk_pixbuf_new_from_file(path, NULL); |
|
| 2293 if (pixbuf) |
|
| 2294 l = g_list_append(l, pixbuf); |
|
| 2295 g_free(path); |
|
| 2296 |
|
| 2297 path = g_build_filename(DATADIR, "pixmaps", "pidgin", "protocols", "48", filename, NULL); |
|
| 2298 pixbuf = gdk_pixbuf_new_from_file(path, NULL); |
|
| 2299 if (pixbuf) |
|
| 2300 l = g_list_append(l, pixbuf); |
|
| 2301 g_free(path); |
|
| 2302 |
|
| 2303 g_hash_table_insert(prpl_lists, g_strdup(prpl), l); |
|
| 2304 return l; |
2224 return l; |
| 2305 } |
2225 } |
| 2306 |
2226 |
| 2307 static GList * |
2227 static GList * |
| 2308 pidgin_conv_get_tab_icons(PurpleConversation *conv) |
2228 pidgin_conv_get_tab_icons(PurpleConversation *conv) |
| 3027 } |
2947 } |
| 3028 |
2948 |
| 3029 gtk_widget_show_all(menu); |
2949 gtk_widget_show_all(menu); |
| 3030 } |
2950 } |
| 3031 |
2951 |
| |
2952 static void |
| |
2953 remove_from_list(GtkWidget *widget, PidginWindow *win) |
| |
2954 { |
| |
2955 GList *list = g_object_get_data(G_OBJECT(win->window), "plugin-actions"); |
| |
2956 list = g_list_remove(list, widget); |
| |
2957 g_object_set_data(G_OBJECT(win->window), "plugin-actions", list); |
| |
2958 } |
| |
2959 |
| |
2960 static void |
| |
2961 regenerate_plugins_items(PidginWindow *win) |
| |
2962 { |
| |
2963 GList *action_items; |
| |
2964 GtkWidget *menu; |
| |
2965 GList *list; |
| |
2966 PidginConversation *gtkconv; |
| |
2967 PurpleConversation *conv; |
| |
2968 GtkWidget *item; |
| |
2969 |
| |
2970 if (win->window == NULL || win == hidden_convwin) |
| |
2971 return; |
| |
2972 |
| |
2973 gtkconv = pidgin_conv_window_get_active_gtkconv(win); |
| |
2974 if (gtkconv == NULL) |
| |
2975 return; |
| |
2976 |
| |
2977 conv = gtkconv->active_conv; |
| |
2978 action_items = g_object_get_data(G_OBJECT(win->window), "plugin-actions"); |
| |
2979 |
| |
2980 /* Remove the old menuitems */ |
| |
2981 while (action_items) { |
| |
2982 g_signal_handlers_disconnect_by_func(G_OBJECT(action_items->data), |
| |
2983 G_CALLBACK(remove_from_list), win); |
| |
2984 gtk_widget_destroy(action_items->data); |
| |
2985 action_items = g_list_delete_link(action_items, action_items); |
| |
2986 } |
| |
2987 |
| |
2988 menu = gtk_item_factory_get_widget(win->menu.item_factory, N_("/Options")); |
| |
2989 |
| |
2990 list = purple_conversation_get_extended_menu(conv); |
| |
2991 if (list) { |
| |
2992 action_items = g_list_prepend(NULL, (item = pidgin_separator(menu))); |
| |
2993 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); |
| |
2994 } |
| |
2995 |
| |
2996 for(; list; list = g_list_delete_link(list, list)) { |
| |
2997 PurpleMenuAction *act = (PurpleMenuAction *) list->data; |
| |
2998 item = pidgin_append_menu_action(menu, act, conv); |
| |
2999 action_items = g_list_prepend(action_items, item); |
| |
3000 gtk_widget_show_all(item); |
| |
3001 g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(remove_from_list), win); |
| |
3002 } |
| |
3003 g_object_set_data(G_OBJECT(win->window), "plugin-actions", action_items); |
| |
3004 } |
| |
3005 |
| 3032 static void menubar_activated(GtkWidget *item, gpointer data) |
3006 static void menubar_activated(GtkWidget *item, gpointer data) |
| 3033 { |
3007 { |
| 3034 PidginWindow *win = data; |
3008 PidginWindow *win = data; |
| 3035 regenerate_options_items(win); |
3009 regenerate_options_items(win); |
| |
3010 regenerate_plugins_items(win); |
| 3036 |
3011 |
| 3037 /* The following are to make sure the 'More' submenu is not regenerated every time |
3012 /* The following are to make sure the 'More' submenu is not regenerated every time |
| 3038 * the focus shifts from 'Conversations' to some other menu and back. */ |
3013 * the focus shifts from 'Conversations' to some other menu and back. */ |
| 3039 g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data); |
3014 g_signal_handlers_block_by_func(G_OBJECT(item), G_CALLBACK(menubar_activated), data); |
| 3040 g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), data); |
3015 g_signal_connect(G_OBJECT(win->menu.menubar), "deactivate", G_CALLBACK(focus_out_from_menubar), data); |
| 4242 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height + PIDGIN_HIG_BOX_SPACE); |
4217 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height + PIDGIN_HIG_BOX_SPACE); |
| 4243 g_idle_add(reset_auto_resize_cb, gtkconv); |
4218 g_idle_add(reset_auto_resize_cb, gtkconv); |
| 4244 } |
4219 } |
| 4245 } |
4220 } |
| 4246 |
4221 |
| 4247 static GtkWidget * |
4222 static void |
| 4248 setup_chat_pane(PidginConversation *gtkconv) |
4223 setup_chat_topic(PidginConversation *gtkconv, GtkWidget *vbox) |
| 4249 { |
4224 { |
| 4250 PurplePluginProtocolInfo *prpl_info; |
|
| 4251 PurpleConversation *conv = gtkconv->active_conv; |
4225 PurpleConversation *conv = gtkconv->active_conv; |
| 4252 PidginChatPane *gtkchat; |
4226 PurpleConnection *gc = purple_conversation_get_gc(conv); |
| 4253 PurpleConnection *gc; |
4227 PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); |
| 4254 GtkWidget *vpaned, *hpaned; |
|
| 4255 GtkWidget *vbox, *hbox, *frame; |
|
| 4256 GtkWidget *imhtml_sw; |
|
| 4257 GtkPolicyType imhtml_sw_hscroll; |
|
| 4258 GtkWidget *lbox; |
|
| 4259 GtkWidget *label; |
|
| 4260 GtkWidget *list; |
|
| 4261 GtkWidget *sw; |
|
| 4262 GtkListStore *ls; |
|
| 4263 GtkCellRenderer *rend; |
|
| 4264 GtkTreeViewColumn *col; |
|
| 4265 void *blist_handle = purple_blist_get_handle(); |
|
| 4266 GList *focus_chain = NULL; |
|
| 4267 int ul_width; |
|
| 4268 |
|
| 4269 gtkchat = gtkconv->u.chat; |
|
| 4270 gc = purple_conversation_get_gc(conv); |
|
| 4271 g_return_val_if_fail(gc != NULL, NULL); |
|
| 4272 g_return_val_if_fail(gc->prpl != NULL, NULL); |
|
| 4273 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); |
|
| 4274 |
|
| 4275 /* Setup the outer pane. */ |
|
| 4276 vpaned = gtk_vpaned_new(); |
|
| 4277 gtk_widget_show(vpaned); |
|
| 4278 |
|
| 4279 /* Setup the top part of the pane. */ |
|
| 4280 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
|
| 4281 gtk_paned_pack1(GTK_PANED(vpaned), vbox, TRUE, TRUE); |
|
| 4282 gtk_widget_show(vbox); |
|
| 4283 |
|
| 4284 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) |
4228 if (prpl_info->options & OPT_PROTO_CHAT_TOPIC) |
| 4285 { |
4229 { |
| |
4230 GtkWidget *hbox, *label; |
| |
4231 PidginChatPane *gtkchat = gtkconv->u.chat; |
| |
4232 |
| 4286 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4233 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| 4287 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
4234 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); |
| 4288 gtk_widget_show(hbox); |
4235 gtk_widget_show(hbox); |
| 4289 |
4236 |
| 4290 label = gtk_label_new(_("Topic:")); |
4237 label = gtk_label_new(_("Topic:")); |
| 4303 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); |
4250 gtk_box_pack_start(GTK_BOX(hbox), gtkchat->topic_text, TRUE, TRUE, 0); |
| 4304 gtk_widget_show(gtkchat->topic_text); |
4251 gtk_widget_show(gtkchat->topic_text); |
| 4305 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", |
4252 g_signal_connect(G_OBJECT(gtkchat->topic_text), "key_press_event", |
| 4306 G_CALLBACK(entry_key_press_cb), gtkconv); |
4253 G_CALLBACK(entry_key_press_cb), gtkconv); |
| 4307 } |
4254 } |
| 4308 |
4255 } |
| 4309 /* Setup the horizontal pane. */ |
4256 |
| 4310 hpaned = gtk_hpaned_new(); |
4257 static void |
| 4311 gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); |
4258 setup_chat_userlist(PidginConversation *gtkconv, GtkWidget *hpaned) |
| 4312 gtk_widget_show(hpaned); |
4259 { |
| 4313 |
4260 PidginChatPane *gtkchat = gtkconv->u.chat; |
| 4314 /* Setup gtkihmtml. */ |
4261 GtkWidget *lbox, *sw, *list; |
| 4315 frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); |
4262 GtkListStore *ls; |
| 4316 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); |
4263 GtkCellRenderer *rend; |
| 4317 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml), TRUE); |
4264 GtkTreeViewColumn *col; |
| 4318 gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE); |
4265 int ul_width; |
| 4319 gtk_widget_show(frame); |
4266 void *blist_handle = purple_blist_get_handle(); |
| 4320 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), |
4267 PurpleConversation *conv = gtkconv->active_conv; |
| 4321 &imhtml_sw_hscroll, NULL); |
|
| 4322 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), |
|
| 4323 imhtml_sw_hscroll, GTK_POLICY_ALWAYS); |
|
| 4324 |
|
| 4325 gtk_widget_set_size_request(gtkconv->imhtml, |
|
| 4326 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width"), |
|
| 4327 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height")); |
|
| 4328 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", |
|
| 4329 G_CALLBACK(size_allocate_cb), gtkconv); |
|
| 4330 |
|
| 4331 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", |
|
| 4332 G_CALLBACK(entry_stop_rclick_cb), NULL); |
|
| 4333 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", |
|
| 4334 G_CALLBACK(refocus_entry_cb), gtkconv); |
|
| 4335 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", |
|
| 4336 G_CALLBACK(refocus_entry_cb), gtkconv); |
|
| 4337 |
4268 |
| 4338 /* Build the right pane. */ |
4269 /* Build the right pane. */ |
| 4339 lbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4270 lbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| 4340 gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE); |
4271 gtk_paned_pack2(GTK_PANED(hpaned), lbox, FALSE, TRUE); |
| 4341 gtk_widget_show(lbox); |
4272 gtk_widget_show(lbox); |
| 4412 gtk_widget_show(list); |
4341 gtk_widget_show(list); |
| 4413 |
4342 |
| 4414 gtkchat->list = list; |
4343 gtkchat->list = list; |
| 4415 |
4344 |
| 4416 gtk_container_add(GTK_CONTAINER(sw), list); |
4345 gtk_container_add(GTK_CONTAINER(sw), list); |
| |
4346 } |
| |
4347 |
| |
4348 static GtkWidget * |
| |
4349 setup_common_pane(PidginConversation *gtkconv) |
| |
4350 { |
| |
4351 GtkWidget *paned, *vbox, *frame, *imhtml_sw; |
| |
4352 PurpleConversation *conv = gtkconv->active_conv; |
| |
4353 gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT); |
| |
4354 GtkPolicyType imhtml_sw_hscroll; |
| |
4355 |
| |
4356 paned = gtk_vpaned_new(); |
| |
4357 gtk_widget_show(paned); |
| |
4358 |
| |
4359 /* Setup the top part of the pane */ |
| |
4360 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| |
4361 gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE); |
| |
4362 gtk_widget_show(vbox); |
| |
4363 |
| |
4364 /* Setup the gtkimhtml widget */ |
| |
4365 frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); |
| |
4366 if (chat) { |
| |
4367 GtkWidget *hpaned; |
| |
4368 |
| |
4369 /* Add the topic */ |
| |
4370 setup_chat_topic(gtkconv, vbox); |
| |
4371 |
| |
4372 /* Add the gtkimhtml frame */ |
| |
4373 hpaned = gtk_hpaned_new(); |
| |
4374 gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0); |
| |
4375 gtk_widget_show(hpaned); |
| |
4376 gtk_paned_pack1(GTK_PANED(hpaned), frame, TRUE, TRUE); |
| |
4377 |
| |
4378 /* Now add the userlist */ |
| |
4379 setup_chat_userlist(gtkconv, hpaned); |
| |
4380 } else { |
| |
4381 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); |
| |
4382 } |
| |
4383 gtk_widget_show(frame); |
| |
4384 |
| |
4385 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); |
| |
4386 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); |
| |
4387 |
| |
4388 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), |
| |
4389 &imhtml_sw_hscroll, NULL); |
| |
4390 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), |
| |
4391 imhtml_sw_hscroll, GTK_POLICY_ALWAYS); |
| |
4392 |
| |
4393 gtk_widget_set_size_request(gtkconv->imhtml, |
| |
4394 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width") : |
| |
4395 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"), |
| |
4396 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height") : |
| |
4397 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height")); |
| |
4398 |
| |
4399 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", |
| |
4400 G_CALLBACK(size_allocate_cb), gtkconv); |
| |
4401 |
| |
4402 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", |
| |
4403 G_CALLBACK(entry_stop_rclick_cb), NULL); |
| |
4404 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", |
| |
4405 G_CALLBACK(refocus_entry_cb), gtkconv); |
| |
4406 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", |
| |
4407 G_CALLBACK(refocus_entry_cb), gtkconv); |
| 4417 |
4408 |
| 4418 /* Setup the bottom half of the conversation window */ |
4409 /* Setup the bottom half of the conversation window */ |
| 4419 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4410 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| 4420 gtk_paned_pack2(GTK_PANED(vpaned), vbox, FALSE, TRUE); |
4411 gtk_paned_pack2(GTK_PANED(paned), vbox, FALSE, TRUE); |
| 4421 gtk_widget_show(vbox); |
4412 gtk_widget_show(vbox); |
| 4422 |
4413 |
| 4423 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
4414 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
| 4424 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->lower_hbox, TRUE, TRUE, 0); |
4415 gtk_box_pack_start(GTK_BOX(vbox), gtkconv->lower_hbox, TRUE, TRUE, 0); |
| 4425 gtk_widget_show(gtkconv->lower_hbox); |
4416 gtk_widget_show(gtkconv->lower_hbox); |
| 4431 /* Setup the toolbar, entry widget and all signals */ |
4422 /* Setup the toolbar, entry widget and all signals */ |
| 4432 frame = pidgin_create_imhtml(TRUE, >kconv->entry, >kconv->toolbar, NULL); |
4423 frame = pidgin_create_imhtml(TRUE, >kconv->entry, >kconv->toolbar, NULL); |
| 4433 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); |
4424 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); |
| 4434 gtk_widget_show(frame); |
4425 gtk_widget_show(frame); |
| 4435 |
4426 |
| 4436 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", |
|
| 4437 G_CALLBACK(entry_popup_menu_cb), gtkconv); |
|
| 4438 |
|
| 4439 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); |
4427 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); |
| 4440 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), |
4428 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), |
| 4441 purple_account_get_protocol_name(conv->account)); |
4429 purple_account_get_protocol_name(conv->account)); |
| 4442 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, |
4430 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, |
| 4443 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height")); |
4431 chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height") : |
| 4444 gtkconv->entry_buffer = |
4432 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height")); |
| 4445 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); |
4433 |
| 4446 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); |
4434 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", |
| 4447 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", |
4435 G_CALLBACK(entry_popup_menu_cb), gtkconv); |
| 4448 G_CALLBACK(resize_imhtml_cb), gtkconv); |
|
| 4449 |
|
| 4450 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", |
4436 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", |
| 4451 G_CALLBACK(entry_key_press_cb), gtkconv); |
4437 G_CALLBACK(entry_key_press_cb), gtkconv); |
| 4452 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", |
4438 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", |
| 4453 G_CALLBACK(send_cb), gtkconv); |
4439 G_CALLBACK(send_cb), gtkconv); |
| 4454 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", |
4440 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", |
| 4455 G_CALLBACK(entry_stop_rclick_cb), NULL); |
4441 G_CALLBACK(entry_stop_rclick_cb), NULL); |
| 4456 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", |
4442 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", |
| 4457 G_CALLBACK(size_allocate_cb), gtkconv); |
4443 G_CALLBACK(size_allocate_cb), gtkconv); |
| 4458 |
4444 |
| 4459 default_formatize(gtkconv); |
|
| 4460 |
|
| 4461 /* |
|
| 4462 * Focus for chat windows should be as follows: |
|
| 4463 * Tab title -> chat topic -> conversation scrollback -> user list -> |
|
| 4464 * user list buttons -> entry -> buttons at bottom |
|
| 4465 */ |
|
| 4466 focus_chain = g_list_prepend(focus_chain, gtkconv->entry); |
|
| 4467 gtk_container_set_focus_chain(GTK_CONTAINER(vbox), focus_chain); |
|
| 4468 |
|
| 4469 return vpaned; |
|
| 4470 } |
|
| 4471 |
|
| 4472 static GtkWidget * |
|
| 4473 setup_im_pane(PidginConversation *gtkconv) |
|
| 4474 { |
|
| 4475 PurpleConversation *conv = gtkconv->active_conv; |
|
| 4476 GtkWidget *frame; |
|
| 4477 GtkWidget *imhtml_sw; |
|
| 4478 GtkPolicyType imhtml_sw_hscroll; |
|
| 4479 GtkWidget *paned; |
|
| 4480 GtkWidget *vbox; |
|
| 4481 GtkWidget *vbox2; |
|
| 4482 GList *focus_chain = NULL; |
|
| 4483 |
|
| 4484 /* Setup the outer pane */ |
|
| 4485 paned = gtk_vpaned_new(); |
|
| 4486 gtk_widget_show(paned); |
|
| 4487 |
|
| 4488 /* Setup the top part of the pane */ |
|
| 4489 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
|
| 4490 gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE); |
|
| 4491 gtk_widget_show(vbox); |
|
| 4492 |
|
| 4493 /* Setup the gtkimhtml widget */ |
|
| 4494 frame = pidgin_create_imhtml(FALSE, >kconv->imhtml, NULL, &imhtml_sw); |
|
| 4495 gtk_widget_set_name(gtkconv->imhtml, "pidgin_conv_imhtml"); |
|
| 4496 gtk_imhtml_show_comments(GTK_IMHTML(gtkconv->imhtml),TRUE); |
|
| 4497 gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0); |
|
| 4498 gtk_widget_show(frame); |
|
| 4499 gtk_scrolled_window_get_policy(GTK_SCROLLED_WINDOW(imhtml_sw), |
|
| 4500 &imhtml_sw_hscroll, NULL); |
|
| 4501 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw), |
|
| 4502 imhtml_sw_hscroll, GTK_POLICY_ALWAYS); |
|
| 4503 |
|
| 4504 gtk_widget_set_size_request(gtkconv->imhtml, |
|
| 4505 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"), |
|
| 4506 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height")); |
|
| 4507 g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate", |
|
| 4508 G_CALLBACK(size_allocate_cb), gtkconv); |
|
| 4509 |
|
| 4510 g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event", |
|
| 4511 G_CALLBACK(entry_stop_rclick_cb), NULL); |
|
| 4512 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event", |
|
| 4513 G_CALLBACK(refocus_entry_cb), gtkconv); |
|
| 4514 g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event", |
|
| 4515 G_CALLBACK(refocus_entry_cb), gtkconv); |
|
| 4516 |
|
| 4517 /* Setup the bottom half of the conversation window */ |
|
| 4518 vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
|
| 4519 gtk_paned_pack2(GTK_PANED(paned), vbox2, FALSE, TRUE); |
|
| 4520 gtk_widget_show(vbox2); |
|
| 4521 |
|
| 4522 gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
|
| 4523 gtk_box_pack_start(GTK_BOX(vbox2), gtkconv->lower_hbox, TRUE, TRUE, 0); |
|
| 4524 gtk_widget_show(gtkconv->lower_hbox); |
|
| 4525 |
|
| 4526 vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); |
|
| 4527 gtk_box_pack_end(GTK_BOX(gtkconv->lower_hbox), vbox2, TRUE, TRUE, 0); |
|
| 4528 gtk_widget_show(vbox2); |
|
| 4529 |
|
| 4530 /* Setup the toolbar, entry widget and all signals */ |
|
| 4531 frame = pidgin_create_imhtml(TRUE, >kconv->entry, >kconv->toolbar, NULL); |
|
| 4532 gtk_box_pack_start(GTK_BOX(vbox2), frame, TRUE, TRUE, 0); |
|
| 4533 gtk_widget_show(frame); |
|
| 4534 |
|
| 4535 g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup", |
|
| 4536 G_CALLBACK(entry_popup_menu_cb), gtkconv); |
|
| 4537 |
|
| 4538 gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry"); |
|
| 4539 gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry), |
|
| 4540 purple_account_get_protocol_name(conv->account)); |
|
| 4541 gtk_widget_set_size_request(gtkconv->lower_hbox, -1, |
|
| 4542 purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height")); |
|
| 4543 gtkconv->entry_buffer = |
4445 gtkconv->entry_buffer = |
| 4544 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); |
4446 gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry)); |
| 4545 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); |
4447 g_object_set_data(G_OBJECT(gtkconv->entry_buffer), "user_data", gtkconv); |
| 4546 |
4448 |
| 4547 g_signal_connect(G_OBJECT(gtkconv->entry), "key_press_event", |
4449 if (!chat) { |
| 4548 G_CALLBACK(entry_key_press_cb), gtkconv); |
4450 /* For sending typing notifications for IMs */ |
| 4549 g_signal_connect_after(G_OBJECT(gtkconv->entry), "message_send", |
4451 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", |
| 4550 G_CALLBACK(send_cb), gtkconv); |
4452 G_CALLBACK(insert_text_cb), gtkconv); |
| 4551 g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event", |
4453 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", |
| 4552 G_CALLBACK(entry_stop_rclick_cb), NULL); |
4454 G_CALLBACK(delete_text_cb), gtkconv); |
| 4553 g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate", |
4455 gtkconv->u.im->typing_timer = 0; |
| 4554 G_CALLBACK(size_allocate_cb), gtkconv); |
4456 gtkconv->u.im->animate = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/animate_buddy_icons"); |
| 4555 |
4457 gtkconv->u.im->show_icon = TRUE; |
| 4556 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", |
4458 } |
| 4557 G_CALLBACK(insert_text_cb), gtkconv); |
4459 |
| 4558 g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", |
|
| 4559 G_CALLBACK(delete_text_cb), gtkconv); |
|
| 4560 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", |
4460 g_signal_connect_swapped(G_OBJECT(gtkconv->entry_buffer), "changed", |
| 4561 G_CALLBACK(resize_imhtml_cb), gtkconv); |
4461 G_CALLBACK(resize_imhtml_cb), gtkconv); |
| 4562 |
4462 |
| 4563 /* had to move this after the imtoolbar is attached so that the |
|
| 4564 * signals get fired to toggle the buttons on the toolbar as well. |
|
| 4565 */ |
|
| 4566 default_formatize(gtkconv); |
4463 default_formatize(gtkconv); |
| 4567 |
|
| 4568 g_signal_connect_after(G_OBJECT(gtkconv->entry), "format_function_clear", |
4464 g_signal_connect_after(G_OBJECT(gtkconv->entry), "format_function_clear", |
| 4569 G_CALLBACK(clear_formatting_cb), gtkconv); |
4465 G_CALLBACK(clear_formatting_cb), gtkconv); |
| 4570 |
4466 |
| 4571 gtkconv->u.im->animate = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/animate_buddy_icons"); |
|
| 4572 gtkconv->u.im->show_icon = TRUE; |
|
| 4573 |
|
| 4574 /* |
|
| 4575 * Focus for IM windows should be as follows: |
|
| 4576 * Tab title -> conversation scrollback -> entry |
|
| 4577 */ |
|
| 4578 focus_chain = g_list_prepend(focus_chain, gtkconv->entry); |
|
| 4579 gtk_container_set_focus_chain(GTK_CONTAINER(vbox2), focus_chain); |
|
| 4580 |
|
| 4581 gtkconv->u.im->typing_timer = 0; |
|
| 4582 return paned; |
4467 return paned; |
| 4583 } |
4468 } |
| 4584 |
4469 |
| 4585 static void |
4470 static void |
| 4586 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, |
4471 conv_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, |