Mercurial > pidgin.yaz
comparison src/gtkconv.c @ 8189:b75fa309b2c6
[gaim-migrate @ 8910]
A patch from MBG (chromakode) to make icons not animate when they've
not being viewed. So only the icon on the active conversation in a
window should be animating itself.
His patch was 99 lines and mine is 648... I'm not really sure how that
happened, but I think it's for the best.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sat, 31 Jan 2004 00:33:18 +0000 |
parents | 4e68644a47f6 |
children | 90a1fbd2493d |
comparison
equal
deleted
inserted
replaced
8188:cd9ea20cd8ed | 8189:b75fa309b2c6 |
---|---|
139 static void tab_complete(GaimConversation *conv); | 139 static void tab_complete(GaimConversation *conv); |
140 static void update_typing_icon(GaimConversation *conv); | 140 static void update_typing_icon(GaimConversation *conv); |
141 static gboolean update_send_as_selection(GaimConvWindow *win); | 141 static gboolean update_send_as_selection(GaimConvWindow *win); |
142 static char *item_factory_translate_func (const char *path, gpointer func_data); | 142 static char *item_factory_translate_func (const char *path, gpointer func_data); |
143 static void save_convo(GtkWidget *save, GaimConversation *c); | 143 static void save_convo(GtkWidget *save, GaimConversation *c); |
144 static void update_tab_icon(GaimConversation *conv); | |
145 | 144 |
146 /************************************************************************** | 145 /************************************************************************** |
147 * Callbacks | 146 * Callbacks |
148 **************************************************************************/ | 147 **************************************************************************/ |
149 static void | 148 static void |
2112 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); | 2111 gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); |
2113 | 2112 |
2114 return TRUE; | 2113 return TRUE; |
2115 } | 2114 } |
2116 | 2115 |
2117 static GdkPixbuf *get_tab_icon(GaimConversation *conv) | 2116 /************************************************************************** |
2117 * A bunch of buddy icon functions | |
2118 **************************************************************************/ | |
2119 static GdkPixbuf * | |
2120 get_tab_icon(GaimConversation *conv) | |
2118 { | 2121 { |
2119 GaimAccount *account = gaim_conversation_get_account(conv); | 2122 GaimAccount *account = gaim_conversation_get_account(conv); |
2120 const char *name = gaim_conversation_get_name(conv); | 2123 const char *name = gaim_conversation_get_name(conv); |
2121 GdkPixbuf *status = NULL; | 2124 GdkPixbuf *status = NULL; |
2122 | 2125 |
2138 g_object_unref(pixbuf); | 2141 g_object_unref(pixbuf); |
2139 } | 2142 } |
2140 } | 2143 } |
2141 return status; | 2144 return status; |
2142 } | 2145 } |
2146 | |
2147 static void | |
2148 update_tab_icon(GaimConversation *conv) | |
2149 { | |
2150 GaimGtkConversation *gtkconv; | |
2151 GaimConvWindow *win = gaim_conversation_get_window(conv); | |
2152 GaimAccount *account; | |
2153 const char *name; | |
2154 GdkPixbuf *status = NULL; | |
2155 | |
2156 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2157 name = gaim_conversation_get_name(conv); | |
2158 account = gaim_conversation_get_account(conv); | |
2159 | |
2160 status = get_tab_icon(conv); | |
2161 | |
2162 gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->icon), status); | |
2163 gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->menu_icon), status); | |
2164 | |
2165 if (gaim_conv_window_get_active_conversation(win) == conv && gtkconv->u.im->anim == NULL) | |
2166 gtk_window_set_icon(GTK_WINDOW(GAIM_GTK_WINDOW(win)->window), status); | |
2167 | |
2168 if(status) | |
2169 g_object_unref(status); | |
2170 } | |
2171 | |
2172 static gboolean | |
2173 redraw_icon(gpointer data) | |
2174 { | |
2175 GaimConversation *conv = (GaimConversation *)data; | |
2176 GaimGtkConversation *gtkconv; | |
2177 | |
2178 GdkPixbuf *buf; | |
2179 GdkPixbuf *scale; | |
2180 GdkPixmap *pm; | |
2181 GdkBitmap *bm; | |
2182 gint delay; | |
2183 | |
2184 if (!g_list_find(gaim_get_ims(), conv)) { | |
2185 gaim_debug(GAIM_DEBUG_WARNING, "gtkconv", | |
2186 "Conversation not found in redraw_icon. I think this " | |
2187 "is a bug.\n"); | |
2188 return FALSE; | |
2189 } | |
2190 | |
2191 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2192 | |
2193 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); | |
2194 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); | |
2195 | |
2196 scale = gdk_pixbuf_scale_simple(buf, | |
2197 MAX(gdk_pixbuf_get_width(buf) * SCALE(gtkconv->u.im->anim) / | |
2198 gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1), | |
2199 MAX(gdk_pixbuf_get_height(buf) * SCALE(gtkconv->u.im->anim) / | |
2200 gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1), | |
2201 GDK_INTERP_NEAREST); | |
2202 | |
2203 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 100); | |
2204 g_object_unref(G_OBJECT(scale)); | |
2205 gtk_image_set_from_pixmap(GTK_IMAGE(gtkconv->u.im->icon), pm, bm); | |
2206 g_object_unref(G_OBJECT(pm)); | |
2207 gtk_widget_queue_draw(gtkconv->u.im->icon); | |
2208 | |
2209 if (bm) | |
2210 g_object_unref(G_OBJECT(bm)); | |
2211 | |
2212 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter) / 10; | |
2213 | |
2214 gtkconv->u.im->icon_timer = g_timeout_add(delay * 10, redraw_icon, conv); | |
2215 | |
2216 return FALSE; | |
2217 } | |
2218 | |
2219 static void | |
2220 start_anim(GtkObject *obj, GaimConversation *conv) | |
2221 { | |
2222 GaimGtkConversation *gtkconv; | |
2223 int delay; | |
2224 | |
2225 if (!GAIM_IS_GTK_CONVERSATION(conv)) | |
2226 return; | |
2227 | |
2228 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2229 | |
2230 if (gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim)) | |
2231 return; | |
2232 | |
2233 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter) / 10; | |
2234 | |
2235 if (gtkconv->u.im->anim) | |
2236 gtkconv->u.im->icon_timer = g_timeout_add(delay * 10, redraw_icon, | |
2237 conv); | |
2238 } | |
2239 | |
2240 static void | |
2241 stop_anim(GtkObject *obj, GaimConversation *conv) | |
2242 { | |
2243 GaimGtkConversation *gtkconv; | |
2244 | |
2245 if (!GAIM_IS_GTK_CONVERSATION(conv)) | |
2246 return; | |
2247 | |
2248 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2249 | |
2250 if (gtkconv->u.im->icon_timer != 0) | |
2251 g_source_remove(gtkconv->u.im->icon_timer); | |
2252 | |
2253 gtkconv->u.im->icon_timer = 0; | |
2254 } | |
2255 | |
2256 static void | |
2257 toggle_icon_animate_cb(GtkWidget *w, GaimConversation *conv) | |
2258 { | |
2259 GaimGtkConversation *gtkconv; | |
2260 | |
2261 if (!GAIM_IS_GTK_CONVERSATION(conv)) | |
2262 return; | |
2263 | |
2264 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2265 | |
2266 gtkconv->u.im->animate = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); | |
2267 | |
2268 if (gtkconv->u.im->animate) | |
2269 start_anim(NULL, conv); | |
2270 else | |
2271 stop_anim(NULL, conv); | |
2272 } | |
2273 static void | |
2274 remove_icon(GaimGtkConversation *gtkconv) | |
2275 { | |
2276 g_return_if_fail(gtkconv != NULL); | |
2277 | |
2278 if (gtkconv->u.im->icon != NULL) | |
2279 gtk_container_remove(GTK_CONTAINER(gtkconv->bbox), | |
2280 gtkconv->u.im->icon->parent->parent); | |
2281 | |
2282 if (gtkconv->u.im->anim != NULL) | |
2283 g_object_unref(G_OBJECT(gtkconv->u.im->anim)); | |
2284 | |
2285 if (gtkconv->u.im->icon_timer != 0) | |
2286 g_source_remove(gtkconv->u.im->icon_timer); | |
2287 | |
2288 if (gtkconv->u.im->iter != NULL) | |
2289 g_object_unref(G_OBJECT(gtkconv->u.im->iter)); | |
2290 | |
2291 gtkconv->u.im->icon_timer = 0; | |
2292 gtkconv->u.im->icon = NULL; | |
2293 gtkconv->u.im->anim = NULL; | |
2294 gtkconv->u.im->iter = NULL; | |
2295 } | |
2296 | |
2297 static gboolean | |
2298 icon_menu(GtkObject *obj, GdkEventButton *e, GaimConversation *conv) | |
2299 { | |
2300 GaimGtkConversation *gtkconv; | |
2301 static GtkWidget *menu = NULL; | |
2302 GtkWidget *button; | |
2303 | |
2304 if (e->button != 3 || e->type != GDK_BUTTON_PRESS) | |
2305 return FALSE; | |
2306 | |
2307 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2308 | |
2309 /* | |
2310 * If a menu already exists, destroy it before creating a new one, | |
2311 * thus freeing-up the memory it occupied. | |
2312 */ | |
2313 if (menu != NULL) | |
2314 gtk_widget_destroy(menu); | |
2315 | |
2316 menu = gtk_menu_new(); | |
2317 | |
2318 if (gtkconv->u.im->anim && | |
2319 !(gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim))) | |
2320 { | |
2321 gaim_new_check_item(menu, _("Animate"), | |
2322 G_CALLBACK(toggle_icon_animate_cb), conv, | |
2323 gtkconv->u.im->icon_timer); | |
2324 } | |
2325 | |
2326 button = gtk_menu_item_new_with_label(_("Hide Icon")); | |
2327 g_signal_connect_swapped(G_OBJECT(button), "activate", | |
2328 G_CALLBACK(remove_icon), gtkconv); | |
2329 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); | |
2330 gtk_widget_show(button); | |
2331 | |
2332 gaim_new_item_from_stock(menu, _("Save Icon As..."), GTK_STOCK_SAVE_AS, | |
2333 G_CALLBACK(gaim_gtk_save_icon_dialog), conv, | |
2334 0, 0, NULL); | |
2335 | |
2336 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time); | |
2337 | |
2338 return TRUE; | |
2339 } | |
2340 /************************************************************************** | |
2341 * End of the bunch of buddy icon functions | |
2342 **************************************************************************/ | |
2143 | 2343 |
2144 /* | 2344 /* |
2145 * Makes sure all the menu items and all the buttons are hidden/shown and | 2345 * Makes sure all the menu items and all the buttons are hidden/shown and |
2146 * sensitive/insensitve. This is called after changing tabs and when an | 2346 * sensitive/insensitve. This is called after changing tabs and when an |
2147 * account signs on or off. | 2347 * account signs on or off. |
2352 gtk_window_set_icon(GTK_WINDOW(gtkwin->window), window_icon); | 2552 gtk_window_set_icon(GTK_WINDOW(gtkwin->window), window_icon); |
2353 g_object_unref(G_OBJECT(window_icon)); | 2553 g_object_unref(G_OBJECT(window_icon)); |
2354 } | 2554 } |
2355 | 2555 |
2356 static void | 2556 static void |
2557 before_switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num, | |
2558 gpointer user_data) | |
2559 { | |
2560 GaimConvWindow *win; | |
2561 GaimConversation *conv; | |
2562 GaimGtkConversation *gtkconv; | |
2563 | |
2564 win = (GaimConvWindow *)user_data; | |
2565 conv = gaim_conv_window_get_active_conversation(win); | |
2566 | |
2567 g_return_if_fail(conv != NULL); | |
2568 | |
2569 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
2570 | |
2571 stop_anim(NULL, conv); | |
2572 } | |
2573 | |
2574 static void | |
2357 switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num, | 2575 switch_conv_cb(GtkNotebook *notebook, GtkWidget *page, gint page_num, |
2358 gpointer user_data) | 2576 gpointer user_data) |
2359 { | 2577 { |
2360 GaimConvWindow *win; | 2578 GaimConvWindow *win; |
2361 GaimConversation *conv; | 2579 GaimConversation *conv; |
2384 gtkconv->make_sound); | 2602 gtkconv->make_sound); |
2385 | 2603 |
2386 gtk_check_menu_item_set_active( | 2604 gtk_check_menu_item_set_active( |
2387 GTK_CHECK_MENU_ITEM(gtkwin->menu.show_formatting_toolbar), | 2605 GTK_CHECK_MENU_ITEM(gtkwin->menu.show_formatting_toolbar), |
2388 gtkconv->show_formatting_toolbar); | 2606 gtkconv->show_formatting_toolbar); |
2607 | |
2608 /* | |
2609 * We pause icons when they are not visible. If this icon should | |
2610 * be animated then start it back up again.lll | |
2611 */ | |
2612 if (gtkconv->u.im->animate) | |
2613 start_anim(NULL, conv); | |
2389 | 2614 |
2390 gtk_widget_grab_focus(gtkconv->entry); | 2615 gtk_widget_grab_focus(gtkconv->entry); |
2391 | 2616 |
2392 gtk_window_set_title(GTK_WINDOW(gtkwin->window), | 2617 gtk_window_set_title(GTK_WINDOW(gtkwin->window), |
2393 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); | 2618 gtk_label_get_text(GTK_LABEL(gtkconv->tab_label))); |
4073 gtk_notebook_popup_enable(GTK_NOTEBOOK(gtkwin->notebook)); | 4298 gtk_notebook_popup_enable(GTK_NOTEBOOK(gtkwin->notebook)); |
4074 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gtkwin->notebook), FALSE); | 4299 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(gtkwin->notebook), FALSE); |
4075 | 4300 |
4076 gtk_widget_show(gtkwin->notebook); | 4301 gtk_widget_show(gtkwin->notebook); |
4077 | 4302 |
4303 g_signal_connect(G_OBJECT(gtkwin->notebook), "switch_page", | |
4304 G_CALLBACK(before_switch_conv_cb), win); | |
4078 g_signal_connect_after(G_OBJECT(gtkwin->notebook), "switch_page", | 4305 g_signal_connect_after(G_OBJECT(gtkwin->notebook), "switch_page", |
4079 G_CALLBACK(switch_conv_cb), win); | 4306 G_CALLBACK(switch_conv_cb), win); |
4080 | 4307 |
4081 /* Setup the tab drag and drop signals. */ | 4308 /* Setup the tab drag and drop signals. */ |
4082 gtk_widget_add_events(gtkwin->notebook, | 4309 gtk_widget_add_events(gtkwin->notebook, |
5050 | 5277 |
5051 gtk_label_set_text(GTK_LABEL(gtkchat->count), tmp); | 5278 gtk_label_set_text(GTK_LABEL(gtkchat->count), tmp); |
5052 } | 5279 } |
5053 | 5280 |
5054 static void | 5281 static void |
5055 update_tab_icon(GaimConversation *conv) | |
5056 { | |
5057 GaimGtkConversation *gtkconv; | |
5058 GaimConvWindow *win = gaim_conversation_get_window(conv); | |
5059 GaimAccount *account; | |
5060 const char *name; | |
5061 GdkPixbuf *status = NULL; | |
5062 | |
5063 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
5064 name = gaim_conversation_get_name(conv); | |
5065 account = gaim_conversation_get_account(conv); | |
5066 | |
5067 status = get_tab_icon(conv); | |
5068 | |
5069 gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->icon), status); | |
5070 gtk_image_set_from_pixbuf(GTK_IMAGE(gtkconv->menu_icon), status); | |
5071 | |
5072 if (gaim_conv_window_get_active_conversation(win) == conv && gtkconv->u.im->anim == NULL) | |
5073 gtk_window_set_icon(GTK_WINDOW(GAIM_GTK_WINDOW(win)->window), status); | |
5074 | |
5075 if(status) | |
5076 g_object_unref(status); | |
5077 | |
5078 } | |
5079 | |
5080 static void | |
5081 gaim_gtkconv_updated(GaimConversation *conv, GaimConvUpdateType type) | 5282 gaim_gtkconv_updated(GaimConversation *conv, GaimConvUpdateType type) |
5082 { | 5283 { |
5083 GaimConvWindow *win; | 5284 GaimConvWindow *win; |
5084 GaimGtkWindow *gtkwin; | 5285 GaimGtkWindow *gtkwin; |
5085 GaimGtkConversation *gtkconv; | 5286 GaimGtkConversation *gtkconv; |
5222 } | 5423 } |
5223 | 5424 |
5224 /************************************************************************** | 5425 /************************************************************************** |
5225 * Public conversation utility functions | 5426 * Public conversation utility functions |
5226 **************************************************************************/ | 5427 **************************************************************************/ |
5227 static void | |
5228 remove_icon(GaimGtkConversation *gtkconv) | |
5229 { | |
5230 g_return_if_fail(gtkconv != NULL); | |
5231 | |
5232 if (gtkconv->u.im->icon != NULL) | |
5233 gtk_container_remove(GTK_CONTAINER(gtkconv->bbox), | |
5234 gtkconv->u.im->icon->parent->parent); | |
5235 | |
5236 if (gtkconv->u.im->anim != NULL) | |
5237 g_object_unref(G_OBJECT(gtkconv->u.im->anim)); | |
5238 | |
5239 if (gtkconv->u.im->icon_timer != 0) | |
5240 g_source_remove(gtkconv->u.im->icon_timer); | |
5241 | |
5242 if (gtkconv->u.im->iter != NULL) | |
5243 g_object_unref(G_OBJECT(gtkconv->u.im->iter)); | |
5244 | |
5245 gtkconv->u.im->icon_timer = 0; | |
5246 gtkconv->u.im->icon = NULL; | |
5247 gtkconv->u.im->anim = NULL; | |
5248 gtkconv->u.im->iter = NULL; | |
5249 } | |
5250 | |
5251 static gboolean | |
5252 redraw_icon(gpointer data) | |
5253 { | |
5254 GaimConversation *conv = (GaimConversation *)data; | |
5255 GaimGtkConversation *gtkconv; | |
5256 | |
5257 GdkPixbuf *buf; | |
5258 GdkPixbuf *scale; | |
5259 GdkPixmap *pm; | |
5260 GdkBitmap *bm; | |
5261 gint delay; | |
5262 | |
5263 if (!g_list_find(gaim_get_ims(), conv)) { | |
5264 gaim_debug(GAIM_DEBUG_WARNING, "gtkconv", | |
5265 "Conversation not found in redraw_icon. I think this " | |
5266 "is a bug.\n"); | |
5267 return FALSE; | |
5268 } | |
5269 | |
5270 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
5271 | |
5272 gdk_pixbuf_animation_iter_advance(gtkconv->u.im->iter, NULL); | |
5273 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); | |
5274 | |
5275 scale = gdk_pixbuf_scale_simple(buf, | |
5276 MAX(gdk_pixbuf_get_width(buf) * SCALE(gtkconv->u.im->anim) / | |
5277 gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1), | |
5278 MAX(gdk_pixbuf_get_height(buf) * SCALE(gtkconv->u.im->anim) / | |
5279 gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1), | |
5280 GDK_INTERP_NEAREST); | |
5281 | |
5282 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 100); | |
5283 g_object_unref(G_OBJECT(scale)); | |
5284 gtk_image_set_from_pixmap(GTK_IMAGE(gtkconv->u.im->icon), pm, bm); | |
5285 g_object_unref(G_OBJECT(pm)); | |
5286 gtk_widget_queue_draw(gtkconv->u.im->icon); | |
5287 | |
5288 if (bm) | |
5289 g_object_unref(G_OBJECT(bm)); | |
5290 | |
5291 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter) / 10; | |
5292 | |
5293 gtkconv->u.im->icon_timer = g_timeout_add(delay * 10, redraw_icon, conv); | |
5294 | |
5295 return FALSE; | |
5296 } | |
5297 | |
5298 static void | |
5299 start_anim(GtkObject *obj, GaimConversation *conv) | |
5300 { | |
5301 GaimGtkConversation *gtkconv; | |
5302 int delay; | |
5303 | |
5304 if (!GAIM_IS_GTK_CONVERSATION(conv)) | |
5305 return; | |
5306 | |
5307 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
5308 | |
5309 if (gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim)) | |
5310 return; | |
5311 | |
5312 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter) / 10; | |
5313 | |
5314 if (gtkconv->u.im->anim) | |
5315 gtkconv->u.im->icon_timer = g_timeout_add(delay * 10, redraw_icon, | |
5316 conv); | |
5317 } | |
5318 | |
5319 static void | |
5320 stop_anim(GtkObject *obj, GaimConversation *conv) | |
5321 { | |
5322 GaimGtkConversation *gtkconv; | |
5323 | |
5324 if (!GAIM_IS_GTK_CONVERSATION(conv)) | |
5325 return; | |
5326 | |
5327 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
5328 | |
5329 if (gtkconv->u.im->icon_timer != 0) | |
5330 g_source_remove(gtkconv->u.im->icon_timer); | |
5331 | |
5332 gtkconv->u.im->icon_timer = 0; | |
5333 } | |
5334 | |
5335 static void | |
5336 toggle_icon_animate_cb(GtkWidget *w, GaimConversation *conv) | |
5337 { | |
5338 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))) | |
5339 start_anim(NULL, conv); | |
5340 else | |
5341 stop_anim(NULL, conv); | |
5342 } | |
5343 | |
5344 static gboolean | |
5345 icon_menu(GtkObject *obj, GdkEventButton *e, GaimConversation *conv) | |
5346 { | |
5347 GaimGtkConversation *gtkconv; | |
5348 static GtkWidget *menu = NULL; | |
5349 GtkWidget *button; | |
5350 | |
5351 if (e->button != 3 || e->type != GDK_BUTTON_PRESS) | |
5352 return FALSE; | |
5353 | |
5354 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
5355 | |
5356 /* | |
5357 * If a menu already exists, destroy it before creating a new one, | |
5358 * thus freeing-up the memory it occupied. | |
5359 */ | |
5360 if (menu != NULL) | |
5361 gtk_widget_destroy(menu); | |
5362 | |
5363 menu = gtk_menu_new(); | |
5364 | |
5365 if (gtkconv->u.im->anim && | |
5366 !(gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim))) | |
5367 { | |
5368 gaim_new_check_item(menu, _("Animate"), | |
5369 G_CALLBACK(toggle_icon_animate_cb), conv, | |
5370 gtkconv->u.im->icon_timer); | |
5371 } | |
5372 | |
5373 button = gtk_menu_item_new_with_label(_("Hide Icon")); | |
5374 g_signal_connect_swapped(G_OBJECT(button), "activate", | |
5375 G_CALLBACK(remove_icon), gtkconv); | |
5376 gtk_menu_shell_append(GTK_MENU_SHELL(menu), button); | |
5377 gtk_widget_show(button); | |
5378 | |
5379 gaim_new_item_from_stock(menu, _("Save Icon As..."), GTK_STOCK_SAVE_AS, | |
5380 G_CALLBACK(gaim_gtk_save_icon_dialog), conv, | |
5381 0, 0, NULL); | |
5382 | |
5383 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, e->button, e->time); | |
5384 | |
5385 return TRUE; | |
5386 } | |
5387 | |
5388 void | 5428 void |
5389 gaim_gtkconv_update_buddy_icon(GaimConversation *conv) | 5429 gaim_gtkconv_update_buddy_icon(GaimConversation *conv) |
5390 { | 5430 { |
5391 GaimGtkConversation *gtkconv; | 5431 GaimGtkConversation *gtkconv; |
5392 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(conv)); | 5432 GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(gaim_conversation_get_window(conv)); |
5393 | 5433 |
5394 char filename[256]; | 5434 char filename[256]; |
5395 FILE *file; | 5435 FILE *file; |
5396 GError *err = NULL; | 5436 GError *err = NULL; |
5397 gboolean animate = TRUE; | |
5398 | 5437 |
5399 GaimBuddy *buddy; | 5438 GaimBuddy *buddy; |
5400 | 5439 |
5401 const void *data; | 5440 const void *data; |
5402 size_t len; | 5441 size_t len; |
5403 int delay; | |
5404 | 5442 |
5405 GdkPixbuf *buf; | 5443 GdkPixbuf *buf; |
5406 | 5444 |
5407 GtkWidget *event; | 5445 GtkWidget *event; |
5408 GtkWidget *frame; | 5446 GtkWidget *frame; |
5415 g_return_if_fail(GAIM_IS_GTK_CONVERSATION(conv)); | 5453 g_return_if_fail(GAIM_IS_GTK_CONVERSATION(conv)); |
5416 g_return_if_fail(gaim_conversation_get_type(conv) == GAIM_CONV_IM); | 5454 g_return_if_fail(gaim_conversation_get_type(conv) == GAIM_CONV_IM); |
5417 | 5455 |
5418 gtkconv = GAIM_GTK_CONVERSATION(conv); | 5456 gtkconv = GAIM_GTK_CONVERSATION(conv); |
5419 | 5457 |
5420 if (gtkconv->u.im->icon_timer == 0 && gtkconv->u.im->icon != NULL) | |
5421 animate = FALSE; | |
5422 | |
5423 remove_icon(gtkconv); | 5458 remove_icon(gtkconv); |
5424 | 5459 |
5425 if (!gaim_prefs_get_bool("/gaim/gtk/conversations/im/show_buddy_icons")) | 5460 if (!gaim_prefs_get_bool("/gaim/gtk/conversations/im/show_buddy_icons")) |
5426 return; | 5461 return; |
5427 | 5462 |
5428 if (gaim_conversation_get_gc(conv) == NULL) | 5463 if (gaim_conversation_get_gc(conv) == NULL) |
5429 return; | 5464 return; |
5430 | 5465 |
5431 if(gtkconv->u.im->anim) | 5466 if (gtkconv->u.im->anim) |
5432 g_object_unref(G_OBJECT(gtkconv->u.im->anim)); | 5467 g_object_unref(G_OBJECT(gtkconv->u.im->anim)); |
5468 else | |
5469 gtkconv->u.im->animate = gaim_prefs_get_bool("/gaim/gtk/conversations/im/animate_buddy_icons"); | |
5433 | 5470 |
5434 if((buddy = gaim_find_buddy(gaim_conversation_get_account(conv), | 5471 if((buddy = gaim_find_buddy(gaim_conversation_get_account(conv), |
5435 gaim_conversation_get_name(conv))) != NULL) { | 5472 gaim_conversation_get_name(conv))) != NULL) { |
5436 const char *file; | 5473 const char *file; |
5437 if((file = gaim_blist_node_get_string((GaimBlistNode*)buddy, "buddy_icon"))) | 5474 if((file = gaim_blist_node_get_string((GaimBlistNode*)buddy, "buddy_icon"))) |
5467 gaim_debug(GAIM_DEBUG_ERROR, "gtkconv", | 5504 gaim_debug(GAIM_DEBUG_ERROR, "gtkconv", |
5468 "Buddy icon error: %s\n", err->message); | 5505 "Buddy icon error: %s\n", err->message); |
5469 g_error_free(err); | 5506 g_error_free(err); |
5470 } | 5507 } |
5471 | 5508 |
5472 | |
5473 if (!gtkconv->u.im->anim) | 5509 if (!gtkconv->u.im->anim) |
5474 return; | 5510 return; |
5475 | 5511 |
5476 if(gtkconv->u.im->iter) | 5512 if(gtkconv->u.im->iter) |
5477 g_object_unref(G_OBJECT(gtkconv->u.im->iter)); | 5513 g_object_unref(G_OBJECT(gtkconv->u.im->iter)); |
5478 | 5514 |
5479 if (gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim)) { | 5515 if (gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim)) { |
5480 gtkconv->u.im->iter = NULL; | 5516 gtkconv->u.im->iter = NULL; |
5481 delay = 0; | |
5482 buf = gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); | 5517 buf = gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); |
5483 } else { | 5518 } else { |
5484 gtkconv->u.im->iter = | 5519 gtkconv->u.im->iter = |
5485 gdk_pixbuf_animation_get_iter(gtkconv->u.im->anim, NULL); | 5520 gdk_pixbuf_animation_get_iter(gtkconv->u.im->anim, NULL); |
5486 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); | 5521 buf = gdk_pixbuf_animation_iter_get_pixbuf(gtkconv->u.im->iter); |
5487 delay = gdk_pixbuf_animation_iter_get_delay_time(gtkconv->u.im->iter); | 5522 if (gtkconv->u.im->animate) |
5488 delay = delay / 10; | 5523 start_anim(NULL, conv); |
5489 } | 5524 } |
5490 | 5525 |
5491 sf = SCALE(gtkconv->u.im->anim); | 5526 sf = SCALE(gtkconv->u.im->anim); |
5492 scale = gdk_pixbuf_scale_simple(buf, | 5527 scale = gdk_pixbuf_scale_simple(buf, |
5493 MAX(gdk_pixbuf_get_width(buf) * sf / | 5528 MAX(gdk_pixbuf_get_width(buf) * sf / |
5494 gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1), | 5529 gdk_pixbuf_animation_get_width(gtkconv->u.im->anim), 1), |
5495 MAX(gdk_pixbuf_get_height(buf) * sf / | 5530 MAX(gdk_pixbuf_get_height(buf) * sf / |
5496 gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1), | 5531 gdk_pixbuf_animation_get_height(gtkconv->u.im->anim), 1), |
5497 GDK_INTERP_NEAREST); | 5532 GDK_INTERP_NEAREST); |
5498 | 5533 |
5499 if (delay) | |
5500 gtkconv->u.im->icon_timer = g_timeout_add(delay * 10, redraw_icon, | |
5501 conv); | |
5502 | |
5503 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 100); | 5534 gdk_pixbuf_render_pixmap_and_mask(scale, &pm, &bm, 100); |
5504 g_object_unref(G_OBJECT(scale)); | 5535 g_object_unref(G_OBJECT(scale)); |
5505 | 5536 |
5506 frame = gtk_frame_new(NULL); | 5537 frame = gtk_frame_new(NULL); |
5507 gtk_frame_set_shadow_type(GTK_FRAME(frame), | 5538 gtk_frame_set_shadow_type(GTK_FRAME(frame), |
5519 gtkconv->u.im->icon = gtk_image_new_from_pixmap(pm, bm); | 5550 gtkconv->u.im->icon = gtk_image_new_from_pixmap(pm, bm); |
5520 gtk_widget_set_size_request(gtkconv->u.im->icon, sf, sf); | 5551 gtk_widget_set_size_request(gtkconv->u.im->icon, sf, sf); |
5521 gtk_container_add(GTK_CONTAINER(event), gtkconv->u.im->icon); | 5552 gtk_container_add(GTK_CONTAINER(event), gtkconv->u.im->icon); |
5522 gtk_widget_show(gtkconv->u.im->icon); | 5553 gtk_widget_show(gtkconv->u.im->icon); |
5523 | 5554 |
5524 if (!animate || | |
5525 !gaim_prefs_get_bool("/gaim/gtk/conversations/im/animate_buddy_icons")) { | |
5526 stop_anim(NULL, conv); | |
5527 } | |
5528 | |
5529 g_object_unref(G_OBJECT(pm)); | 5555 g_object_unref(G_OBJECT(pm)); |
5530 | 5556 |
5531 if (bm) | 5557 if (bm) |
5532 g_object_unref(G_OBJECT(bm)); | 5558 g_object_unref(G_OBJECT(bm)); |
5533 | 5559 |
5534 /* The buddy icon code needs badly to be fixed. */ | 5560 /* The buddy icon code needs badly to be fixed. */ |
5535 buf = gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); | 5561 buf = gdk_pixbuf_animation_get_static_image(gtkconv->u.im->anim); |
5536 if(conv == gaim_conv_window_get_active_conversation(gaim_conversation_get_window(conv))) | 5562 if(conv == gaim_conv_window_get_active_conversation(gaim_conversation_get_window(conv))) |
5537 gtk_window_set_icon(GTK_WINDOW(gtkwin->window), buf); | 5563 gtk_window_set_icon(GTK_WINDOW(gtkwin->window), buf); |
5538 } | |
5539 | |
5540 void | |
5541 gaim_gtkconv_update_font_buttons(void) | |
5542 { | |
5543 GList *l; | |
5544 GaimConversation *conv; | |
5545 GaimGtkConversation *gtkconv; | |
5546 | |
5547 for (l = gaim_get_ims(); l != NULL; l = l->next) { | |
5548 conv = (GaimConversation *)l->data; | |
5549 | |
5550 if (!GAIM_IS_GTK_CONVERSATION(conv)) | |
5551 continue; | |
5552 | |
5553 gtkconv = GAIM_GTK_CONVERSATION(conv); | |
5554 | |
5555 if (gtkconv->toolbar.bold != NULL) | |
5556 gtk_widget_set_sensitive(gtkconv->toolbar.bold, | |
5557 !gaim_prefs_get_bool("/gaim/gtk/conversations/send_bold")); | |
5558 | |
5559 if (gtkconv->toolbar.italic != NULL) | |
5560 gtk_widget_set_sensitive(gtkconv->toolbar.italic, | |
5561 !gaim_prefs_get_bool("/gaim/gtk/conversations/send_italic")); | |
5562 | |
5563 if (gtkconv->toolbar.underline != NULL) | |
5564 gtk_widget_set_sensitive(gtkconv->toolbar.underline, | |
5565 !gaim_prefs_get_bool("/gaim/gtk/conversations/send_underline")); | |
5566 } | |
5567 } | 5564 } |
5568 | 5565 |
5569 void | 5566 void |
5570 gaim_gtkconv_update_font_colors(GaimConversation *conv) | 5567 gaim_gtkconv_update_font_colors(GaimConversation *conv) |
5571 { | 5568 { |
5975 static void | 5972 static void |
5976 animate_buddy_icons_pref_cb(const char *name, GaimPrefType type, | 5973 animate_buddy_icons_pref_cb(const char *name, GaimPrefType type, |
5977 gpointer value, gpointer data) | 5974 gpointer value, gpointer data) |
5978 { | 5975 { |
5979 GList *l; | 5976 GList *l; |
5977 GaimConversation *conv; | |
5978 GaimGtkConversation *gtkconv; | |
5979 GaimConvWindow *win; | |
5980 | 5980 |
5981 if (!gaim_prefs_get_bool("/gaim/gtk/conversations/im/show_buddy_icons")) | 5981 if (!gaim_prefs_get_bool("/gaim/gtk/conversations/im/show_buddy_icons")) |
5982 return; | 5982 return; |
5983 | 5983 |
5984 if (value) { | 5984 /* Set the "animate" flag for each icon based on the new preference */ |
5985 for (l = gaim_get_ims(); l != NULL; l = l->next) | 5985 for (l = gaim_get_ims(); l != NULL; l = l->next) { |
5986 start_anim(NULL, (GaimConversation *)l->data); | 5986 conv = (GaimConversation *)l->data; |
5987 } | 5987 gtkconv = GAIM_GTK_CONVERSATION(conv); |
5988 else { | 5988 gtkconv->u.im->animate = (gboolean)value; |
5989 for (l = gaim_get_ims(); l != NULL; l = l->next) | 5989 } |
5990 stop_anim(NULL, (GaimConversation *)l->data); | 5990 |
5991 /* Now either stop or start animation for the active conversation in each window */ | |
5992 for (l = gaim_get_windows(); l != NULL; l = l->next) { | |
5993 win = (GaimConvWindow *)l->data; | |
5994 conv = gaim_conv_window_get_active_conversation(win); | |
5995 gaim_gtkconv_update_buddy_icon(conv); | |
5991 } | 5996 } |
5992 } | 5997 } |
5993 | 5998 |
5994 static void | 5999 static void |
5995 show_buddy_icons_pref_cb(const char *name, GaimPrefType type, gpointer value, | 6000 show_buddy_icons_pref_cb(const char *name, GaimPrefType type, gpointer value, |