Mercurial > pidgin
annotate src/gtkstatusselector.c @ 10475:94fd0bf8c4b1
[gaim-migrate @ 11762]
sf patch #1094341, from Richard Laager
implements sf rfe #1090971
"tracks when a buddy was last seen and displays this value in the
tooltip for offline and "signing on" buddies."
The changes for this feature were pretty small and self-contained,
and it's a neat feature.
Then I started changing other things. I changed the way tooltips are
created to use GStrings. I think it's easier to make changes without
screwing stuff up, and the code is hopefully a bit easier to read through.
I also changed how Add a Chat and Join a Chat work slightly. Now
PRPLs can specify if a field is required or not, and the dialogs
will not allow the user to click on "ok" if the field is not filled
in. For example, when joining an oscar chat, the room name MUST be
specified.
This change and I think something else minor should fix the problem with
adding chats to the buddy list that didn't have names.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Wed, 05 Jan 2005 05:52:10 +0000 |
parents | 6d4f02da1cef |
children | 58ab47ed31bf |
rev | line source |
---|---|
10178 | 1 /** |
10297
ec140184437b
[gaim-migrate @ 11480]
Luke Schierer <lschiere@pidgin.im>
parents:
10249
diff
changeset
|
2 * @file gtkstatusselector.c GTK+ Status selector widget |
10178 | 3 * @ingroup gtkui |
4 * | |
5 * gaim | |
6 * | |
7 * Gaim is the legal property of its developers, whose names are too numerous | |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
25 #include "internal.h" | |
26 #include "gtkgaim.h" | |
27 #include "gtkimhtml.h" | |
10447 | 28 #include "gtksavedstatuses.h" |
10178 | 29 #include "gtkstatusselector.h" |
30 #include "gtkutils.h" | |
31 | |
32 #include "account.h" | |
33 #include "debug.h" | |
34 #include "prefs.h" | |
35 | |
36 struct _GaimGtkStatusSelectorPrivate | |
37 { | |
38 GtkWidget *combo; | |
39 GtkWidget *entry; | |
10191 | 40 GtkWidget *frame; |
10178 | 41 |
10347 | 42 GtkWidget *optmenu; |
43 GtkWidget *menu; | |
44 GtkSizeGroup *sg; | |
45 | |
10178 | 46 GtkListStore *model; |
10199 | 47 |
48 guint entry_timer; | |
10178 | 49 }; |
50 | |
51 enum | |
52 { | |
53 COLUMN_STATUS_TYPE_ID, | |
54 COLUMN_ICON, | |
55 COLUMN_NAME, | |
56 NUM_COLUMNS | |
57 }; | |
58 | |
10347 | 59 #define GAIM_SELECTOR_TEXT "gaim-text" |
60 #define GAIM_SELECTOR_STATUS_TYPE_ID "gaim-status-type-id" | |
61 | |
10178 | 62 static void gaim_gtk_status_selector_class_init(GaimGtkStatusSelectorClass *klass); |
63 static void gaim_gtk_status_selector_init(GaimGtkStatusSelector *selector); | |
64 static void gaim_gtk_status_selector_finalize(GObject *obj); | |
65 static void gaim_gtk_status_selector_destroy(GtkObject *obj); | |
66 static void status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector); | |
10199 | 67 static gboolean key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer user_data); |
10178 | 68 static void signed_on_off_cb(GaimConnection *gc, GaimGtkStatusSelector *selector); |
69 static void rebuild_list(GaimGtkStatusSelector *selector); | |
70 | |
71 static GtkVBox *parent_class = NULL; | |
72 | |
73 GType | |
74 gaim_gtk_status_selector_get_type(void) | |
75 { | |
76 static GType type = 0; | |
77 | |
78 if (!type) | |
79 { | |
80 static const GTypeInfo info = | |
81 { | |
82 sizeof(GaimGtkStatusSelectorClass), | |
83 NULL, | |
84 NULL, | |
85 (GClassInitFunc)gaim_gtk_status_selector_class_init, | |
86 NULL, | |
87 NULL, | |
88 sizeof(GaimGtkStatusSelector), | |
89 0, | |
90 (GInstanceInitFunc)gaim_gtk_status_selector_init | |
91 }; | |
92 | |
93 type = g_type_register_static(GTK_TYPE_VBOX, | |
94 "GaimGtkStatusSelector", &info, 0); | |
95 } | |
96 | |
97 return type; | |
98 } | |
99 | |
100 static void | |
101 gaim_gtk_status_selector_class_init(GaimGtkStatusSelectorClass *klass) | |
102 { | |
103 GObjectClass *gobject_class; | |
104 GtkObjectClass *object_class; | |
105 | |
106 parent_class = g_type_class_peek_parent(klass); | |
107 | |
108 gobject_class = G_OBJECT_CLASS(klass); | |
109 object_class = GTK_OBJECT_CLASS(klass); | |
110 | |
111 gobject_class->finalize = gaim_gtk_status_selector_finalize; | |
112 | |
113 object_class->destroy = gaim_gtk_status_selector_destroy; | |
114 } | |
115 | |
116 static void | |
117 gaim_gtk_status_selector_init(GaimGtkStatusSelector *selector) | |
118 { | |
10225 | 119 #if GTK_CHECK_VERSION(2,4,0) |
10178 | 120 GtkWidget *combo; |
10347 | 121 GtkCellRenderer *renderer; |
122 #else | |
123 GtkWidget *optmenu; | |
124 #endif | |
10178 | 125 GtkWidget *entry; |
10191 | 126 GtkWidget *toolbar; |
127 GtkWidget *frame; | |
10178 | 128 |
129 selector->priv = g_new0(GaimGtkStatusSelectorPrivate, 1); | |
130 | |
131 #if GTK_CHECK_VERSION(2,4,0) | |
132 selector->priv->model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_POINTER, | |
10347 | 133 GDK_TYPE_PIXBUF, G_TYPE_STRING); |
10178 | 134 |
135 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(selector->priv->model)); | |
136 selector->priv->combo = combo; | |
137 | |
138 g_object_unref(G_OBJECT(selector->priv->model)); | |
139 | |
140 renderer = gtk_cell_renderer_pixbuf_new(); | |
141 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, FALSE); | |
142 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, | |
143 "pixbuf", COLUMN_ICON, | |
144 NULL); | |
145 | |
146 renderer = gtk_cell_renderer_text_new(); | |
147 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE); | |
148 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, | |
149 "text", COLUMN_NAME, | |
150 NULL); | |
151 | |
152 g_signal_connect(G_OBJECT(combo), "changed", | |
153 G_CALLBACK(status_switched_cb), selector); | |
154 | |
155 /* TODO */ | |
156 | |
157 | |
158 gtk_widget_show(combo); | |
159 gtk_box_pack_start(GTK_BOX(selector), combo, FALSE, FALSE, 0); | |
160 | |
10347 | 161 |
162 #else /* GTK < 2.4.0 */ | |
163 selector->priv->optmenu = optmenu = gtk_option_menu_new(); | |
164 gtk_widget_show(optmenu); | |
165 | |
166 selector->priv->menu = gtk_menu_new(); | |
167 gtk_widget_show(selector->priv->menu); | |
168 gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), selector->priv->menu); | |
169 | |
170 selector->priv->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
171 | |
172 g_signal_connect(G_OBJECT(optmenu), "changed", | |
173 G_CALLBACK(status_switched_cb), selector); | |
174 | |
175 gtk_box_pack_start(GTK_BOX(selector), optmenu, FALSE, FALSE, 0); | |
176 #endif | |
177 | |
10191 | 178 frame = gaim_gtk_create_imhtml(TRUE, &entry, &toolbar); |
179 selector->priv->entry = entry; | |
180 selector->priv->frame = frame; | |
181 gtk_widget_set_name(entry, "gaim_gtkstatusselector_imhtml"); | |
182 gtk_box_pack_start(GTK_BOX(selector), frame, TRUE, TRUE, 0); | |
183 gtk_widget_hide(toolbar); | |
10178 | 184 |
10199 | 185 g_signal_connect(G_OBJECT(entry), "key_press_event", |
10347 | 186 G_CALLBACK(key_press_cb), selector); |
10178 | 187 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", |
10347 | 188 selector, GAIM_CALLBACK(signed_on_off_cb), |
189 selector); | |
10178 | 190 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", |
10347 | 191 selector, GAIM_CALLBACK(signed_on_off_cb), |
192 selector); | |
10404 | 193 |
10178 | 194 rebuild_list(selector); |
195 } | |
196 | |
197 static void | |
198 gaim_gtk_status_selector_finalize(GObject *obj) | |
199 { | |
200 GaimGtkStatusSelector *selector; | |
201 | |
202 g_return_if_fail(obj != NULL); | |
203 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(obj)); | |
204 | |
205 selector = GAIM_GTK_STATUS_SELECTOR(obj); | |
206 | |
10347 | 207 if (selector->priv->sg) { |
208 g_object_unref(selector->priv->sg); | |
209 selector->priv->sg = NULL; | |
210 } | |
211 | |
10178 | 212 g_free(selector->priv); |
213 | |
214 if (G_OBJECT_CLASS(parent_class)->finalize) | |
215 G_OBJECT_CLASS(parent_class)->finalize(obj); | |
216 } | |
217 | |
218 static void | |
219 gaim_gtk_status_selector_destroy(GtkObject *obj) | |
220 { | |
221 GaimGtkStatusSelector *selector; | |
222 | |
223 g_return_if_fail(obj != NULL); | |
224 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(obj)); | |
225 | |
226 selector = GAIM_GTK_STATUS_SELECTOR(obj); | |
227 | |
10187 | 228 gaim_signals_disconnect_by_handle(selector); |
10249 | 229 if (selector->priv->entry_timer != 0) |
230 gaim_timeout_remove(selector->priv->entry_timer); | |
10187 | 231 |
10178 | 232 if (GTK_OBJECT_CLASS(parent_class)->destroy) |
233 GTK_OBJECT_CLASS(parent_class)->destroy(obj); | |
234 } | |
235 | |
10347 | 236 static gboolean |
237 get_selected_data(GaimGtkStatusSelector *selector, const char **text, const char **status_type_id) | |
238 { | |
10225 | 239 #if GTK_CHECK_VERSION(2,4,0) |
10347 | 240 GtkTreeIter iter; |
241 | |
242 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(selector->priv->combo), | |
243 &iter)) | |
244 return FALSE; | |
245 | |
246 gtk_tree_model_get(GTK_TREE_MODEL(selector->priv->model), &iter, | |
247 COLUMN_NAME, text, | |
248 COLUMN_STATUS_TYPE_ID, status_type_id, | |
249 -1); | |
250 return TRUE; | |
251 #else | |
252 GtkWidget *item; | |
253 int i; | |
254 GList *l; | |
255 | |
256 i = gtk_option_menu_get_history(GTK_OPTION_MENU(selector->priv->optmenu)); | |
257 l = GTK_MENU_SHELL(selector->priv->menu)->children; | |
258 item = g_list_nth_data(l, i); | |
259 *text = g_object_get_data(G_OBJECT(item), GAIM_SELECTOR_TEXT); | |
260 *status_type_id = g_object_get_data(G_OBJECT(item), GAIM_SELECTOR_STATUS_TYPE_ID); | |
261 return TRUE; | |
262 #endif | |
263 } | |
264 | |
10447 | 265 /* |
10455 | 266 * TODO: Is it possible to remove of the duplication in this |
267 * function and insert_text_timeout_cb()? | |
10447 | 268 */ |
10178 | 269 static void |
270 status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector) | |
271 { | |
10347 | 272 const char *status_type_id = NULL; |
273 const char *text = NULL; | |
10178 | 274 |
10455 | 275 /* Reset the status selector */ |
276 if (selector->priv->entry_timer != 0) | |
277 gaim_timeout_remove(selector->priv->entry_timer); | |
278 gtk_widget_hide(selector->priv->frame); | |
279 gtk_widget_set_sensitive(selector->priv->frame, FALSE); | |
280 | |
10347 | 281 if (!get_selected_data(selector, &text, &status_type_id)) |
10188 | 282 return; |
10178 | 283 |
10191 | 284 if (status_type_id == NULL) |
285 { | |
286 if (!strcmp(text, _("New Status"))) | |
287 { | |
10447 | 288 gaim_gtk_status_editor_show(NULL); |
10191 | 289 } |
290 } | |
10197 | 291 else |
10188 | 292 { |
10199 | 293 /* |
294 * If the chosen status does not require a message, then set the | |
295 * status immediately. Otherwise just register a timeout and the | |
296 * status will be set whenever the user stops typing the message. | |
297 */ | |
298 GList *l; | |
10188 | 299 GtkTextBuffer *buffer; |
10455 | 300 gboolean has_message = FALSE; |
10178 | 301 |
10188 | 302 buffer = |
303 gtk_text_view_get_buffer(GTK_TEXT_VIEW(selector->priv->entry)); | |
304 | |
10199 | 305 gtk_text_buffer_set_text(buffer, text, -1); |
306 | |
10400 | 307 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) |
10199 | 308 { |
10400 | 309 GaimAccount *account = (GaimAccount*)l->data; |
10199 | 310 GaimStatusType *status_type; |
10404 | 311 |
10400 | 312 if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) |
313 continue; | |
10199 | 314 |
10455 | 315 status_type = gaim_account_get_status_type(account, status_type_id); |
10199 | 316 |
317 if (status_type == NULL) | |
318 continue; | |
319 | |
320 if (gaim_status_type_get_attr(status_type, "message") != NULL) | |
321 { | |
10455 | 322 has_message = TRUE; |
10199 | 323 } |
324 else | |
325 { | |
10455 | 326 gaim_account_set_status(account, status_type_id, TRUE, NULL); |
10199 | 327 } |
328 } | |
329 | |
10455 | 330 if (has_message) |
10199 | 331 { |
332 gtk_widget_show(selector->priv->frame); | |
10455 | 333 gtk_widget_set_sensitive(selector->priv->frame, TRUE); |
10199 | 334 key_press_cb(NULL, NULL, selector); |
335 } | |
336 } | |
337 } | |
338 | |
10455 | 339 /** |
340 * This is used to set the message of the selected status. It | |
341 * is triggered after the user has stopped typing in the little box. | |
342 * It just goes through and, if the selected status type for any | |
343 * given online/enabled account requires a message, then it sets | |
344 * that status with the entered message. | |
345 */ | |
10199 | 346 static gboolean |
347 insert_text_timeout_cb(gpointer data) | |
348 { | |
349 GaimGtkStatusSelector *selector = (GaimGtkStatusSelector *)data; | |
350 const char *status_type_id; | |
351 const char *text; | |
10455 | 352 gchar *message; |
353 GList *l; | |
354 | |
355 gtk_widget_set_sensitive(selector->priv->frame, FALSE); | |
10199 | 356 |
10347 | 357 if (!get_selected_data(selector, &text, &status_type_id)) |
10199 | 358 return FALSE; |
359 | |
360 if (status_type_id == NULL) | |
10455 | 361 return FALSE; |
362 | |
363 message = gtk_imhtml_get_markup(GTK_IMHTML(selector->priv->entry)); | |
364 | |
365 for (l = gaim_accounts_get_all(); l != NULL; l = l->next) | |
10199 | 366 { |
10455 | 367 GaimAccount *account = (GaimAccount*)l->data; |
368 GaimStatusType *status_type; | |
369 | |
370 if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) | |
371 continue; | |
10199 | 372 |
10455 | 373 status_type = gaim_account_get_status_type(account, |
374 status_type_id); | |
10188 | 375 |
10455 | 376 if (status_type == NULL) |
377 continue; | |
378 | |
379 if (gaim_status_type_get_attr(status_type, "message") != NULL) | |
10178 | 380 { |
10455 | 381 gaim_account_set_status(account, |
382 status_type_id, TRUE, | |
383 "message", message, | |
384 NULL); | |
10188 | 385 } |
10199 | 386 } |
10178 | 387 |
10199 | 388 return FALSE; |
389 } | |
390 | |
391 /** | |
392 * The user typed in the IMHTML entry widget. If the user is finished | |
393 * typing then we want to set the appropriate status message. So let's | |
394 * wait 3 seconds, and if they haven't typed anything else then set the | |
395 * status message. | |
396 */ | |
397 static gboolean | |
398 key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer user_data) | |
399 { | |
400 GaimGtkStatusSelector *selector = (GaimGtkStatusSelector *)user_data; | |
401 | |
402 if (selector->priv->entry_timer != 0) { | |
403 gaim_timeout_remove(selector->priv->entry_timer); | |
10178 | 404 } |
10199 | 405 |
10455 | 406 selector->priv->entry_timer = gaim_timeout_add(3000, |
407 insert_text_timeout_cb, | |
408 selector); | |
10199 | 409 |
410 return FALSE; | |
10178 | 411 } |
412 | |
413 static void | |
414 signed_on_off_cb(GaimConnection *gc, GaimGtkStatusSelector *selector) | |
415 { | |
416 rebuild_list(selector); | |
417 } | |
418 | |
419 static GdkPixbuf * | |
420 load_icon(const char *basename) | |
421 { | |
422 char *filename; | |
423 GdkPixbuf *pixbuf, *scale = NULL; | |
424 | |
425 if (!strcmp(basename, "available.png")) | |
426 basename = "online.png"; | |
427 else if (!strcmp(basename, "hidden.png")) | |
428 basename = "invisible.png"; | |
429 | |
430 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "icons", | |
431 basename, NULL); | |
432 pixbuf = gdk_pixbuf_new_from_file(filename, NULL); | |
433 g_free(filename); | |
434 | |
435 if (pixbuf != NULL) | |
436 { | |
437 scale = gdk_pixbuf_scale_simple(pixbuf, 16, 16, | |
438 GDK_INTERP_BILINEAR); | |
439 | |
440 g_object_unref(G_OBJECT(pixbuf)); | |
441 } | |
442 else | |
443 { | |
444 filename = g_build_filename(DATADIR, "pixmaps", "gaim", "status", | |
445 "default", basename, NULL); | |
446 scale = gdk_pixbuf_new_from_file(filename, NULL); | |
447 g_free(filename); | |
448 } | |
449 | |
450 return scale; | |
451 } | |
452 | |
453 static void | |
454 add_item(GaimGtkStatusSelector *selector, const char *status_type_id, | |
455 const char *text, GdkPixbuf *pixbuf) | |
456 { | |
10347 | 457 #if GTK_CHECK_VERSION(2,4,0) |
10178 | 458 GtkTreeIter iter; |
459 | |
460 gtk_list_store_append(selector->priv->model, &iter); | |
461 gtk_list_store_set(selector->priv->model, &iter, | |
462 COLUMN_STATUS_TYPE_ID, status_type_id, | |
463 COLUMN_ICON, pixbuf, | |
464 COLUMN_NAME, text, | |
465 -1); | |
10347 | 466 #else |
467 GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); | |
468 GtkWidget *item, *hbox, *label; | |
469 | |
470 /* Create the item. */ | |
471 item = gtk_menu_item_new(); | |
472 | |
473 /* Create the hbox. */ | |
474 hbox = gtk_hbox_new(FALSE, 4); | |
475 gtk_container_add(GTK_CONTAINER(item), hbox); | |
476 gtk_widget_show(hbox); | |
477 | |
478 gtk_size_group_add_widget(selector->priv->sg, image); | |
479 | |
480 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); | |
481 gtk_widget_show(image); | |
482 | |
483 /* Create the label. */ | |
484 label = gtk_label_new(text); | |
485 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); | |
486 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
487 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); | |
488 gtk_widget_show(label); | |
489 | |
490 g_object_set_data_full(G_OBJECT(item), GAIM_SELECTOR_TEXT, g_strdup(text), g_free); | |
491 g_object_set_data_full(G_OBJECT(item), GAIM_SELECTOR_STATUS_TYPE_ID, g_strdup(status_type_id), g_free); | |
492 | |
493 gtk_menu_shell_append(GTK_MENU_SHELL(selector->priv->menu), item); | |
494 gtk_widget_show(item); | |
495 gaim_set_accessible_label(item, label); | |
496 #endif | |
10178 | 497 |
498 if (pixbuf != NULL) | |
499 g_object_unref(G_OBJECT(pixbuf)); | |
500 } | |
501 | |
10347 | 502 |
10178 | 503 static void |
504 rebuild_list(GaimGtkStatusSelector *selector) | |
505 { | |
506 gboolean single_prpl = TRUE; | |
10400 | 507 GList *accounts; |
508 gboolean enabled = FALSE; | |
10178 | 509 GaimAccount *first_account = NULL; |
510 const char *first_prpl_type = NULL; | |
511 GList *l; | |
512 | |
513 g_return_if_fail(selector != NULL); | |
514 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(selector)); | |
515 | |
10347 | 516 #if GTK_CHECK_VERSION(2,4,0) |
10178 | 517 gtk_list_store_clear(selector->priv->model); |
10347 | 518 #else |
519 gtk_option_menu_remove_menu(GTK_OPTION_MENU(selector->priv->optmenu)); | |
520 /* XXX this automaticly destroys the menu, right? */ | |
521 selector->priv->menu = gtk_menu_new(); | |
522 gtk_widget_show(selector->priv->menu); | |
523 #endif | |
10178 | 524 |
525 /* | |
10400 | 526 * If no accounts are enabled then gray ourself out and get |
10352 | 527 * outta hee. |
528 */ | |
10447 | 529 for (accounts = gaim_accounts_get_all(); accounts != NULL; |
530 accounts = accounts->next) | |
531 { | |
10400 | 532 GaimAccount *a = accounts->data; |
10447 | 533 if (gaim_account_get_enabled(a, GAIM_GTK_UI)) |
534 { | |
10400 | 535 enabled = TRUE; |
536 break; | |
537 } | |
538 } | |
10447 | 539 |
10400 | 540 if (enabled == FALSE) |
10352 | 541 { |
542 gtk_widget_set_sensitive(GTK_WIDGET(selector), FALSE); | |
543 return; | |
544 } | |
545 gtk_widget_set_sensitive(GTK_WIDGET(selector), TRUE); | |
546 | |
547 /* | |
10178 | 548 * If the user only has one IM account or one type of IM account |
549 * connected, they'll see all their statuses. This is ideal for those | |
550 * who use only one account, or one single protocol. Everyone else | |
551 * gets Available and Away and a list of saved statuses. | |
552 */ | |
10400 | 553 for (l = gaim_accounts_get_all(); l != NULL && single_prpl; l = l->next) |
10178 | 554 { |
10400 | 555 GaimAccount *account = l->data; |
10178 | 556 GaimPluginProtocolInfo *prpl_info; |
10400 | 557 GaimPlugin *plugin; |
10178 | 558 const char *basename; |
559 | |
10400 | 560 if (!gaim_account_get_enabled(account, GAIM_GTK_UI)) |
561 continue; | |
562 | |
563 plugin = gaim_find_prpl(account->protocol_id); | |
564 if (!plugin) | |
565 continue; | |
566 | |
567 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | |
10178 | 568 basename = prpl_info->list_icon(account, NULL); |
569 | |
570 if (first_prpl_type == NULL) | |
571 { | |
572 first_prpl_type = basename; | |
573 first_account = account; | |
574 } | |
10179
97ee3bf7bcf7
[gaim-migrate @ 11294]
Christian Hammond <chipx86@chipx86.com>
parents:
10178
diff
changeset
|
575 else if (strcmp(first_prpl_type, basename)) |
10178 | 576 single_prpl = FALSE; |
577 } | |
578 | |
579 if (single_prpl) | |
580 { | |
581 const GList *l; | |
582 | |
583 for (l = gaim_account_get_status_types(first_account); | |
584 l != NULL; | |
585 l = l->next) | |
586 { | |
587 GaimStatusType *status_type = (GaimStatusType *)l->data; | |
588 char filename[BUFSIZ]; | |
589 | |
590 if (!gaim_status_type_is_user_settable(status_type)) | |
591 continue; | |
592 | |
10207 | 593 /* |
10447 | 594 * TODO: Find a way to fallback to the GaimStatusPrimitive |
10207 | 595 * if an icon for this id does not exist. |
596 */ | |
10178 | 597 g_snprintf(filename, sizeof(filename), "%s.png", |
598 gaim_status_type_get_id(status_type)); | |
599 | |
600 add_item(selector, | |
601 gaim_status_type_get_id(status_type), | |
602 gaim_status_type_get_name(status_type), | |
603 load_icon(filename)); | |
604 } | |
605 } | |
606 else | |
607 { | |
10447 | 608 /* TODO: Add "online" and "offline" here? */ |
10178 | 609 add_item(selector, "available", _("Available"), |
610 load_icon("online.png")); | |
611 add_item(selector, "away", _("Away"), load_icon("away.png")); | |
612 } | |
613 | |
10191 | 614 /* TODO: Add saved statuses here? */ |
615 | |
10178 | 616 add_item(selector, NULL, _("New Status"), |
10347 | 617 gtk_widget_render_icon(GTK_WIDGET(selector), GTK_STOCK_NEW, |
618 GTK_ICON_SIZE_MENU, NULL)); | |
619 #if !GTK_CHECK_VERSION(2,4,0) | |
620 gtk_option_menu_set_menu(GTK_OPTION_MENU(selector->priv->optmenu), selector->priv->menu); | |
621 #endif | |
10178 | 622 } |
623 | |
624 GtkWidget * | |
625 gaim_gtk_status_selector_new(void) | |
626 { | |
627 GaimGtkStatusSelector *selector; | |
628 | |
629 selector = g_object_new(GAIM_GTK_TYPE_STATUS_SELECTOR, NULL); | |
630 | |
631 return GTK_WIDGET(selector); | |
632 } |