The row[] array is used to prepare data passed to set_node(), but this indirection is unnecessary. Squash fill_row() into set_node() and call gtk_tree_store_set() directly. Also, calling gdk_pixbuf_new_from_xpm_data() for every row is inefficient. Call it once and store the resulting pixbuf in a global variable.
Unified · Split
| @@ -44,6 +44,7 @@ static GtkWidget *save_menu_item; · 43 unmodified lines | |||
| 44 | static GtkTextTag *tag1, *tag2; | 44 | static GtkTextTag *tag1, *tag2; |
| 45 | 45 | ||
| 46 | static GtkTreeStore *tree1, *tree2; | 46 | static GtkTreeStore *tree1, *tree2; |
| 47 | static GdkPixbuf *pix_menu; | ||
| 47 | 48 | ||
| 48 | static struct menu *browsed; // browsed menu for SINGLE/SPLIT view | 49 | static struct menu *browsed; // browsed menu for SINGLE/SPLIT view |
| 49 | static struct menu *selected; // selected entry | 50 | static struct menu *selected; // selected entry |
| @@ -58,9 +59,6 @@ enum { · 8 unmodified lines | |||
| 58 | static void display_list(void); | 59 | static void display_list(void); |
| 59 | static void display_tree(GtkTreeStore *store, struct menu *menu); | 60 | static void display_tree(GtkTreeStore *store, struct menu *menu); |
| 60 | static void display_tree_part(void); | 61 | static void display_tree_part(void); |
| 61 | static gchar **fill_row(struct menu *menu); | ||
| 62 | static void set_node(GtkTreeStore *tree, GtkTreeIter *node, | ||
| 63 | struct menu *menu, gchar **row); | ||
| 64 | 62 | ||
| 65 | static void conf_changed(bool dirty) | 63 | static void conf_changed(bool dirty) |
| 66 | { | 64 | { |
| @@ -173,6 +171,104 @@ static void update_row_visibility(void) · 106 unmodified lines | |||
| 173 | _update_row_visibility(GTK_TREE_VIEW(tree2_w)); | 171 | _update_row_visibility(GTK_TREE_VIEW(tree2_w)); |
| 174 | } | 172 | } |
| 175 | 173 | ||
| 174 | static void set_node(GtkTreeStore *tree, GtkTreeIter *node, struct menu *menu) | ||
| 175 | { | ||
| 176 | struct symbol *sym = menu->sym; | ||
| 177 | tristate val; | ||
| 178 | gchar *option; | ||
| 179 | const gchar *_no = ""; | ||
| 180 | const gchar *_mod = ""; | ||
| 181 | const gchar *_yes = ""; | ||
| 182 | const gchar *value = ""; | ||
| 183 | GdkColor color; | ||
| 184 | gboolean editable = FALSE; | ||
| 185 | gboolean btnvis = FALSE; | ||
| 186 | |||
| 187 | option = g_strdup_printf("%s %s %s %s", | ||
| 188 | menu->type == M_COMMENT ? "***" : "", | ||
| 189 | menu_get_prompt(menu), | ||
| 190 | menu->type == M_COMMENT ? "***" : "", | ||
| 191 | sym && !sym_has_value(sym) ? "(NEW)" : ""); | ||
| 192 | |||
| 193 | gdk_color_parse(menu_is_visible(menu) ? "Black" : "DarkGray", &color); | ||
| 194 | |||
| 195 | if (!sym) | ||
| 196 | goto set; | ||
| 197 | |||
| 198 | sym_calc_value(sym); | ||
| 199 | |||
| 200 | if (menu->type == M_CHOICE) { // parse children to get a final value | ||
| 201 | struct symbol *def_sym = sym_calc_choice(menu); | ||
| 202 | struct menu *def_menu = NULL; | ||
| 203 | |||
| 204 | for (struct menu *child = menu->list; child; child = child->next) { | ||
| 205 | if (menu_is_visible(child) && child->sym == def_sym) | ||
| 206 | def_menu = child; | ||
| 207 | } | ||
| 208 | |||
| 209 | if (def_menu) | ||
| 210 | value = menu_get_prompt(def_menu); | ||
| 211 | |||
| 212 | goto set; | ||
| 213 | } | ||
| 214 | |||
| 215 | switch (sym_get_type(sym)) { | ||
| 216 | case S_BOOLEAN: | ||
| 217 | case S_TRISTATE: | ||
| 218 | |||
| 219 | btnvis = TRUE; | ||
| 220 | |||
| 221 | val = sym_get_tristate_value(sym); | ||
| 222 | switch (val) { | ||
| 223 | case no: | ||
| 224 | _no = "N"; | ||
| 225 | value = "N"; | ||
| 226 | break; | ||
| 227 | case mod: | ||
| 228 | _mod = "M"; | ||
| 229 | value = "M"; | ||
| 230 | break; | ||
| 231 | case yes: | ||
| 232 | _yes = "Y"; | ||
| 233 | value = "Y"; | ||
| 234 | break; | ||
| 235 | } | ||
| 236 | |||
| 237 | if (val != no && sym_tristate_within_range(sym, no)) | ||
| 238 | _no = "_"; | ||
| 239 | if (val != mod && sym_tristate_within_range(sym, mod)) | ||
| 240 | _mod = "_"; | ||
| 241 | if (val != yes && sym_tristate_within_range(sym, yes)) | ||
| 242 | _yes = "_"; | ||
| 243 | break; | ||
| 244 | default: | ||
| 245 | value = sym_get_string_value(sym); | ||
| 246 | editable = TRUE; | ||
| 247 | break; | ||
| 248 | } | ||
| 249 | |||
| 250 | set: | ||
| 251 | gtk_tree_store_set(tree, node, | ||
| 252 | COL_OPTION, option, | ||
| 253 | COL_NAME, sym ? sym->name : "", | ||
| 254 | COL_NO, _no, | ||
| 255 | COL_MOD, _mod, | ||
| 256 | COL_YES, _yes, | ||
| 257 | COL_VALUE, value, | ||
| 258 | COL_MENU, (gpointer) menu, | ||
| 259 | COL_COLOR, &color, | ||
| 260 | COL_EDIT, editable, | ||
| 261 | COL_PIXBUF, pix_menu, | ||
| 262 | COL_PIXVIS, view_mode == SINGLE_VIEW && menu->type == M_MENU, | ||
| 263 | COL_BTNVIS, btnvis, | ||
| 264 | COL_BTNACT, _yes[0] == 'Y', | ||
| 265 | COL_BTNINC, _mod[0] == 'M', | ||
| 266 | COL_BTNRAD, sym && sym_is_choice_value(sym), | ||
| 267 | -1); | ||
| 268 | |||
| 269 | g_free(option); | ||
| 270 | } | ||
| 271 | |||
| 176 | static void _update_tree(GtkTreeStore *store, GtkTreeIter *parent) | 272 | static void _update_tree(GtkTreeStore *store, GtkTreeIter *parent) |
| 177 | { | 273 | { |
| 178 | GtkTreeModel *model = GTK_TREE_MODEL(store); | 274 | GtkTreeModel *model = GTK_TREE_MODEL(store); |
| @@ -186,7 +282,7 @@ static void _update_tree(GtkTreeStore *store, GtkTreeIter *parent) · 7 unmodified lines | |||
| 186 | gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1); | 282 | gtk_tree_model_get(model, &iter, COL_MENU, &menu, -1); |
| 187 | 283 | ||
| 188 | if (menu) | 284 | if (menu) |
| 189 | set_node(store, &iter, menu, fill_row(menu)); | 285 | set_node(store, &iter, menu); |
| 190 | 286 | ||
| 191 | _update_tree(store, &iter); | 287 | _update_tree(store, &iter); |
| 192 | 288 | ||
| @@ -565,6 +661,9 @@ static gboolean on_window1_delete_event(GtkWidget *widget, GdkEvent *event, · 372 unmodified lines | |||
| 565 | 661 | ||
| 566 | gtk_widget_destroy(dialog); | 662 | gtk_widget_destroy(dialog); |
| 567 | 663 | ||
| 664 | if (!ret) | ||
| 665 | g_object_unref(pix_menu); | ||
| 666 | |||
| 568 | return ret; | 667 | return ret; |
| 569 | } | 668 | } |
| 570 | 669 | ||
| @@ -826,167 +925,6 @@ static gboolean on_treeview1_button_press_event(GtkWidget *widget, · 255 unmodified lines | |||
| 826 | return FALSE; | 925 | return FALSE; |
| 827 | } | 926 | } |
| 828 | 927 | ||
| 829 | |||
| 830 | /* Fill a row of strings */ | ||
| 831 | static gchar **fill_row(struct menu *menu) | ||
| 832 | { | ||
| 833 | static gchar *row[COL_NUMBER]; | ||
| 834 | struct symbol *sym = menu->sym; | ||
| 835 | const char *def; | ||
| 836 | int stype; | ||
| 837 | tristate val; | ||
| 838 | enum prop_type ptype; | ||
| 839 | int i; | ||
| 840 | |||
| 841 | for (i = COL_OPTION; i <= COL_COLOR; i++) | ||
| 842 | g_free(row[i]); | ||
| 843 | bzero(row, sizeof(row)); | ||
| 844 | |||
| 845 | ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; | ||
| 846 | |||
| 847 | row[COL_OPTION] = | ||
| 848 | g_strdup_printf("%s %s %s %s", | ||
| 849 | ptype == P_COMMENT ? "***" : "", | ||
| 850 | menu_get_prompt(menu), | ||
| 851 | ptype == P_COMMENT ? "***" : "", | ||
| 852 | sym && !sym_has_value(sym) ? "(NEW)" : ""); | ||
| 853 | |||
| 854 | if (opt_mode == OPT_ALL && !menu_is_visible(menu)) | ||
| 855 | row[COL_COLOR] = g_strdup("DarkGray"); | ||
| 856 | else if (opt_mode == OPT_PROMPT && | ||
| 857 | menu_has_prompt(menu) && !menu_is_visible(menu)) | ||
| 858 | row[COL_COLOR] = g_strdup("DarkGray"); | ||
| 859 | else | ||
| 860 | row[COL_COLOR] = g_strdup("Black"); | ||
| 861 | |||
| 862 | switch (ptype) { | ||
| 863 | case P_MENU: | ||
| 864 | row[COL_PIXBUF] = (gchar *) xpm_menu; | ||
| 865 | if (view_mode == SINGLE_VIEW) | ||
| 866 | row[COL_PIXVIS] = GINT_TO_POINTER(TRUE); | ||
| 867 | row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); | ||
| 868 | break; | ||
| 869 | case P_COMMENT: | ||
| 870 | row[COL_PIXBUF] = (gchar *) xpm_void; | ||
| 871 | row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); | ||
| 872 | row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); | ||
| 873 | break; | ||
| 874 | default: | ||
| 875 | row[COL_PIXBUF] = (gchar *) xpm_void; | ||
| 876 | row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); | ||
| 877 | row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); | ||
| 878 | break; | ||
| 879 | } | ||
| 880 | |||
| 881 | if (!sym) | ||
| 882 | return row; | ||
| 883 | row[COL_NAME] = g_strdup(sym->name); | ||
| 884 | |||
| 885 | sym_calc_value(sym); | ||
| 886 | |||
| 887 | if (sym_is_choice(sym)) { // parse childs for getting final value | ||
| 888 | struct menu *child; | ||
| 889 | struct symbol *def_sym = sym_calc_choice(menu); | ||
| 890 | struct menu *def_menu = NULL; | ||
| 891 | |||
| 892 | for (child = menu->list; child; child = child->next) { | ||
| 893 | if (menu_is_visible(child) | ||
| 894 | && child->sym == def_sym) | ||
| 895 | def_menu = child; | ||
| 896 | } | ||
| 897 | |||
| 898 | if (def_menu) | ||
| 899 | row[COL_VALUE] = | ||
| 900 | g_strdup(menu_get_prompt(def_menu)); | ||
| 901 | |||
| 902 | row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); | ||
| 903 | return row; | ||
| 904 | } | ||
| 905 | if (sym_is_choice_value(sym)) | ||
| 906 | row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); | ||
| 907 | |||
| 908 | stype = sym_get_type(sym); | ||
| 909 | switch (stype) { | ||
| 910 | case S_BOOLEAN: | ||
| 911 | case S_TRISTATE: | ||
| 912 | val = sym_get_tristate_value(sym); | ||
| 913 | switch (val) { | ||
| 914 | case no: | ||
| 915 | row[COL_NO] = g_strdup("N"); | ||
| 916 | row[COL_VALUE] = g_strdup("N"); | ||
| 917 | row[COL_BTNACT] = GINT_TO_POINTER(FALSE); | ||
| 918 | row[COL_BTNINC] = GINT_TO_POINTER(FALSE); | ||
| 919 | break; | ||
| 920 | case mod: | ||
| 921 | row[COL_MOD] = g_strdup("M"); | ||
| 922 | row[COL_VALUE] = g_strdup("M"); | ||
| 923 | row[COL_BTNINC] = GINT_TO_POINTER(TRUE); | ||
| 924 | break; | ||
| 925 | case yes: | ||
| 926 | row[COL_YES] = g_strdup("Y"); | ||
| 927 | row[COL_VALUE] = g_strdup("Y"); | ||
| 928 | row[COL_BTNACT] = GINT_TO_POINTER(TRUE); | ||
| 929 | row[COL_BTNINC] = GINT_TO_POINTER(FALSE); | ||
| 930 | break; | ||
| 931 | } | ||
| 932 | |||
| 933 | if (val != no && sym_tristate_within_range(sym, no)) | ||
| 934 | row[COL_NO] = g_strdup("_"); | ||
| 935 | if (val != mod && sym_tristate_within_range(sym, mod)) | ||
| 936 | row[COL_MOD] = g_strdup("_"); | ||
| 937 | if (val != yes && sym_tristate_within_range(sym, yes)) | ||
| 938 | row[COL_YES] = g_strdup("_"); | ||
| 939 | break; | ||
| 940 | case S_INT: | ||
| 941 | case S_HEX: | ||
| 942 | case S_STRING: | ||
| 943 | def = sym_get_string_value(sym); | ||
| 944 | row[COL_VALUE] = g_strdup(def); | ||
| 945 | row[COL_EDIT] = GINT_TO_POINTER(TRUE); | ||
| 946 | row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); | ||
| 947 | break; | ||
| 948 | } | ||
| 949 | |||
| 950 | return row; | ||
| 951 | } | ||
| 952 | |||
| 953 | |||
| 954 | /* Set the node content with a row of strings */ | ||
| 955 | static void set_node(GtkTreeStore *tree, GtkTreeIter *node, | ||
| 956 | struct menu *menu, gchar **row) | ||
| 957 | { | ||
| 958 | GdkColor color; | ||
| 959 | gboolean success; | ||
| 960 | GdkPixbuf *pix; | ||
| 961 | |||
| 962 | pix = gdk_pixbuf_new_from_xpm_data((const char **) | ||
| 963 | row[COL_PIXBUF]); | ||
| 964 | |||
| 965 | gdk_color_parse(row[COL_COLOR], &color); | ||
| 966 | gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1, | ||
| 967 | FALSE, FALSE, &success); | ||
| 968 | |||
| 969 | gtk_tree_store_set(tree, node, | ||
| 970 | COL_OPTION, row[COL_OPTION], | ||
| 971 | COL_NAME, row[COL_NAME], | ||
| 972 | COL_NO, row[COL_NO], | ||
| 973 | COL_MOD, row[COL_MOD], | ||
| 974 | COL_YES, row[COL_YES], | ||
| 975 | COL_VALUE, row[COL_VALUE], | ||
| 976 | COL_MENU, (gpointer) menu, | ||
| 977 | COL_COLOR, &color, | ||
| 978 | COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]), | ||
| 979 | COL_PIXBUF, pix, | ||
| 980 | COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]), | ||
| 981 | COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]), | ||
| 982 | COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]), | ||
| 983 | COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]), | ||
| 984 | COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]), | ||
| 985 | -1); | ||
| 986 | |||
| 987 | g_object_unref(pix); | ||
| 988 | } | ||
| 989 | |||
| 990 | /* Display the whole tree (single/split/full view) */ | 928 | /* Display the whole tree (single/split/full view) */ |
| 991 | static void _display_tree(GtkTreeStore *tree, struct menu *menu, | 929 | static void _display_tree(GtkTreeStore *tree, struct menu *menu, |
| 992 | GtkTreeIter *parent) | 930 | GtkTreeIter *parent) |
| @@ -1018,7 +956,7 @@ static void _display_tree(GtkTreeStore *tree, struct menu *menu, · 25 unmodified lines | |||
| 1018 | continue; | 956 | continue; |
| 1019 | 957 | ||
| 1020 | gtk_tree_store_append(tree, &iter, parent); | 958 | gtk_tree_store_append(tree, &iter, parent); |
| 1021 | set_node(tree, &iter, child, fill_row(child)); | 959 | set_node(tree, &iter, child); |
| 1022 | 960 | ||
| 1023 | if ((view_mode != FULL_VIEW) && (ptype == P_MENU) | 961 | if ((view_mode != FULL_VIEW) && (ptype == P_MENU) |
| 1024 | && (tree == tree2)) | 962 | && (tree == tree2)) |
| @@ -1393,6 +1331,8 @@ static void init_right_tree(void) · 368 unmodified lines | |||
| 1393 | g_signal_connect(G_OBJECT(renderer), "edited", | 1331 | g_signal_connect(G_OBJECT(renderer), "edited", |
| 1394 | G_CALLBACK(renderer_edited), tree2_w); | 1332 | G_CALLBACK(renderer_edited), tree2_w); |
| 1395 | 1333 | ||
| 1334 | pix_menu = gdk_pixbuf_new_from_xpm_data((const char **)xpm_menu); | ||
| 1335 | |||
| 1396 | for (i = 0; i < COL_VALUE; i++) { | 1336 | for (i = 0; i < COL_VALUE; i++) { |
| 1397 | column = gtk_tree_view_get_column(view, i); | 1337 | column = gtk_tree_view_get_column(view, i); |
| 1398 | gtk_tree_view_column_set_resizable(column, TRUE); | 1338 | gtk_tree_view_column_set_resizable(column, TRUE); |