Mercurial > pidgin
comparison src/gtkstatusbox.c @ 13050:fb607b2d4ff2
[gaim-migrate @ 15411]
Some fixes and documentation. I'm not sure if we were escaping everything
correctly after my changes last night, but it's definitely working
correctly now.
Selecting a saved status with a message will not show the imhtml. Instead
it'll show the title and the first part of the message directly on the
status box. That seemed like a good idea to me.
Selecting one of the 4 basic transient statuses (available, away, invisible,
offline) with no substatuses will make the status box show the primtive
and open the imhtml.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Fri, 27 Jan 2006 06:40:38 +0000 |
parents | 704dc95d0198 |
children | 1ef760c65174 |
comparison
equal
deleted
inserted
replaced
13049:97fa7332b034 | 13050:fb607b2d4ff2 |
---|---|
396 */ | 396 */ |
397 static void | 397 static void |
398 update_to_reflect_current_status(GtkGaimStatusBox *status_box) | 398 update_to_reflect_current_status(GtkGaimStatusBox *status_box) |
399 { | 399 { |
400 GaimSavedStatus *saved_status; | 400 GaimSavedStatus *saved_status; |
401 GaimStatusPrimitive primitive; | |
401 gint index; | 402 gint index; |
402 const char *message; | 403 const char *message; |
403 GList *list; | 404 GList *list; |
404 | 405 |
405 /* this function is inappropriate for ones with accounts */ | 406 /* this function is inappropriate for ones with accounts */ |
412 * Suppress the "changed" signal because the status | 413 * Suppress the "changed" signal because the status |
413 * was changed programmatically. | 414 * was changed programmatically. |
414 */ | 415 */ |
415 gtk_widget_set_sensitive(GTK_WIDGET(status_box), FALSE); | 416 gtk_widget_set_sensitive(GTK_WIDGET(status_box), FALSE); |
416 | 417 |
417 list = gaim_savedstatuses_get_popular(6); | 418 /* |
418 if ((index = g_list_index(list, saved_status)) > -1) | 419 * If the saved_status is transient, is Available, Away, Invisible |
419 index += 5; | 420 * or Offline, and it does not have an substatuses, then select |
421 * the primitive in the dropdown menu. Otherwise select the | |
422 * popular status in the dropdown menu. | |
423 */ | |
424 primitive = gaim_savedstatus_get_type(saved_status); | |
425 if (gaim_savedstatus_is_transient(saved_status) && | |
426 ((primitive == GAIM_STATUS_AVAILABLE) || (primitive == GAIM_STATUS_AWAY) || | |
427 (primitive == GAIM_STATUS_INVISIBLE) || (primitive == GAIM_STATUS_OFFLINE)) && | |
428 (!gaim_savedstatus_has_substatuses(saved_status))) | |
429 { | |
430 index = get_statusbox_index(status_box, saved_status); | |
431 } | |
420 else | 432 else |
421 { | 433 { |
422 if (gaim_savedstatus_has_substatuses(saved_status)) | 434 /* |
423 index = GTK_LIST_STORE(status_box->dropdown_store)->length - 2; | 435 * TODO: This code is really bad. We need to look at the DATA |
436 * column of the saved statuses, instead. | |
437 */ | |
438 list = gaim_savedstatuses_get_popular(6); | |
439 if ((index = g_list_index(list, saved_status)) > -1) | |
440 index += 5; /* Skip over the primitives and a spacer that may or may not exist! (Fix this) */ | |
424 else | 441 else |
425 { | 442 index = 0; /* TODO: Need to do something better here */ |
426 index = get_statusbox_index(status_box, saved_status); | 443 g_list_free(list); |
427 } | 444 } |
428 } | 445 |
429 g_list_free(list); | |
430 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), index); | 446 gtk_combo_box_set_active(GTK_COMBO_BOX(status_box), index); |
431 | 447 |
432 message = gaim_savedstatus_get_message(saved_status); | 448 message = gaim_savedstatus_get_message(saved_status); |
433 if (!message || !*message) | 449 if (!gaim_savedstatus_is_transient(saved_status) || !message || !*message) |
434 { | 450 { |
435 status_box->imhtml_visible = FALSE; | 451 status_box->imhtml_visible = FALSE; |
436 gtk_widget_hide_all(status_box->vbox); | 452 gtk_widget_hide_all(status_box->vbox); |
437 } | 453 } |
438 else | 454 else |
461 static void | 477 static void |
462 add_popular_statuses(GtkGaimStatusBox *statusbox) | 478 add_popular_statuses(GtkGaimStatusBox *statusbox) |
463 { | 479 { |
464 GList *list, *cur; | 480 GList *list, *cur; |
465 GtkIconSize icon_size; | 481 GtkIconSize icon_size; |
466 GdkPixbuf *away_pix, *avl_pix, *pixbuf; | 482 GdkPixbuf *pixbuf, *emblem, *scale; |
467 | 483 |
468 list = gaim_savedstatuses_get_popular(6); | 484 list = gaim_savedstatuses_get_popular(6); |
469 if (list == NULL) | 485 if (list == NULL) |
470 /* Odd... oh well, nothing we can do about it. */ | 486 /* Odd... oh well, nothing we can do about it. */ |
471 return; | 487 return; |
473 if (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) | 489 if (gaim_prefs_get_bool("/gaim/gtk/blist/show_buddy_icons")) |
474 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS); | 490 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS); |
475 else | 491 else |
476 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS_SMALL); | 492 icon_size = gtk_icon_size_from_name(GAIM_ICON_SIZE_STATUS_SMALL); |
477 | 493 |
478 away_pix = gtk_widget_render_icon(GTK_WIDGET(statusbox->vbox), GAIM_STOCK_STATUS_AWAY, | 494 /* Create the icon to use for non-transient saved-statuses */ |
479 icon_size, "GtkGaimStatusBox"); | 495 pixbuf = gtk_widget_render_icon(GTK_WIDGET(statusbox->vbox), |
480 avl_pix = gtk_widget_render_icon(GTK_WIDGET(statusbox->vbox), GAIM_STOCK_STATUS_ONLINE, | 496 GAIM_STOCK_STATUS_ONLINE, icon_size, "GtkGaimStatusBox"); |
481 icon_size, "GtkGaimStatusBox"); | 497 scale = gdk_pixbuf_scale_simple(pixbuf, 32, 32, GDK_INTERP_BILINEAR); |
498 g_object_unref(G_OBJECT(pixbuf)); | |
499 pixbuf = scale; | |
500 | |
501 emblem = gtk_widget_render_icon(GTK_WIDGET(statusbox->vbox), | |
502 GTK_STOCK_SAVE, icon_size, "GtkGaimStatusBox"); | |
503 scale = gdk_pixbuf_scale_simple(emblem, 15, 15, GDK_INTERP_BILINEAR); | |
504 g_object_unref(G_OBJECT(emblem)); | |
505 emblem = scale; | |
506 | |
507 gdk_pixbuf_composite(emblem, pixbuf, 32-15, 32-15, 15, 15, 17, 17, 1, 1, | |
508 GDK_INTERP_BILINEAR, 255); | |
509 g_object_unref(G_OBJECT(emblem)); | |
482 | 510 |
483 gtk_gaim_status_box_add_separator(statusbox); | 511 gtk_gaim_status_box_add_separator(statusbox); |
484 | 512 |
485 for (cur = list; cur != NULL; cur = cur->next) | 513 for (cur = list; cur != NULL; cur = cur->next) |
486 { | 514 { |
487 GaimSavedStatus *saved = cur->data; | 515 GaimSavedStatus *saved = cur->data; |
488 | 516 const gchar *message; |
489 switch (gaim_savedstatus_get_type(saved)) | 517 gchar *stripped; |
490 { | 518 |
491 case GAIM_STATUS_AVAILABLE: | 519 /* TODO: For transient saved-statuses, make a new icon showing the primitive */ |
492 pixbuf = avl_pix; | 520 |
493 break; | 521 if (gaim_savedstatus_is_transient(saved)) |
494 default: | 522 { |
495 pixbuf = away_pix; | 523 /* |
496 break; | 524 * Transient statuses do not have a title, so the savedstatus |
525 * API returns the message when gaim_savedstatus_get_title() is | |
526 * called, so we don't need to get the message a second time. | |
527 */ | |
528 stripped = NULL; | |
529 } | |
530 else | |
531 { | |
532 message = gaim_savedstatus_get_message(saved); | |
533 stripped = gaim_markup_strip_html(message); | |
534 gaim_util_chrreplace(stripped, '\n', ' '); | |
497 } | 535 } |
498 gtk_gaim_status_box_add(statusbox, GTK_GAIM_STATUS_BOX_TYPE_POPULAR, | 536 gtk_gaim_status_box_add(statusbox, GTK_GAIM_STATUS_BOX_TYPE_POPULAR, |
499 pixbuf, gaim_savedstatus_get_title(saved), NULL, | 537 pixbuf, gaim_savedstatus_get_title(saved), stripped, |
500 GINT_TO_POINTER(gaim_savedstatus_get_creation_time(saved))); | 538 GINT_TO_POINTER(gaim_savedstatus_get_creation_time(saved))); |
539 g_free(stripped); | |
501 } | 540 } |
502 | 541 |
503 g_list_free(list); | 542 g_list_free(list); |
504 } | 543 } |
505 | 544 |
937 gtk_gaim_status_box_new_with_account(GaimAccount *account) | 976 gtk_gaim_status_box_new_with_account(GaimAccount *account) |
938 { | 977 { |
939 return g_object_new(GTK_GAIM_TYPE_STATUS_BOX, "account", account, NULL); | 978 return g_object_new(GTK_GAIM_TYPE_STATUS_BOX, "account", account, NULL); |
940 } | 979 } |
941 | 980 |
981 /** | |
982 * Add a row to the dropdown menu. | |
983 * | |
984 * @param status_box The status box itself. | |
985 * @param type A GtkGaimStatusBoxItemType. | |
986 * @param pixbuf The icon to associate with this row in the menu. | |
987 * @param title The title of this item. For the primitive entries, | |
988 * this is something like "Available" or "Away." For | |
989 * the saved statuses, this is something like | |
990 * "My favorite away message!" This should be | |
991 * plaintext (non-markedup) (this function escapes it). | |
992 * @param desc The secondary text for this item. This will be | |
993 * placed on the row below the title, in a dimmer | |
994 * font (generally gray). This text should be plaintext | |
995 * (non-markedup) (this function escapes it). | |
996 * @param data Data to be associated with this row in the dropdown | |
997 * menu. For primitives this is the value of the | |
998 * GaimStatusPrimitive. For saved statuses this is the | |
999 * creation timestamp. | |
1000 */ | |
942 void | 1001 void |
943 gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GtkGaimStatusBoxItemType type, GdkPixbuf *pixbuf, const char *text, const char *sec_text, gpointer data) | 1002 gtk_gaim_status_box_add(GtkGaimStatusBox *status_box, GtkGaimStatusBoxItemType type, GdkPixbuf *pixbuf, const char *title, const char *desc, gpointer data) |
944 { | 1003 { |
945 GtkTreeIter iter; | 1004 GtkTreeIter iter; |
946 char *t; | 1005 char *text; |
947 | 1006 |
948 if (sec_text) { | 1007 if (desc == NULL) |
1008 { | |
1009 text = g_markup_escape_text(title, -1); | |
1010 } | |
1011 else | |
1012 { | |
949 char aa_color[8]; | 1013 char aa_color[8]; |
950 gchar *escaped; | 1014 gchar *escaped_title, *escaped_desc; |
951 GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(status_box)); | 1015 GtkStyle *style; |
1016 | |
1017 style = gtk_widget_get_style(GTK_WIDGET(status_box)); | |
952 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", | 1018 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", |
953 style->text_aa[GTK_STATE_NORMAL].red >> 8, | 1019 style->text_aa[GTK_STATE_NORMAL].red >> 8, |
954 style->text_aa[GTK_STATE_NORMAL].green >> 8, | 1020 style->text_aa[GTK_STATE_NORMAL].green >> 8, |
955 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | 1021 style->text_aa[GTK_STATE_NORMAL].blue >> 8); |
956 escaped = g_markup_escape_text(sec_text, -1); | 1022 |
957 t = g_strdup_printf("%s\n<span color=\"%s\">%s</span>", text, aa_color, escaped); | 1023 escaped_title = g_markup_escape_text(title, -1); |
958 g_free(escaped); | 1024 escaped_desc = g_markup_escape_text(desc, -1); |
959 } else { | 1025 text = g_strdup_printf("%s\n<span color=\"%s\" size=\"smaller\">%s</span>", |
960 t = g_markup_escape_text(text, -1); | 1026 escaped_title, aa_color, escaped_desc); |
1027 g_free(escaped_title); | |
1028 g_free(escaped_desc); | |
961 } | 1029 } |
962 | 1030 |
963 gtk_list_store_append(status_box->dropdown_store, &iter); | 1031 gtk_list_store_append(status_box->dropdown_store, &iter); |
964 gtk_list_store_set(status_box->dropdown_store, &iter, | 1032 gtk_list_store_set(status_box->dropdown_store, &iter, |
965 TYPE_COLUMN, type, | 1033 TYPE_COLUMN, type, |
966 ICON_COLUMN, pixbuf, | 1034 ICON_COLUMN, pixbuf, |
967 TEXT_COLUMN, t, | 1035 TEXT_COLUMN, text, |
968 TITLE_COLUMN, text, | 1036 TITLE_COLUMN, title, |
969 DESC_COLUMN, sec_text, | 1037 DESC_COLUMN, desc, |
970 DATA_COLUMN, data, | 1038 DATA_COLUMN, data, |
971 -1); | 1039 -1); |
972 g_free(t); | 1040 g_free(text); |
973 } | 1041 } |
974 | 1042 |
975 void | 1043 void |
976 gtk_gaim_status_box_add_separator(GtkGaimStatusBox *status_box) | 1044 gtk_gaim_status_box_add_separator(GtkGaimStatusBox *status_box) |
977 { | 1045 { |
1029 else | 1097 else |
1030 status_box->typing_index++; | 1098 status_box->typing_index++; |
1031 gtk_gaim_status_box_refresh(status_box); | 1099 gtk_gaim_status_box_refresh(status_box); |
1032 } | 1100 } |
1033 | 1101 |
1034 static GaimStatusType | 1102 static GaimStatusType * |
1035 *find_status_type_by_index(const GaimAccount *account, gint active) | 1103 find_status_type_by_index(const GaimAccount *account, gint active) |
1036 { | 1104 { |
1037 const GList *l = gaim_account_get_status_types(account); | 1105 const GList *l = gaim_account_get_status_types(account); |
1038 gint i; | 1106 gint i; |
1039 | 1107 |
1040 for (i = 0; l; l = l->next) { | 1108 for (i = 0; l; l = l->next) { |
1230 static void gtk_gaim_status_box_changed(GtkComboBox *box) | 1298 static void gtk_gaim_status_box_changed(GtkComboBox *box) |
1231 { | 1299 { |
1232 GtkGaimStatusBox *status_box; | 1300 GtkGaimStatusBox *status_box; |
1233 GtkTreeIter iter; | 1301 GtkTreeIter iter; |
1234 GtkGaimStatusBoxItemType type; | 1302 GtkGaimStatusBoxItemType type; |
1235 char *text, *sec_text; | 1303 char *text, *desc; |
1236 GdkPixbuf *pixbuf; | 1304 GdkPixbuf *pixbuf; |
1237 gpointer data; | 1305 gpointer data; |
1238 GList *accounts = NULL, *node; | 1306 GList *accounts = NULL, *node; |
1239 | 1307 |
1240 status_box = GTK_GAIM_STATUS_BOX(box); | 1308 status_box = GTK_GAIM_STATUS_BOX(box); |
1242 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter)) | 1310 if (!gtk_combo_box_get_active_iter(GTK_COMBO_BOX(status_box), &iter)) |
1243 return; | 1311 return; |
1244 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, | 1312 gtk_tree_model_get(GTK_TREE_MODEL(status_box->dropdown_store), &iter, |
1245 TYPE_COLUMN, &type, | 1313 TYPE_COLUMN, &type, |
1246 TITLE_COLUMN, &text, | 1314 TITLE_COLUMN, &text, |
1247 DESC_COLUMN, &sec_text, | 1315 DESC_COLUMN, &desc, |
1248 ICON_COLUMN, &pixbuf, | 1316 ICON_COLUMN, &pixbuf, |
1249 DATA_COLUMN, &data, | 1317 DATA_COLUMN, &data, |
1250 -1); | 1318 -1); |
1251 if (status_box->title) | 1319 if (status_box->title) |
1252 g_free(status_box->title); | 1320 g_free(status_box->title); |
1253 status_box->title = text; | 1321 status_box->title = text; |
1254 if (status_box->desc && sec_text) | 1322 if (status_box->desc && desc) |
1255 g_free(status_box->desc); | 1323 g_free(status_box->desc); |
1256 status_box->desc = sec_text; | 1324 status_box->desc = desc; |
1257 if (status_box->pixbuf) | 1325 if (status_box->pixbuf) |
1258 g_object_unref(status_box->pixbuf); | 1326 g_object_unref(status_box->pixbuf); |
1259 status_box->pixbuf = pixbuf; | 1327 status_box->pixbuf = pixbuf; |
1260 if (status_box->typing) | 1328 if (status_box->typing) |
1261 g_source_remove(status_box->typing); | 1329 g_source_remove(status_box->typing); |
1358 break; | 1426 break; |
1359 case GAIM_STATUS_OFFLINE: | 1427 case GAIM_STATUS_OFFLINE: |
1360 index = 3; | 1428 index = 3; |
1361 break; | 1429 break; |
1362 default: | 1430 default: |
1363 index = GTK_LIST_STORE(box->dropdown_store)->length - 2; | 1431 /* |
1432 * TODO: This is very bad! I believe it's causing the infinite | |
1433 * windows bug. Need to do something better here. | |
1434 */ | |
1435 /* index = GTK_LIST_STORE(box->dropdown_store)->length - 2; */ | |
1436 index = 0; | |
1364 break; | 1437 break; |
1365 } | 1438 } |
1366 | 1439 |
1367 return index; | 1440 return index; |
1368 } | 1441 } |