Mercurial > pidgin.yaz
comparison src/gtkstatusbox.c @ 13044:18fc2a679e38
[gaim-migrate @ 15403]
Two things:
* Escape text displayed in the status box and the status box drop down
* Add and improve some gtkstatusbox documentation.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Thu, 26 Jan 2006 05:23:49 +0000 |
parents | 7d39e6c73dc3 |
children | 704dc95d0198 |
comparison
equal
deleted
inserted
replaced
13043:fa99be331f2f | 13044:18fc2a679e38 |
---|---|
21 * You should have received a copy of the GNU General Public License | 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 | 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 | 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 */ | 24 */ |
25 | 25 |
26 /* | |
27 * The status box is made up of two main pieces: | |
28 * - The box that displays the current status, which is made | |
29 * of a GtkListStore ("status_box->store") and GtkCellView | |
30 * ("status_box->cell_view"). There is always exactly 1 row | |
31 * in this list store. Only the TYPE_ICON and TYPE_TEXT | |
32 * columns are used in this list store. | |
33 * - The dropdown menu that lets users select a status, which | |
34 * is made of a GtkComboBox ("status_box") and GtkListStore | |
35 * ("status_box->dropdown_store"). This dropdown is shown | |
36 * when the user clicks on the box that displays the current | |
37 * status. This list store contains one row for Available, | |
38 * one row for Away, etc., a few rows for popular statuses, | |
39 * and the "New..." and "Saved..." options. | |
40 */ | |
41 | |
26 #include <gdk/gdkkeysyms.h> | 42 #include <gdk/gdkkeysyms.h> |
27 | 43 |
28 #include "account.h" | 44 #include "account.h" |
29 #include "internal.h" | 45 #include "internal.h" |
30 #include "savedstatuses.h" | 46 #include "savedstatuses.h" |
64 static void (*combo_box_size_request)(GtkWidget *widget, GtkRequisition *requisition); | 80 static void (*combo_box_size_request)(GtkWidget *widget, GtkRequisition *requisition); |
65 static void (*combo_box_size_allocate)(GtkWidget *widget, GtkAllocation *allocation); | 81 static void (*combo_box_size_allocate)(GtkWidget *widget, GtkAllocation *allocation); |
66 static void (*combo_box_forall) (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); | 82 static void (*combo_box_forall) (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data); |
67 | 83 |
68 enum { | 84 enum { |
69 TYPE_COLUMN, /* A GtkGaimStatusBoxItemType */ | 85 /** A GtkGaimStatusBoxItemType */ |
70 ICON_COLUMN, /* This is a GdkPixbuf (the other columns are strings) */ | 86 TYPE_COLUMN, |
71 TEXT_COLUMN, /* A string */ | 87 |
72 TITLE_COLUMN, /* The plain-English title of this item */ | 88 /** |
73 DESC_COLUMN, /* A plain-English description of this item */ | 89 * This is a GdkPixbuf (the other columns are strings). |
74 DATA_COLUMN, /* Keep track of the creation time of popular | 90 * This column is visible. |
75 statuses, and also the GaimStatusPrimitive */ | 91 */ |
92 ICON_COLUMN, | |
93 | |
94 /** The text displayed on the status box. This column is visible. */ | |
95 TEXT_COLUMN, | |
96 | |
97 /** The plain-English title of this item */ | |
98 TITLE_COLUMN, | |
99 | |
100 /** A plain-English description of this item */ | |
101 DESC_COLUMN, | |
102 | |
103 /* | |
104 * This value depends on TYPE_COLUMN. For POPULAR types, | |
105 * this is the creation time. For PRIMITIVE types, | |
106 * this is the GaimStatusPrimitive. | |
107 */ | |
108 DATA_COLUMN, | |
109 | |
76 NUM_COLUMNS | 110 NUM_COLUMNS |
77 }; | 111 }; |
78 | 112 |
79 enum { | 113 enum { |
80 PROP_0, | 114 PROP_0, |
266 G_PARAM_READWRITE | 300 G_PARAM_READWRITE |
267 ) | 301 ) |
268 ); | 302 ); |
269 } | 303 } |
270 | 304 |
305 /** | |
306 * This updates the text displayed on the status box so that it shows | |
307 * the current status. | |
308 */ | |
271 static void | 309 static void |
272 gtk_gaim_status_box_refresh(GtkGaimStatusBox *status_box) | 310 gtk_gaim_status_box_refresh(GtkGaimStatusBox *status_box) |
273 { | 311 { |
274 char *text = NULL, *title; | 312 char *text = NULL, *title; |
275 char aa_color[8]; | 313 char aa_color[8]; |
281 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", | 319 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", |
282 style->text_aa[GTK_STATE_NORMAL].red >> 8, | 320 style->text_aa[GTK_STATE_NORMAL].red >> 8, |
283 style->text_aa[GTK_STATE_NORMAL].green >> 8, | 321 style->text_aa[GTK_STATE_NORMAL].green >> 8, |
284 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | 322 style->text_aa[GTK_STATE_NORMAL].blue >> 8); |
285 | 323 |
286 title = status_box->title; | 324 if (status_box->title != NULL) |
287 if (!title) | 325 title = g_markup_escape_text(status_box->title, -1); |
288 title = ""; | 326 else |
327 title = g_strdup(""); | |
289 | 328 |
290 if (status_box->error) { | 329 if (status_box->error) { |
330 gchar *tmp = g_markup_escape_text(status_box->error, -1); | |
291 text = g_strdup_printf("<span size=\"smaller\" weight=\"bold\" color=\"red\">%s</span>", | 331 text = g_strdup_printf("<span size=\"smaller\" weight=\"bold\" color=\"red\">%s</span>", |
292 status_box->error); | 332 tmp); |
333 g_free(tmp); | |
293 } else if (status_box->typing) { | 334 } else if (status_box->typing) { |
294 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", | 335 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", |
295 aa_color, _("Typing")); | 336 aa_color, _("Typing")); |
296 } else if (status_box->connecting) { | 337 } else if (status_box->connecting) { |
297 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", | 338 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", |
298 aa_color, _("Connecting")); | 339 aa_color, _("Connecting")); |
299 } else if (status_box->desc) { | 340 } else if (status_box->desc) { |
341 gchar *tmp = g_markup_escape_text(status_box->desc, -1); | |
300 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", | 342 text = g_strdup_printf("<span size=\"smaller\" color=\"%s\">%s</span>", |
301 aa_color, status_box->desc); | 343 aa_color, tmp); |
344 g_free(tmp); | |
302 } | 345 } |
303 | 346 |
304 if (status_box->account) { | 347 if (status_box->account) { |
305 char *text2 = g_strdup_printf("%s\n<span size=\"smaller\">%s</span>", | 348 char *text2 = g_strdup_printf("%s\n<span size=\"smaller\">%s</span>", |
306 gaim_account_get_username(status_box->account), | 349 gaim_account_get_username(status_box->account), |
312 g_free(text); | 355 g_free(text); |
313 text = text2; | 356 text = text2; |
314 } else { | 357 } else { |
315 text = g_strdup(title); | 358 text = g_strdup(title); |
316 } | 359 } |
360 g_free(title); | |
317 | 361 |
318 if (status_box->connecting) | 362 if (status_box->connecting) |
319 pixbuf = status_box->connecting_pixbufs[status_box->connecting_index]; | 363 pixbuf = status_box->connecting_pixbufs[status_box->connecting_index]; |
320 else if (status_box->error) | 364 else if (status_box->error) |
321 pixbuf = status_box->error_pixbuf; | 365 pixbuf = status_box->error_pixbuf; |
322 else if (status_box->typing) | 366 else if (status_box->typing) |
323 pixbuf = status_box->typing_pixbufs[status_box->typing_index]; | 367 pixbuf = status_box->typing_pixbufs[status_box->typing_index]; |
324 else | 368 else |
325 pixbuf = status_box->pixbuf; | 369 pixbuf = status_box->pixbuf; |
326 | 370 |
371 /* | |
372 * Only two columns are used in this list store (does it | |
373 * really need to be a list store?) | |
374 */ | |
327 gtk_list_store_set(status_box->store, &(status_box->iter), | 375 gtk_list_store_set(status_box->store, &(status_box->iter), |
328 TYPE_COLUMN, -1, /* This field is not used in this list store */ | |
329 ICON_COLUMN, pixbuf, | 376 ICON_COLUMN, pixbuf, |
330 TEXT_COLUMN, text, | 377 TEXT_COLUMN, text, |
331 TITLE_COLUMN, title, | |
332 DESC_COLUMN, status_box->desc, | |
333 DATA_COLUMN, -1, /* This field is not used in this list store */ | |
334 -1); | 378 -1); |
335 path = gtk_tree_path_new_from_string("0"); | 379 path = gtk_tree_path_new_from_string("0"); |
336 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); | 380 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); |
337 gtk_tree_path_free(path); | 381 gtk_tree_path_free(path); |
338 | 382 |
709 gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) | 753 gtk_gaim_status_box_init (GtkGaimStatusBox *status_box) |
710 { | 754 { |
711 GtkCellRenderer *text_rend; | 755 GtkCellRenderer *text_rend; |
712 GtkCellRenderer *icon_rend; | 756 GtkCellRenderer *icon_rend; |
713 GtkTextBuffer *buffer; | 757 GtkTextBuffer *buffer; |
714 GtkTreePath *path; | |
715 | |
716 text_rend = gtk_cell_renderer_text_new(); | |
717 icon_rend = gtk_cell_renderer_pixbuf_new(); | |
718 | 758 |
719 status_box->imhtml_visible = FALSE; | 759 status_box->imhtml_visible = FALSE; |
720 status_box->connecting = FALSE; | 760 status_box->connecting = FALSE; |
721 status_box->typing = FALSE; | 761 status_box->typing = FALSE; |
722 status_box->title = NULL; | 762 status_box->title = NULL; |
732 gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), GTK_TREE_MODEL(status_box->dropdown_store)); | 772 gtk_combo_box_set_model(GTK_COMBO_BOX(status_box), GTK_TREE_MODEL(status_box->dropdown_store)); |
733 gtk_cell_view_set_model(GTK_CELL_VIEW(status_box->cell_view), GTK_TREE_MODEL(status_box->store)); | 773 gtk_cell_view_set_model(GTK_CELL_VIEW(status_box->cell_view), GTK_TREE_MODEL(status_box->store)); |
734 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(status_box), 0); | 774 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(status_box), 0); |
735 gtk_list_store_append(status_box->store, &(status_box->iter)); | 775 gtk_list_store_append(status_box->store, &(status_box->iter)); |
736 gtk_gaim_status_box_refresh(status_box); | 776 gtk_gaim_status_box_refresh(status_box); |
737 path = gtk_tree_path_new_from_string("0"); | |
738 gtk_cell_view_set_displayed_row(GTK_CELL_VIEW(status_box->cell_view), path); | |
739 gtk_tree_path_free(path); | |
740 | 777 |
741 gtk_container_add(GTK_CONTAINER(status_box->toggle_button), status_box->hbox); | 778 gtk_container_add(GTK_CONTAINER(status_box->toggle_button), status_box->hbox); |
742 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->cell_view, TRUE, TRUE, 0); | 779 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->cell_view, TRUE, TRUE, 0); |
743 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->vsep, FALSE, FALSE, 0); | 780 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->vsep, FALSE, FALSE, 0); |
744 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->arrow, FALSE, FALSE, 0); | 781 gtk_box_pack_start(GTK_BOX(status_box->hbox), status_box->arrow, FALSE, FALSE, 0); |
745 gtk_widget_show_all(status_box->toggle_button); | 782 gtk_widget_show_all(status_box->toggle_button); |
746 #if GTK_CHECK_VERSION(2,4,0) | 783 #if GTK_CHECK_VERSION(2,4,0) |
747 gtk_button_set_focus_on_click(GTK_BUTTON(status_box->toggle_button), FALSE); | 784 gtk_button_set_focus_on_click(GTK_BUTTON(status_box->toggle_button), FALSE); |
748 #endif | 785 #endif |
749 status_box->icon_rend = gtk_cell_renderer_pixbuf_new(); | 786 |
750 status_box->text_rend = gtk_cell_renderer_text_new(); | 787 text_rend = gtk_cell_renderer_text_new(); |
751 | 788 icon_rend = gtk_cell_renderer_pixbuf_new(); |
752 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), icon_rend, FALSE); | 789 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), icon_rend, FALSE); |
753 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), text_rend, TRUE); | 790 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box), text_rend, TRUE); |
754 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), icon_rend, "pixbuf", ICON_COLUMN, NULL); | 791 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), icon_rend, "pixbuf", ICON_COLUMN, NULL); |
755 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), text_rend, "markup", TEXT_COLUMN, NULL); | 792 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box), text_rend, "markup", TEXT_COLUMN, NULL); |
756 | 793 |
794 status_box->icon_rend = gtk_cell_renderer_pixbuf_new(); | |
795 status_box->text_rend = gtk_cell_renderer_text_new(); | |
757 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, FALSE); | 796 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, FALSE); |
758 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, TRUE); | 797 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, TRUE); |
759 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, "pixbuf", ICON_COLUMN, NULL); | 798 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->icon_rend, "pixbuf", ICON_COLUMN, NULL); |
760 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, "markup", TEXT_COLUMN, NULL); | 799 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(status_box->cell_view), status_box->text_rend, "markup", TEXT_COLUMN, NULL); |
761 | 800 |
900 GtkTreeIter iter; | 939 GtkTreeIter iter; |
901 char *t; | 940 char *t; |
902 | 941 |
903 if (sec_text) { | 942 if (sec_text) { |
904 char aa_color[8]; | 943 char aa_color[8]; |
944 gchar *escaped; | |
905 GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(status_box)); | 945 GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(status_box)); |
906 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", | 946 snprintf(aa_color, sizeof(aa_color), "#%02x%02x%02x", |
907 style->text_aa[GTK_STATE_NORMAL].red >> 8, | 947 style->text_aa[GTK_STATE_NORMAL].red >> 8, |
908 style->text_aa[GTK_STATE_NORMAL].green >> 8, | 948 style->text_aa[GTK_STATE_NORMAL].green >> 8, |
909 style->text_aa[GTK_STATE_NORMAL].blue >> 8); | 949 style->text_aa[GTK_STATE_NORMAL].blue >> 8); |
910 t = g_strdup_printf("%s\n<span color=\"%s\">%s</span>", text, aa_color, sec_text); | 950 escaped = g_markup_escape_text(sec_text, -1); |
951 t = g_strdup_printf("%s\n<span color=\"%s\">%s</span>", text, aa_color, escaped); | |
952 g_free(escaped); | |
911 } else { | 953 } else { |
912 t = g_strdup(text); | 954 t = g_markup_escape_text(text, -1); |
913 } | 955 } |
914 | 956 |
915 gtk_list_store_append(status_box->dropdown_store, &iter); | 957 gtk_list_store_append(status_box->dropdown_store, &iter); |
916 gtk_list_store_set(status_box->dropdown_store, &iter, | 958 gtk_list_store_set(status_box->dropdown_store, &iter, |
917 TYPE_COLUMN, type, | 959 TYPE_COLUMN, type, |