Mercurial > pidgin
comparison src/gtkstatusselector.c @ 10347:4d2ecbb139a0
[gaim-migrate @ 11561]
This now works on < GTK 2.4
committer: Tailor Script <tailor@pidgin.im>
author | Tim Ringenbach <marv@pidgin.im> |
---|---|
date | Sun, 12 Dec 2004 18:20:17 +0000 |
parents | ec140184437b |
children | 5879593a6a10 |
comparison
equal
deleted
inserted
replaced
10346:bbf738a0ce7b | 10347:4d2ecbb139a0 |
---|---|
36 { | 36 { |
37 GtkWidget *combo; | 37 GtkWidget *combo; |
38 GtkWidget *entry; | 38 GtkWidget *entry; |
39 GtkWidget *frame; | 39 GtkWidget *frame; |
40 | 40 |
41 GtkWidget *optmenu; | |
42 GtkWidget *menu; | |
43 GtkSizeGroup *sg; | |
44 | |
41 GtkListStore *model; | 45 GtkListStore *model; |
42 | 46 |
43 guint entry_timer; | 47 guint entry_timer; |
44 }; | 48 }; |
45 | 49 |
49 COLUMN_ICON, | 53 COLUMN_ICON, |
50 COLUMN_NAME, | 54 COLUMN_NAME, |
51 NUM_COLUMNS | 55 NUM_COLUMNS |
52 }; | 56 }; |
53 | 57 |
58 #define GAIM_SELECTOR_TEXT "gaim-text" | |
59 #define GAIM_SELECTOR_STATUS_TYPE_ID "gaim-status-type-id" | |
60 | |
54 static void gaim_gtk_status_selector_class_init(GaimGtkStatusSelectorClass *klass); | 61 static void gaim_gtk_status_selector_class_init(GaimGtkStatusSelectorClass *klass); |
55 static void gaim_gtk_status_selector_init(GaimGtkStatusSelector *selector); | 62 static void gaim_gtk_status_selector_init(GaimGtkStatusSelector *selector); |
56 static void gaim_gtk_status_selector_finalize(GObject *obj); | 63 static void gaim_gtk_status_selector_finalize(GObject *obj); |
57 static void gaim_gtk_status_selector_destroy(GtkObject *obj); | 64 static void gaim_gtk_status_selector_destroy(GtkObject *obj); |
58 #if GTK_CHECK_VERSION (2,4,0) | |
59 static void status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector); | 65 static void status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector); |
60 static gboolean key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer user_data); | 66 static gboolean key_press_cb(GtkWidget *entry, GdkEventKey *event, gpointer user_data); |
61 static void signed_on_off_cb(GaimConnection *gc, GaimGtkStatusSelector *selector); | 67 static void signed_on_off_cb(GaimConnection *gc, GaimGtkStatusSelector *selector); |
62 #endif | |
63 static void rebuild_list(GaimGtkStatusSelector *selector); | 68 static void rebuild_list(GaimGtkStatusSelector *selector); |
64 | 69 |
65 static GtkVBox *parent_class = NULL; | 70 static GtkVBox *parent_class = NULL; |
66 | 71 |
67 GType | 72 GType |
110 static void | 115 static void |
111 gaim_gtk_status_selector_init(GaimGtkStatusSelector *selector) | 116 gaim_gtk_status_selector_init(GaimGtkStatusSelector *selector) |
112 { | 117 { |
113 #if GTK_CHECK_VERSION(2,4,0) | 118 #if GTK_CHECK_VERSION(2,4,0) |
114 GtkWidget *combo; | 119 GtkWidget *combo; |
120 GtkCellRenderer *renderer; | |
121 #else | |
122 GtkWidget *optmenu; | |
123 #endif | |
115 GtkWidget *entry; | 124 GtkWidget *entry; |
116 GtkWidget *toolbar; | 125 GtkWidget *toolbar; |
117 GtkWidget *frame; | 126 GtkWidget *frame; |
118 GtkCellRenderer *renderer; | |
119 #endif | |
120 | 127 |
121 selector->priv = g_new0(GaimGtkStatusSelectorPrivate, 1); | 128 selector->priv = g_new0(GaimGtkStatusSelectorPrivate, 1); |
122 | 129 |
123 #if GTK_CHECK_VERSION(2,4,0) | 130 #if GTK_CHECK_VERSION(2,4,0) |
124 selector->priv->model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_POINTER, | 131 selector->priv->model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_POINTER, |
125 GDK_TYPE_PIXBUF, G_TYPE_STRING); | 132 GDK_TYPE_PIXBUF, G_TYPE_STRING); |
126 | 133 |
127 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(selector->priv->model)); | 134 combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(selector->priv->model)); |
128 selector->priv->combo = combo; | 135 selector->priv->combo = combo; |
129 | 136 |
130 g_object_unref(G_OBJECT(selector->priv->model)); | 137 g_object_unref(G_OBJECT(selector->priv->model)); |
147 /* TODO */ | 154 /* TODO */ |
148 | 155 |
149 | 156 |
150 gtk_widget_show(combo); | 157 gtk_widget_show(combo); |
151 gtk_box_pack_start(GTK_BOX(selector), combo, FALSE, FALSE, 0); | 158 gtk_box_pack_start(GTK_BOX(selector), combo, FALSE, FALSE, 0); |
159 | |
160 | |
161 #else /* GTK < 2.4.0 */ | |
162 selector->priv->optmenu = optmenu = gtk_option_menu_new(); | |
163 gtk_widget_show(optmenu); | |
164 | |
165 selector->priv->menu = gtk_menu_new(); | |
166 gtk_widget_show(selector->priv->menu); | |
167 gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), selector->priv->menu); | |
168 | |
169 selector->priv->sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); | |
170 | |
171 g_signal_connect(G_OBJECT(optmenu), "changed", | |
172 G_CALLBACK(status_switched_cb), selector); | |
173 | |
174 gtk_box_pack_start(GTK_BOX(selector), optmenu, FALSE, FALSE, 0); | |
175 #endif | |
152 | 176 |
153 frame = gaim_gtk_create_imhtml(TRUE, &entry, &toolbar); | 177 frame = gaim_gtk_create_imhtml(TRUE, &entry, &toolbar); |
154 selector->priv->entry = entry; | 178 selector->priv->entry = entry; |
155 selector->priv->frame = frame; | 179 selector->priv->frame = frame; |
156 gtk_widget_set_name(entry, "gaim_gtkstatusselector_imhtml"); | 180 gtk_widget_set_name(entry, "gaim_gtkstatusselector_imhtml"); |
157 gtk_box_pack_start(GTK_BOX(selector), frame, TRUE, TRUE, 0); | 181 gtk_box_pack_start(GTK_BOX(selector), frame, TRUE, TRUE, 0); |
158 gtk_widget_hide(toolbar); | 182 gtk_widget_hide(toolbar); |
159 | 183 |
160 g_signal_connect(G_OBJECT(entry), "key_press_event", | 184 g_signal_connect(G_OBJECT(entry), "key_press_event", |
161 G_CALLBACK(key_press_cb), selector); | 185 G_CALLBACK(key_press_cb), selector); |
162 | 186 |
163 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", | 187 gaim_signal_connect(gaim_connections_get_handle(), "signed-on", |
164 selector, GAIM_CALLBACK(signed_on_off_cb), | 188 selector, GAIM_CALLBACK(signed_on_off_cb), |
165 selector); | 189 selector); |
166 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", | 190 gaim_signal_connect(gaim_connections_get_handle(), "signed-off", |
167 selector, GAIM_CALLBACK(signed_on_off_cb), | 191 selector, GAIM_CALLBACK(signed_on_off_cb), |
168 selector); | 192 selector); |
169 | 193 |
170 rebuild_list(selector); | 194 rebuild_list(selector); |
171 #endif /* GTK < 2.4.0 */ | |
172 } | 195 } |
173 | 196 |
174 static void | 197 static void |
175 gaim_gtk_status_selector_finalize(GObject *obj) | 198 gaim_gtk_status_selector_finalize(GObject *obj) |
176 { | 199 { |
178 | 201 |
179 g_return_if_fail(obj != NULL); | 202 g_return_if_fail(obj != NULL); |
180 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(obj)); | 203 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(obj)); |
181 | 204 |
182 selector = GAIM_GTK_STATUS_SELECTOR(obj); | 205 selector = GAIM_GTK_STATUS_SELECTOR(obj); |
206 | |
207 if (selector->priv->sg) { | |
208 g_object_unref(selector->priv->sg); | |
209 selector->priv->sg = NULL; | |
210 } | |
183 | 211 |
184 g_free(selector->priv); | 212 g_free(selector->priv); |
185 | 213 |
186 if (G_OBJECT_CLASS(parent_class)->finalize) | 214 if (G_OBJECT_CLASS(parent_class)->finalize) |
187 G_OBJECT_CLASS(parent_class)->finalize(obj); | 215 G_OBJECT_CLASS(parent_class)->finalize(obj); |
203 | 231 |
204 if (GTK_OBJECT_CLASS(parent_class)->destroy) | 232 if (GTK_OBJECT_CLASS(parent_class)->destroy) |
205 GTK_OBJECT_CLASS(parent_class)->destroy(obj); | 233 GTK_OBJECT_CLASS(parent_class)->destroy(obj); |
206 } | 234 } |
207 | 235 |
236 static gboolean | |
237 get_selected_data(GaimGtkStatusSelector *selector, const char **text, const char **status_type_id) | |
238 { | |
208 #if GTK_CHECK_VERSION(2,4,0) | 239 #if GTK_CHECK_VERSION(2,4,0) |
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 return FALSE; | |
264 } | |
265 | |
209 static void | 266 static void |
210 status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector) | 267 status_switched_cb(GtkWidget *combo, GaimGtkStatusSelector *selector) |
211 { | 268 { |
212 GtkTreeIter iter; | 269 const char *status_type_id = NULL; |
213 const char *status_type_id; | 270 const char *text = NULL; |
214 const char *text; | 271 |
215 | 272 if (!get_selected_data(selector, &text, &status_type_id)) |
216 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(selector->priv->combo), | |
217 &iter)) | |
218 { | |
219 return; | 273 return; |
220 } | |
221 | |
222 gtk_tree_model_get(GTK_TREE_MODEL(selector->priv->model), &iter, | |
223 COLUMN_NAME, &text, | |
224 COLUMN_STATUS_TYPE_ID, &status_type_id, | |
225 -1); | |
226 | 274 |
227 if (status_type_id == NULL) | 275 if (status_type_id == NULL) |
228 { | 276 { |
229 if (!strcmp(text, _("New Status"))) | 277 if (!strcmp(text, _("New Status"))) |
230 { | 278 { |
278 } | 326 } |
279 else | 327 else |
280 gtk_widget_hide(selector->priv->frame); | 328 gtk_widget_hide(selector->priv->frame); |
281 } | 329 } |
282 } | 330 } |
283 #endif | |
284 | 331 |
285 static gboolean | 332 static gboolean |
286 insert_text_timeout_cb(gpointer data) | 333 insert_text_timeout_cb(gpointer data) |
287 { | 334 { |
288 #if GTK_CHECK_VERSION(2,4,0) | |
289 GaimGtkStatusSelector *selector = (GaimGtkStatusSelector *)data; | 335 GaimGtkStatusSelector *selector = (GaimGtkStatusSelector *)data; |
290 GtkTreeIter iter; | |
291 const char *status_type_id; | 336 const char *status_type_id; |
292 const char *text; | 337 const char *text; |
293 | 338 |
294 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(selector->priv->combo), | 339 if (!get_selected_data(selector, &text, &status_type_id)) |
295 &iter)) | |
296 { | |
297 return FALSE; | 340 return FALSE; |
298 } | |
299 | |
300 gtk_tree_model_get(GTK_TREE_MODEL(selector->priv->model), &iter, | |
301 COLUMN_NAME, &text, | |
302 COLUMN_STATUS_TYPE_ID, &status_type_id, | |
303 -1); | |
304 | 341 |
305 if (status_type_id == NULL) | 342 if (status_type_id == NULL) |
306 { | 343 { |
307 if (!strcmp(text, _("New Status"))) | 344 if (!strcmp(text, _("New Status"))) |
308 { | 345 { |
321 GaimConnection *gc = (GaimConnection *)l->data; | 358 GaimConnection *gc = (GaimConnection *)l->data; |
322 GaimAccount *account = gaim_connection_get_account(gc); | 359 GaimAccount *account = gaim_connection_get_account(gc); |
323 GaimStatusType *status_type; | 360 GaimStatusType *status_type; |
324 | 361 |
325 status_type = gaim_account_get_status_type(account, | 362 status_type = gaim_account_get_status_type(account, |
326 status_type_id); | 363 status_type_id); |
327 | 364 |
328 if (status_type == NULL) | 365 if (status_type == NULL) |
329 continue; | 366 continue; |
330 | 367 |
331 if (gaim_status_type_get_attr(status_type, "message") != NULL) | 368 if (gaim_status_type_get_attr(status_type, "message") != NULL) |
332 { | 369 { |
333 gaim_account_set_status(account, | 370 gaim_account_set_status(account, |
334 status_type_id, TRUE, | 371 status_type_id, TRUE, |
335 "message", message, | 372 "message", message, |
336 NULL); | 373 NULL); |
337 } | 374 } |
338 } | 375 } |
339 } | 376 } |
340 #endif | |
341 | 377 |
342 return FALSE; | 378 return FALSE; |
343 } | 379 } |
344 | 380 |
345 /** | 381 /** |
405 | 441 |
406 static void | 442 static void |
407 add_item(GaimGtkStatusSelector *selector, const char *status_type_id, | 443 add_item(GaimGtkStatusSelector *selector, const char *status_type_id, |
408 const char *text, GdkPixbuf *pixbuf) | 444 const char *text, GdkPixbuf *pixbuf) |
409 { | 445 { |
446 #if GTK_CHECK_VERSION(2,4,0) | |
410 GtkTreeIter iter; | 447 GtkTreeIter iter; |
411 | 448 |
412 gtk_list_store_append(selector->priv->model, &iter); | 449 gtk_list_store_append(selector->priv->model, &iter); |
413 gtk_list_store_set(selector->priv->model, &iter, | 450 gtk_list_store_set(selector->priv->model, &iter, |
414 COLUMN_STATUS_TYPE_ID, status_type_id, | 451 COLUMN_STATUS_TYPE_ID, status_type_id, |
415 COLUMN_ICON, pixbuf, | 452 COLUMN_ICON, pixbuf, |
416 COLUMN_NAME, text, | 453 COLUMN_NAME, text, |
417 -1); | 454 -1); |
455 #else | |
456 GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); | |
457 GtkWidget *item, *hbox, *label; | |
458 | |
459 /* Create the item. */ | |
460 item = gtk_menu_item_new(); | |
461 | |
462 /* Create the hbox. */ | |
463 hbox = gtk_hbox_new(FALSE, 4); | |
464 gtk_container_add(GTK_CONTAINER(item), hbox); | |
465 gtk_widget_show(hbox); | |
466 | |
467 gtk_size_group_add_widget(selector->priv->sg, image); | |
468 | |
469 gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 0); | |
470 gtk_widget_show(image); | |
471 | |
472 /* Create the label. */ | |
473 label = gtk_label_new(text); | |
474 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); | |
475 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
476 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); | |
477 gtk_widget_show(label); | |
478 | |
479 g_object_set_data_full(G_OBJECT(item), GAIM_SELECTOR_TEXT, g_strdup(text), g_free); | |
480 g_object_set_data_full(G_OBJECT(item), GAIM_SELECTOR_STATUS_TYPE_ID, g_strdup(status_type_id), g_free); | |
481 | |
482 gtk_menu_shell_append(GTK_MENU_SHELL(selector->priv->menu), item); | |
483 gtk_widget_show(item); | |
484 gaim_set_accessible_label(item, label); | |
485 #endif | |
418 | 486 |
419 if (pixbuf != NULL) | 487 if (pixbuf != NULL) |
420 g_object_unref(G_OBJECT(pixbuf)); | 488 g_object_unref(G_OBJECT(pixbuf)); |
421 } | 489 } |
490 | |
422 | 491 |
423 static void | 492 static void |
424 rebuild_list(GaimGtkStatusSelector *selector) | 493 rebuild_list(GaimGtkStatusSelector *selector) |
425 { | 494 { |
426 gboolean single_prpl = TRUE; | 495 gboolean single_prpl = TRUE; |
429 GList *l; | 498 GList *l; |
430 | 499 |
431 g_return_if_fail(selector != NULL); | 500 g_return_if_fail(selector != NULL); |
432 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(selector)); | 501 g_return_if_fail(GAIM_GTK_IS_STATUS_SELECTOR(selector)); |
433 | 502 |
503 #if GTK_CHECK_VERSION(2,4,0) | |
434 gtk_list_store_clear(selector->priv->model); | 504 gtk_list_store_clear(selector->priv->model); |
505 #else | |
506 gtk_option_menu_remove_menu(GTK_OPTION_MENU(selector->priv->optmenu)); | |
507 /* XXX this automaticly destroys the menu, right? */ | |
508 selector->priv->menu = gtk_menu_new(); | |
509 gtk_widget_show(selector->priv->menu); | |
510 #endif | |
435 | 511 |
436 /* | 512 /* |
437 * If the user only has one IM account or one type of IM account | 513 * If the user only has one IM account or one type of IM account |
438 * connected, they'll see all their statuses. This is ideal for those | 514 * connected, they'll see all their statuses. This is ideal for those |
439 * who use only one account, or one single protocol. Everyone else | 515 * who use only one account, or one single protocol. Everyone else |
493 } | 569 } |
494 | 570 |
495 /* TODO: Add saved statuses here? */ | 571 /* TODO: Add saved statuses here? */ |
496 | 572 |
497 add_item(selector, NULL, _("New Status"), | 573 add_item(selector, NULL, _("New Status"), |
498 gtk_widget_render_icon(GTK_WIDGET(selector), GTK_STOCK_NEW, | 574 gtk_widget_render_icon(GTK_WIDGET(selector), GTK_STOCK_NEW, |
499 GTK_ICON_SIZE_MENU, NULL)); | 575 GTK_ICON_SIZE_MENU, NULL)); |
576 #if !GTK_CHECK_VERSION(2,4,0) | |
577 gtk_option_menu_set_menu(GTK_OPTION_MENU(selector->priv->optmenu), selector->priv->menu); | |
578 #endif | |
500 } | 579 } |
501 | 580 |
502 GtkWidget * | 581 GtkWidget * |
503 gaim_gtk_status_selector_new(void) | 582 gaim_gtk_status_selector_new(void) |
504 { | 583 { |