gtk/plugins/ticker/ticker.c

branch
cpw.khc.msnp14
changeset 20472
6a6d2ef151e6
parent 13151
e6f06eacea11
parent 14253
b63ebf84c42b
equal deleted inserted replaced
13912:463b4fa9f067 20472:6a6d2ef151e6
1 /*
2 * Gaim Ticker Plugin
3 * The line below doesn't apply at all, does it? It should be Syd, Sean, and
4 * maybe Nathan, I believe.
5 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23 /*
24 * ticker.c -- Syd Logan, Summer 2000
25 * pluginized- Sean Egan, Summer 2002
26 */
27 #include "internal.h"
28 #include "gtkgaim.h"
29
30 #include "blist.h"
31 #include "conversation.h"
32 #include "debug.h"
33 #include "prpl.h"
34 #include "signals.h"
35 #include "version.h"
36
37 #include "gtkblist.h"
38 #include "gtkplugin.h"
39
40 #include "gtkticker.h"
41
42 #define TICKER_PLUGIN_ID "gtk-ticker"
43
44 static GtkWidget *tickerwindow = NULL;
45 static GtkWidget *ticker;
46
47 typedef struct {
48 GaimContact *contact;
49 GtkWidget *ebox;
50 GtkWidget *label;
51 GtkWidget *icon;
52 guint timeout;
53 } TickerData;
54
55 GList *tickerbuds = NULL;
56
57 static void buddy_ticker_update_contact(GaimContact *contact);
58
59 static gboolean buddy_ticker_destroy_window(GtkWidget *window,
60 GdkEventAny *event, gpointer data) {
61 if(window)
62 gtk_widget_hide(window);
63
64 return TRUE; /* don't actually destroy the window */
65 }
66
67 static void buddy_ticker_create_window() {
68 if(tickerwindow) {
69 gtk_widget_show(tickerwindow);
70 return;
71 }
72
73 tickerwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
74 gtk_window_set_default_size(GTK_WINDOW(tickerwindow), 500, -1);
75 g_signal_connect(G_OBJECT(tickerwindow), "delete_event",
76 G_CALLBACK (buddy_ticker_destroy_window), NULL);
77 gtk_window_set_title (GTK_WINDOW(tickerwindow), _("Buddy Ticker"));
78 gtk_window_set_role (GTK_WINDOW(tickerwindow), "ticker");
79
80 ticker = gtk_ticker_new();
81 gtk_ticker_set_spacing(GTK_TICKER(ticker), 20);
82 gtk_container_add(GTK_CONTAINER(tickerwindow), ticker);
83 gtk_ticker_set_interval(GTK_TICKER(ticker), 500);
84 gtk_ticker_set_scootch(GTK_TICKER(ticker), 10);
85 gtk_ticker_start_scroll(GTK_TICKER(ticker));
86 gtk_widget_set_size_request(ticker, 1, -1);
87
88 gtk_widget_show_all(tickerwindow);
89 }
90
91 static gboolean buddy_click_cb(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
92 GaimContact *contact = user_data;
93 GaimBuddy *b = gaim_contact_get_priority_buddy(contact);
94
95 gaim_conversation_new(GAIM_CONV_TYPE_IM, b->account, b->name);
96 return TRUE;
97 }
98
99 static TickerData *buddy_ticker_find_contact(GaimContact *c) {
100 GList *tb;
101 for(tb = tickerbuds; tb; tb = tb->next) {
102 TickerData *td = tb->data;
103 if(td->contact == c)
104 return td;
105 }
106 return NULL;
107 }
108
109 static void buddy_ticker_set_pixmap(GaimContact *c) {
110 TickerData *td = buddy_ticker_find_contact(c);
111 GdkPixbuf *pixbuf;
112
113 if(!td)
114 return;
115
116 if(!td->icon)
117 td->icon = gtk_image_new();
118
119 pixbuf = gaim_gtk_blist_get_status_icon((GaimBlistNode*)c,
120 GAIM_STATUS_ICON_SMALL);
121 gtk_image_set_from_pixbuf(GTK_IMAGE(td->icon), pixbuf);
122 g_object_unref(G_OBJECT(pixbuf));
123 }
124
125 static gboolean buddy_ticker_set_pixmap_cb(gpointer data) {
126 TickerData *td = data;
127
128 buddy_ticker_update_contact(td->contact);
129 td->timeout = 0;
130
131 return FALSE;
132 }
133
134 static void buddy_ticker_add_buddy(GaimBuddy *b) {
135 GtkWidget *hbox;
136 TickerData *td;
137 GaimContact *contact;
138
139 contact = gaim_buddy_get_contact(b);
140
141 buddy_ticker_create_window();
142
143 if (!ticker)
144 return;
145
146 if (buddy_ticker_find_contact(contact))
147 {
148 buddy_ticker_update_contact(contact);
149 return;
150 }
151
152 td = g_new0(TickerData, 1);
153 td->contact = contact;
154 tickerbuds = g_list_append(tickerbuds, td);
155
156 td->ebox = gtk_event_box_new();
157 gtk_ticker_add(GTK_TICKER(ticker), td->ebox);
158 hbox = gtk_hbox_new(FALSE, 0);
159 gtk_container_add(GTK_CONTAINER(td->ebox), hbox);
160 buddy_ticker_set_pixmap(contact);
161 gtk_box_pack_start(GTK_BOX(hbox), td->icon, FALSE, FALSE, 0);
162
163 g_signal_connect(G_OBJECT(td->ebox), "button-press-event",
164 G_CALLBACK(buddy_click_cb), contact);
165
166 td->label = gtk_label_new(gaim_contact_get_alias(contact));
167 gtk_box_pack_start(GTK_BOX(hbox), td->label, FALSE, FALSE, 2);
168
169 gtk_widget_show_all(td->ebox);
170 gtk_widget_show(tickerwindow);
171
172 /*
173 * Update the icon in a few seconds (after the open door icon has
174 * changed). This is somewhat ugly.
175 */
176 td->timeout = g_timeout_add(11000, buddy_ticker_set_pixmap_cb, td);
177 }
178
179 static void buddy_ticker_remove(TickerData *td) {
180 gtk_ticker_remove(GTK_TICKER(ticker), td->ebox);
181 tickerbuds = g_list_remove(tickerbuds, td);
182 if (td->timeout != 0)
183 g_source_remove(td->timeout);
184 g_free(td);
185 }
186
187 static void buddy_ticker_update_contact(GaimContact *contact) {
188 TickerData *td = buddy_ticker_find_contact(contact);
189
190 if (!td)
191 return;
192
193 /* pop up the ticker window again */
194 buddy_ticker_create_window();
195 if (gaim_contact_get_priority_buddy(contact) == NULL)
196 buddy_ticker_remove(td);
197 else {
198 buddy_ticker_set_pixmap(contact);
199 gtk_label_set_text(GTK_LABEL(td->label), gaim_contact_get_alias(contact));
200 }
201 }
202
203 static void buddy_ticker_remove_buddy(GaimBuddy *b) {
204 GaimContact *c = gaim_buddy_get_contact(b);
205 TickerData *td = buddy_ticker_find_contact(c);
206
207 if (!td)
208 return;
209
210 gaim_contact_invalidate_priority_buddy(c);
211
212 /* pop up the ticker window again */
213 buddy_ticker_create_window();
214 buddy_ticker_update_contact(c);
215 }
216
217 static void buddy_ticker_show()
218 {
219 GaimBuddyList *list = gaim_get_blist();
220 GaimBlistNode *gnode, *cnode, *bnode;
221 GaimBuddy *b;
222
223 if(!list)
224 return;
225
226 for(gnode = list->root; gnode; gnode = gnode->next) {
227 if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
228 continue;
229 for(cnode = gnode->child; cnode; cnode = cnode->next) {
230 if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
231 continue;
232 for(bnode = cnode->child; bnode; bnode = bnode->next) {
233 if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
234 continue;
235 b = (GaimBuddy *)bnode;
236 if(GAIM_BUDDY_IS_ONLINE(b))
237 buddy_ticker_add_buddy(b);
238 }
239 }
240 }
241 }
242
243 static void
244 buddy_signon_cb(GaimBuddy *b)
245 {
246 GaimContact *c = gaim_buddy_get_contact(b);
247 gaim_contact_invalidate_priority_buddy(c);
248 if(buddy_ticker_find_contact(c))
249 buddy_ticker_update_contact(c);
250 else
251 buddy_ticker_add_buddy(b);
252 }
253
254 static void
255 buddy_signoff_cb(GaimBuddy *b)
256 {
257 buddy_ticker_remove_buddy(b);
258 if(!tickerbuds)
259 gtk_widget_hide(tickerwindow);
260 }
261
262 static void
263 status_changed_cb(GaimBuddy *b, GaimStatus *os, GaimStatus *s)
264 {
265 GaimContact *c = gaim_buddy_get_contact(b);
266 if(buddy_ticker_find_contact(c))
267 buddy_ticker_set_pixmap(c);
268 else
269 buddy_ticker_add_buddy(b);
270 }
271
272 static void
273 signoff_cb(GaimConnection *gc)
274 {
275 TickerData *td;
276 if (!gaim_connections_get_all()) {
277 while (tickerbuds) {
278 td = tickerbuds->data;
279 tickerbuds = g_list_delete_link(tickerbuds, tickerbuds);
280 if (td->timeout != 0)
281 g_source_remove(td->timeout);
282 g_free(td);
283 }
284 gtk_widget_destroy(tickerwindow);
285 tickerwindow = NULL;
286 ticker = NULL;
287 } else {
288 GList *t = tickerbuds;
289 while (t) {
290 td = t->data;
291 t = t->next;
292 buddy_ticker_update_contact(td->contact);
293 }
294 }
295 }
296
297
298 /*
299 * EXPORTED FUNCTIONS
300 */
301
302 static gboolean
303 plugin_load(GaimPlugin *plugin)
304 {
305 void *blist_handle = gaim_blist_get_handle();
306
307 gaim_signal_connect(gaim_connections_get_handle(), "signed-off",
308 plugin, GAIM_CALLBACK(signoff_cb), NULL);
309 gaim_signal_connect(blist_handle, "buddy-signed-on",
310 plugin, GAIM_CALLBACK(buddy_signon_cb), NULL);
311 gaim_signal_connect(blist_handle, "buddy-signed-off",
312 plugin, GAIM_CALLBACK(buddy_signoff_cb), NULL);
313 gaim_signal_connect(blist_handle, "buddy-status-changed",
314 plugin, GAIM_CALLBACK(status_changed_cb), NULL);
315
316 if (gaim_connections_get_all())
317 buddy_ticker_show();
318
319 return TRUE;
320 }
321
322 static gboolean
323 plugin_unload(GaimPlugin *plugin)
324 {
325 TickerData *td;
326
327 while (tickerbuds) {
328 td = tickerbuds->data;
329 tickerbuds = g_list_delete_link(tickerbuds, tickerbuds);
330 if (td->timeout != 0)
331 g_source_remove(td->timeout);
332 g_free(td);
333 }
334
335 if (tickerwindow != NULL) {
336 gtk_widget_destroy(tickerwindow);
337 tickerwindow = NULL;
338 }
339
340 return TRUE;
341 }
342
343 static GaimPluginInfo info =
344 {
345 GAIM_PLUGIN_MAGIC,
346 GAIM_MAJOR_VERSION,
347 GAIM_MINOR_VERSION,
348 GAIM_PLUGIN_STANDARD, /**< type */
349 GAIM_GTK_PLUGIN_TYPE, /**< ui_requirement */
350 0, /**< flags */
351 NULL, /**< dependencies */
352 GAIM_PRIORITY_DEFAULT, /**< priority */
353
354 TICKER_PLUGIN_ID, /**< id */
355 N_("Buddy Ticker"), /**< name */
356 VERSION, /**< version */
357 /** summary */
358 N_("A horizontal scrolling version of the buddy list."),
359 /** description */
360 N_("A horizontal scrolling version of the buddy list."),
361 "Syd Logan", /**< author */
362 GAIM_WEBSITE, /**< homepage */
363
364 plugin_load, /**< load */
365 plugin_unload, /**< unload */
366 NULL, /**< destroy */
367
368 NULL, /**< ui_info */
369 NULL, /**< extra_info */
370 NULL,
371 NULL
372 };
373
374 static void
375 init_plugin(GaimPlugin *plugin)
376 {
377 }
378
379 GAIM_INIT_PLUGIN(ticker, init_plugin, info)

mercurial