xref: /rk3399_rockchip-uboot/scripts/kconfig/gconf.c (revision 0a9064fb47bb0a239c04b0b63edebfdd3a201fdc)
1*0a9064fbSMasahiro Yamada /* Hey EMACS -*- linux-c -*- */
2*0a9064fbSMasahiro Yamada /*
3*0a9064fbSMasahiro Yamada  *
4*0a9064fbSMasahiro Yamada  * Copyright (C) 2002-2003 Romain Lievin <roms@tilp.info>
5*0a9064fbSMasahiro Yamada  * Released under the terms of the GNU GPL v2.0.
6*0a9064fbSMasahiro Yamada  *
7*0a9064fbSMasahiro Yamada  */
8*0a9064fbSMasahiro Yamada 
9*0a9064fbSMasahiro Yamada #ifdef HAVE_CONFIG_H
10*0a9064fbSMasahiro Yamada #  include <config.h>
11*0a9064fbSMasahiro Yamada #endif
12*0a9064fbSMasahiro Yamada 
13*0a9064fbSMasahiro Yamada #include <stdlib.h>
14*0a9064fbSMasahiro Yamada #include "lkc.h"
15*0a9064fbSMasahiro Yamada #include "images.c"
16*0a9064fbSMasahiro Yamada 
17*0a9064fbSMasahiro Yamada #include <glade/glade.h>
18*0a9064fbSMasahiro Yamada #include <gtk/gtk.h>
19*0a9064fbSMasahiro Yamada #include <glib.h>
20*0a9064fbSMasahiro Yamada #include <gdk/gdkkeysyms.h>
21*0a9064fbSMasahiro Yamada 
22*0a9064fbSMasahiro Yamada #include <stdio.h>
23*0a9064fbSMasahiro Yamada #include <string.h>
24*0a9064fbSMasahiro Yamada #include <unistd.h>
25*0a9064fbSMasahiro Yamada #include <time.h>
26*0a9064fbSMasahiro Yamada 
27*0a9064fbSMasahiro Yamada //#define DEBUG
28*0a9064fbSMasahiro Yamada 
29*0a9064fbSMasahiro Yamada enum {
30*0a9064fbSMasahiro Yamada 	SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW
31*0a9064fbSMasahiro Yamada };
32*0a9064fbSMasahiro Yamada 
33*0a9064fbSMasahiro Yamada enum {
34*0a9064fbSMasahiro Yamada 	OPT_NORMAL, OPT_ALL, OPT_PROMPT
35*0a9064fbSMasahiro Yamada };
36*0a9064fbSMasahiro Yamada 
37*0a9064fbSMasahiro Yamada static gint view_mode = FULL_VIEW;
38*0a9064fbSMasahiro Yamada static gboolean show_name = TRUE;
39*0a9064fbSMasahiro Yamada static gboolean show_range = TRUE;
40*0a9064fbSMasahiro Yamada static gboolean show_value = TRUE;
41*0a9064fbSMasahiro Yamada static gboolean resizeable = FALSE;
42*0a9064fbSMasahiro Yamada static int opt_mode = OPT_NORMAL;
43*0a9064fbSMasahiro Yamada 
44*0a9064fbSMasahiro Yamada GtkWidget *main_wnd = NULL;
45*0a9064fbSMasahiro Yamada GtkWidget *tree1_w = NULL;	// left  frame
46*0a9064fbSMasahiro Yamada GtkWidget *tree2_w = NULL;	// right frame
47*0a9064fbSMasahiro Yamada GtkWidget *text_w = NULL;
48*0a9064fbSMasahiro Yamada GtkWidget *hpaned = NULL;
49*0a9064fbSMasahiro Yamada GtkWidget *vpaned = NULL;
50*0a9064fbSMasahiro Yamada GtkWidget *back_btn = NULL;
51*0a9064fbSMasahiro Yamada GtkWidget *save_btn = NULL;
52*0a9064fbSMasahiro Yamada GtkWidget *save_menu_item = NULL;
53*0a9064fbSMasahiro Yamada 
54*0a9064fbSMasahiro Yamada GtkTextTag *tag1, *tag2;
55*0a9064fbSMasahiro Yamada GdkColor color;
56*0a9064fbSMasahiro Yamada 
57*0a9064fbSMasahiro Yamada GtkTreeStore *tree1, *tree2, *tree;
58*0a9064fbSMasahiro Yamada GtkTreeModel *model1, *model2;
59*0a9064fbSMasahiro Yamada static GtkTreeIter *parents[256];
60*0a9064fbSMasahiro Yamada static gint indent;
61*0a9064fbSMasahiro Yamada 
62*0a9064fbSMasahiro Yamada static struct menu *current; // current node for SINGLE view
63*0a9064fbSMasahiro Yamada static struct menu *browsed; // browsed node for SPLIT view
64*0a9064fbSMasahiro Yamada 
65*0a9064fbSMasahiro Yamada enum {
66*0a9064fbSMasahiro Yamada 	COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE,
67*0a9064fbSMasahiro Yamada 	COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF,
68*0a9064fbSMasahiro Yamada 	COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD,
69*0a9064fbSMasahiro Yamada 	COL_NUMBER
70*0a9064fbSMasahiro Yamada };
71*0a9064fbSMasahiro Yamada 
72*0a9064fbSMasahiro Yamada static void display_list(void);
73*0a9064fbSMasahiro Yamada static void display_tree(struct menu *menu);
74*0a9064fbSMasahiro Yamada static void display_tree_part(void);
75*0a9064fbSMasahiro Yamada static void update_tree(struct menu *src, GtkTreeIter * dst);
76*0a9064fbSMasahiro Yamada static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row);
77*0a9064fbSMasahiro Yamada static gchar **fill_row(struct menu *menu);
78*0a9064fbSMasahiro Yamada static void conf_changed(void);
79*0a9064fbSMasahiro Yamada 
80*0a9064fbSMasahiro Yamada /* Helping/Debugging Functions */
81*0a9064fbSMasahiro Yamada 
82*0a9064fbSMasahiro Yamada const char *dbg_sym_flags(int val)
83*0a9064fbSMasahiro Yamada {
84*0a9064fbSMasahiro Yamada 	static char buf[256];
85*0a9064fbSMasahiro Yamada 
86*0a9064fbSMasahiro Yamada 	bzero(buf, 256);
87*0a9064fbSMasahiro Yamada 
88*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_CONST)
89*0a9064fbSMasahiro Yamada 		strcat(buf, "const/");
90*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_CHECK)
91*0a9064fbSMasahiro Yamada 		strcat(buf, "check/");
92*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_CHOICE)
93*0a9064fbSMasahiro Yamada 		strcat(buf, "choice/");
94*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_CHOICEVAL)
95*0a9064fbSMasahiro Yamada 		strcat(buf, "choiceval/");
96*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_VALID)
97*0a9064fbSMasahiro Yamada 		strcat(buf, "valid/");
98*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_OPTIONAL)
99*0a9064fbSMasahiro Yamada 		strcat(buf, "optional/");
100*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_WRITE)
101*0a9064fbSMasahiro Yamada 		strcat(buf, "write/");
102*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_CHANGED)
103*0a9064fbSMasahiro Yamada 		strcat(buf, "changed/");
104*0a9064fbSMasahiro Yamada 	if (val & SYMBOL_AUTO)
105*0a9064fbSMasahiro Yamada 		strcat(buf, "auto/");
106*0a9064fbSMasahiro Yamada 
107*0a9064fbSMasahiro Yamada 	buf[strlen(buf) - 1] = '\0';
108*0a9064fbSMasahiro Yamada 
109*0a9064fbSMasahiro Yamada 	return buf;
110*0a9064fbSMasahiro Yamada }
111*0a9064fbSMasahiro Yamada 
112*0a9064fbSMasahiro Yamada void replace_button_icon(GladeXML * xml, GdkDrawable * window,
113*0a9064fbSMasahiro Yamada 			 GtkStyle * style, gchar * btn_name, gchar ** xpm)
114*0a9064fbSMasahiro Yamada {
115*0a9064fbSMasahiro Yamada 	GdkPixmap *pixmap;
116*0a9064fbSMasahiro Yamada 	GdkBitmap *mask;
117*0a9064fbSMasahiro Yamada 	GtkToolButton *button;
118*0a9064fbSMasahiro Yamada 	GtkWidget *image;
119*0a9064fbSMasahiro Yamada 
120*0a9064fbSMasahiro Yamada 	pixmap = gdk_pixmap_create_from_xpm_d(window, &mask,
121*0a9064fbSMasahiro Yamada 					      &style->bg[GTK_STATE_NORMAL],
122*0a9064fbSMasahiro Yamada 					      xpm);
123*0a9064fbSMasahiro Yamada 
124*0a9064fbSMasahiro Yamada 	button = GTK_TOOL_BUTTON(glade_xml_get_widget(xml, btn_name));
125*0a9064fbSMasahiro Yamada 	image = gtk_image_new_from_pixmap(pixmap, mask);
126*0a9064fbSMasahiro Yamada 	gtk_widget_show(image);
127*0a9064fbSMasahiro Yamada 	gtk_tool_button_set_icon_widget(button, image);
128*0a9064fbSMasahiro Yamada }
129*0a9064fbSMasahiro Yamada 
130*0a9064fbSMasahiro Yamada /* Main Window Initialization */
131*0a9064fbSMasahiro Yamada void init_main_window(const gchar * glade_file)
132*0a9064fbSMasahiro Yamada {
133*0a9064fbSMasahiro Yamada 	GladeXML *xml;
134*0a9064fbSMasahiro Yamada 	GtkWidget *widget;
135*0a9064fbSMasahiro Yamada 	GtkTextBuffer *txtbuf;
136*0a9064fbSMasahiro Yamada 	GtkStyle *style;
137*0a9064fbSMasahiro Yamada 
138*0a9064fbSMasahiro Yamada 	xml = glade_xml_new(glade_file, "window1", NULL);
139*0a9064fbSMasahiro Yamada 	if (!xml)
140*0a9064fbSMasahiro Yamada 		g_error(_("GUI loading failed !\n"));
141*0a9064fbSMasahiro Yamada 	glade_xml_signal_autoconnect(xml);
142*0a9064fbSMasahiro Yamada 
143*0a9064fbSMasahiro Yamada 	main_wnd = glade_xml_get_widget(xml, "window1");
144*0a9064fbSMasahiro Yamada 	hpaned = glade_xml_get_widget(xml, "hpaned1");
145*0a9064fbSMasahiro Yamada 	vpaned = glade_xml_get_widget(xml, "vpaned1");
146*0a9064fbSMasahiro Yamada 	tree1_w = glade_xml_get_widget(xml, "treeview1");
147*0a9064fbSMasahiro Yamada 	tree2_w = glade_xml_get_widget(xml, "treeview2");
148*0a9064fbSMasahiro Yamada 	text_w = glade_xml_get_widget(xml, "textview3");
149*0a9064fbSMasahiro Yamada 
150*0a9064fbSMasahiro Yamada 	back_btn = glade_xml_get_widget(xml, "button1");
151*0a9064fbSMasahiro Yamada 	gtk_widget_set_sensitive(back_btn, FALSE);
152*0a9064fbSMasahiro Yamada 
153*0a9064fbSMasahiro Yamada 	widget = glade_xml_get_widget(xml, "show_name1");
154*0a9064fbSMasahiro Yamada 	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
155*0a9064fbSMasahiro Yamada 				       show_name);
156*0a9064fbSMasahiro Yamada 
157*0a9064fbSMasahiro Yamada 	widget = glade_xml_get_widget(xml, "show_range1");
158*0a9064fbSMasahiro Yamada 	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
159*0a9064fbSMasahiro Yamada 				       show_range);
160*0a9064fbSMasahiro Yamada 
161*0a9064fbSMasahiro Yamada 	widget = glade_xml_get_widget(xml, "show_data1");
162*0a9064fbSMasahiro Yamada 	gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
163*0a9064fbSMasahiro Yamada 				       show_value);
164*0a9064fbSMasahiro Yamada 
165*0a9064fbSMasahiro Yamada 	save_btn = glade_xml_get_widget(xml, "button3");
166*0a9064fbSMasahiro Yamada 	save_menu_item = glade_xml_get_widget(xml, "save1");
167*0a9064fbSMasahiro Yamada 	conf_set_changed_callback(conf_changed);
168*0a9064fbSMasahiro Yamada 
169*0a9064fbSMasahiro Yamada 	style = gtk_widget_get_style(main_wnd);
170*0a9064fbSMasahiro Yamada 	widget = glade_xml_get_widget(xml, "toolbar1");
171*0a9064fbSMasahiro Yamada 
172*0a9064fbSMasahiro Yamada #if 0	/* Use stock Gtk icons instead */
173*0a9064fbSMasahiro Yamada 	replace_button_icon(xml, main_wnd->window, style,
174*0a9064fbSMasahiro Yamada 			    "button1", (gchar **) xpm_back);
175*0a9064fbSMasahiro Yamada 	replace_button_icon(xml, main_wnd->window, style,
176*0a9064fbSMasahiro Yamada 			    "button2", (gchar **) xpm_load);
177*0a9064fbSMasahiro Yamada 	replace_button_icon(xml, main_wnd->window, style,
178*0a9064fbSMasahiro Yamada 			    "button3", (gchar **) xpm_save);
179*0a9064fbSMasahiro Yamada #endif
180*0a9064fbSMasahiro Yamada 	replace_button_icon(xml, main_wnd->window, style,
181*0a9064fbSMasahiro Yamada 			    "button4", (gchar **) xpm_single_view);
182*0a9064fbSMasahiro Yamada 	replace_button_icon(xml, main_wnd->window, style,
183*0a9064fbSMasahiro Yamada 			    "button5", (gchar **) xpm_split_view);
184*0a9064fbSMasahiro Yamada 	replace_button_icon(xml, main_wnd->window, style,
185*0a9064fbSMasahiro Yamada 			    "button6", (gchar **) xpm_tree_view);
186*0a9064fbSMasahiro Yamada 
187*0a9064fbSMasahiro Yamada #if 0
188*0a9064fbSMasahiro Yamada 	switch (view_mode) {
189*0a9064fbSMasahiro Yamada 	case SINGLE_VIEW:
190*0a9064fbSMasahiro Yamada 		widget = glade_xml_get_widget(xml, "button4");
191*0a9064fbSMasahiro Yamada 		g_signal_emit_by_name(widget, "clicked");
192*0a9064fbSMasahiro Yamada 		break;
193*0a9064fbSMasahiro Yamada 	case SPLIT_VIEW:
194*0a9064fbSMasahiro Yamada 		widget = glade_xml_get_widget(xml, "button5");
195*0a9064fbSMasahiro Yamada 		g_signal_emit_by_name(widget, "clicked");
196*0a9064fbSMasahiro Yamada 		break;
197*0a9064fbSMasahiro Yamada 	case FULL_VIEW:
198*0a9064fbSMasahiro Yamada 		widget = glade_xml_get_widget(xml, "button6");
199*0a9064fbSMasahiro Yamada 		g_signal_emit_by_name(widget, "clicked");
200*0a9064fbSMasahiro Yamada 		break;
201*0a9064fbSMasahiro Yamada 	}
202*0a9064fbSMasahiro Yamada #endif
203*0a9064fbSMasahiro Yamada 	txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
204*0a9064fbSMasahiro Yamada 	tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
205*0a9064fbSMasahiro Yamada 					  "foreground", "red",
206*0a9064fbSMasahiro Yamada 					  "weight", PANGO_WEIGHT_BOLD,
207*0a9064fbSMasahiro Yamada 					  NULL);
208*0a9064fbSMasahiro Yamada 	tag2 = gtk_text_buffer_create_tag(txtbuf, "mytag2",
209*0a9064fbSMasahiro Yamada 					  /*"style", PANGO_STYLE_OBLIQUE, */
210*0a9064fbSMasahiro Yamada 					  NULL);
211*0a9064fbSMasahiro Yamada 
212*0a9064fbSMasahiro Yamada 	gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text);
213*0a9064fbSMasahiro Yamada 
214*0a9064fbSMasahiro Yamada 	gtk_widget_show(main_wnd);
215*0a9064fbSMasahiro Yamada }
216*0a9064fbSMasahiro Yamada 
217*0a9064fbSMasahiro Yamada void init_tree_model(void)
218*0a9064fbSMasahiro Yamada {
219*0a9064fbSMasahiro Yamada 	gint i;
220*0a9064fbSMasahiro Yamada 
221*0a9064fbSMasahiro Yamada 	tree = tree2 = gtk_tree_store_new(COL_NUMBER,
222*0a9064fbSMasahiro Yamada 					  G_TYPE_STRING, G_TYPE_STRING,
223*0a9064fbSMasahiro Yamada 					  G_TYPE_STRING, G_TYPE_STRING,
224*0a9064fbSMasahiro Yamada 					  G_TYPE_STRING, G_TYPE_STRING,
225*0a9064fbSMasahiro Yamada 					  G_TYPE_POINTER, GDK_TYPE_COLOR,
226*0a9064fbSMasahiro Yamada 					  G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
227*0a9064fbSMasahiro Yamada 					  G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
228*0a9064fbSMasahiro Yamada 					  G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
229*0a9064fbSMasahiro Yamada 					  G_TYPE_BOOLEAN);
230*0a9064fbSMasahiro Yamada 	model2 = GTK_TREE_MODEL(tree2);
231*0a9064fbSMasahiro Yamada 
232*0a9064fbSMasahiro Yamada 	for (parents[0] = NULL, i = 1; i < 256; i++)
233*0a9064fbSMasahiro Yamada 		parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter));
234*0a9064fbSMasahiro Yamada 
235*0a9064fbSMasahiro Yamada 	tree1 = gtk_tree_store_new(COL_NUMBER,
236*0a9064fbSMasahiro Yamada 				   G_TYPE_STRING, G_TYPE_STRING,
237*0a9064fbSMasahiro Yamada 				   G_TYPE_STRING, G_TYPE_STRING,
238*0a9064fbSMasahiro Yamada 				   G_TYPE_STRING, G_TYPE_STRING,
239*0a9064fbSMasahiro Yamada 				   G_TYPE_POINTER, GDK_TYPE_COLOR,
240*0a9064fbSMasahiro Yamada 				   G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
241*0a9064fbSMasahiro Yamada 				   G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
242*0a9064fbSMasahiro Yamada 				   G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
243*0a9064fbSMasahiro Yamada 				   G_TYPE_BOOLEAN);
244*0a9064fbSMasahiro Yamada 	model1 = GTK_TREE_MODEL(tree1);
245*0a9064fbSMasahiro Yamada }
246*0a9064fbSMasahiro Yamada 
247*0a9064fbSMasahiro Yamada void init_left_tree(void)
248*0a9064fbSMasahiro Yamada {
249*0a9064fbSMasahiro Yamada 	GtkTreeView *view = GTK_TREE_VIEW(tree1_w);
250*0a9064fbSMasahiro Yamada 	GtkCellRenderer *renderer;
251*0a9064fbSMasahiro Yamada 	GtkTreeSelection *sel;
252*0a9064fbSMasahiro Yamada 	GtkTreeViewColumn *column;
253*0a9064fbSMasahiro Yamada 
254*0a9064fbSMasahiro Yamada 	gtk_tree_view_set_model(view, model1);
255*0a9064fbSMasahiro Yamada 	gtk_tree_view_set_headers_visible(view, TRUE);
256*0a9064fbSMasahiro Yamada 	gtk_tree_view_set_rules_hint(view, TRUE);
257*0a9064fbSMasahiro Yamada 
258*0a9064fbSMasahiro Yamada 	column = gtk_tree_view_column_new();
259*0a9064fbSMasahiro Yamada 	gtk_tree_view_append_column(view, column);
260*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_title(column, _("Options"));
261*0a9064fbSMasahiro Yamada 
262*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_toggle_new();
263*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
264*0a9064fbSMasahiro Yamada 					renderer, FALSE);
265*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
266*0a9064fbSMasahiro Yamada 					    renderer,
267*0a9064fbSMasahiro Yamada 					    "active", COL_BTNACT,
268*0a9064fbSMasahiro Yamada 					    "inconsistent", COL_BTNINC,
269*0a9064fbSMasahiro Yamada 					    "visible", COL_BTNVIS,
270*0a9064fbSMasahiro Yamada 					    "radio", COL_BTNRAD, NULL);
271*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_text_new();
272*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
273*0a9064fbSMasahiro Yamada 					renderer, FALSE);
274*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
275*0a9064fbSMasahiro Yamada 					    renderer,
276*0a9064fbSMasahiro Yamada 					    "text", COL_OPTION,
277*0a9064fbSMasahiro Yamada 					    "foreground-gdk",
278*0a9064fbSMasahiro Yamada 					    COL_COLOR, NULL);
279*0a9064fbSMasahiro Yamada 
280*0a9064fbSMasahiro Yamada 	sel = gtk_tree_view_get_selection(view);
281*0a9064fbSMasahiro Yamada 	gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
282*0a9064fbSMasahiro Yamada 	gtk_widget_realize(tree1_w);
283*0a9064fbSMasahiro Yamada }
284*0a9064fbSMasahiro Yamada 
285*0a9064fbSMasahiro Yamada static void renderer_edited(GtkCellRendererText * cell,
286*0a9064fbSMasahiro Yamada 			    const gchar * path_string,
287*0a9064fbSMasahiro Yamada 			    const gchar * new_text, gpointer user_data);
288*0a9064fbSMasahiro Yamada 
289*0a9064fbSMasahiro Yamada void init_right_tree(void)
290*0a9064fbSMasahiro Yamada {
291*0a9064fbSMasahiro Yamada 	GtkTreeView *view = GTK_TREE_VIEW(tree2_w);
292*0a9064fbSMasahiro Yamada 	GtkCellRenderer *renderer;
293*0a9064fbSMasahiro Yamada 	GtkTreeSelection *sel;
294*0a9064fbSMasahiro Yamada 	GtkTreeViewColumn *column;
295*0a9064fbSMasahiro Yamada 	gint i;
296*0a9064fbSMasahiro Yamada 
297*0a9064fbSMasahiro Yamada 	gtk_tree_view_set_model(view, model2);
298*0a9064fbSMasahiro Yamada 	gtk_tree_view_set_headers_visible(view, TRUE);
299*0a9064fbSMasahiro Yamada 	gtk_tree_view_set_rules_hint(view, TRUE);
300*0a9064fbSMasahiro Yamada 
301*0a9064fbSMasahiro Yamada 	column = gtk_tree_view_column_new();
302*0a9064fbSMasahiro Yamada 	gtk_tree_view_append_column(view, column);
303*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_title(column, _("Options"));
304*0a9064fbSMasahiro Yamada 
305*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_pixbuf_new();
306*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
307*0a9064fbSMasahiro Yamada 					renderer, FALSE);
308*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
309*0a9064fbSMasahiro Yamada 					    renderer,
310*0a9064fbSMasahiro Yamada 					    "pixbuf", COL_PIXBUF,
311*0a9064fbSMasahiro Yamada 					    "visible", COL_PIXVIS, NULL);
312*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_toggle_new();
313*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
314*0a9064fbSMasahiro Yamada 					renderer, FALSE);
315*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
316*0a9064fbSMasahiro Yamada 					    renderer,
317*0a9064fbSMasahiro Yamada 					    "active", COL_BTNACT,
318*0a9064fbSMasahiro Yamada 					    "inconsistent", COL_BTNINC,
319*0a9064fbSMasahiro Yamada 					    "visible", COL_BTNVIS,
320*0a9064fbSMasahiro Yamada 					    "radio", COL_BTNRAD, NULL);
321*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_text_new();
322*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
323*0a9064fbSMasahiro Yamada 					renderer, FALSE);
324*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
325*0a9064fbSMasahiro Yamada 					    renderer,
326*0a9064fbSMasahiro Yamada 					    "text", COL_OPTION,
327*0a9064fbSMasahiro Yamada 					    "foreground-gdk",
328*0a9064fbSMasahiro Yamada 					    COL_COLOR, NULL);
329*0a9064fbSMasahiro Yamada 
330*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_text_new();
331*0a9064fbSMasahiro Yamada 	gtk_tree_view_insert_column_with_attributes(view, -1,
332*0a9064fbSMasahiro Yamada 						    _("Name"), renderer,
333*0a9064fbSMasahiro Yamada 						    "text", COL_NAME,
334*0a9064fbSMasahiro Yamada 						    "foreground-gdk",
335*0a9064fbSMasahiro Yamada 						    COL_COLOR, NULL);
336*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_text_new();
337*0a9064fbSMasahiro Yamada 	gtk_tree_view_insert_column_with_attributes(view, -1,
338*0a9064fbSMasahiro Yamada 						    "N", renderer,
339*0a9064fbSMasahiro Yamada 						    "text", COL_NO,
340*0a9064fbSMasahiro Yamada 						    "foreground-gdk",
341*0a9064fbSMasahiro Yamada 						    COL_COLOR, NULL);
342*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_text_new();
343*0a9064fbSMasahiro Yamada 	gtk_tree_view_insert_column_with_attributes(view, -1,
344*0a9064fbSMasahiro Yamada 						    "M", renderer,
345*0a9064fbSMasahiro Yamada 						    "text", COL_MOD,
346*0a9064fbSMasahiro Yamada 						    "foreground-gdk",
347*0a9064fbSMasahiro Yamada 						    COL_COLOR, NULL);
348*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_text_new();
349*0a9064fbSMasahiro Yamada 	gtk_tree_view_insert_column_with_attributes(view, -1,
350*0a9064fbSMasahiro Yamada 						    "Y", renderer,
351*0a9064fbSMasahiro Yamada 						    "text", COL_YES,
352*0a9064fbSMasahiro Yamada 						    "foreground-gdk",
353*0a9064fbSMasahiro Yamada 						    COL_COLOR, NULL);
354*0a9064fbSMasahiro Yamada 	renderer = gtk_cell_renderer_text_new();
355*0a9064fbSMasahiro Yamada 	gtk_tree_view_insert_column_with_attributes(view, -1,
356*0a9064fbSMasahiro Yamada 						    _("Value"), renderer,
357*0a9064fbSMasahiro Yamada 						    "text", COL_VALUE,
358*0a9064fbSMasahiro Yamada 						    "editable",
359*0a9064fbSMasahiro Yamada 						    COL_EDIT,
360*0a9064fbSMasahiro Yamada 						    "foreground-gdk",
361*0a9064fbSMasahiro Yamada 						    COL_COLOR, NULL);
362*0a9064fbSMasahiro Yamada 	g_signal_connect(G_OBJECT(renderer), "edited",
363*0a9064fbSMasahiro Yamada 			 G_CALLBACK(renderer_edited), NULL);
364*0a9064fbSMasahiro Yamada 
365*0a9064fbSMasahiro Yamada 	column = gtk_tree_view_get_column(view, COL_NAME);
366*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_visible(column, show_name);
367*0a9064fbSMasahiro Yamada 	column = gtk_tree_view_get_column(view, COL_NO);
368*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_visible(column, show_range);
369*0a9064fbSMasahiro Yamada 	column = gtk_tree_view_get_column(view, COL_MOD);
370*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_visible(column, show_range);
371*0a9064fbSMasahiro Yamada 	column = gtk_tree_view_get_column(view, COL_YES);
372*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_visible(column, show_range);
373*0a9064fbSMasahiro Yamada 	column = gtk_tree_view_get_column(view, COL_VALUE);
374*0a9064fbSMasahiro Yamada 	gtk_tree_view_column_set_visible(column, show_value);
375*0a9064fbSMasahiro Yamada 
376*0a9064fbSMasahiro Yamada 	if (resizeable) {
377*0a9064fbSMasahiro Yamada 		for (i = 0; i < COL_VALUE; i++) {
378*0a9064fbSMasahiro Yamada 			column = gtk_tree_view_get_column(view, i);
379*0a9064fbSMasahiro Yamada 			gtk_tree_view_column_set_resizable(column, TRUE);
380*0a9064fbSMasahiro Yamada 		}
381*0a9064fbSMasahiro Yamada 	}
382*0a9064fbSMasahiro Yamada 
383*0a9064fbSMasahiro Yamada 	sel = gtk_tree_view_get_selection(view);
384*0a9064fbSMasahiro Yamada 	gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
385*0a9064fbSMasahiro Yamada }
386*0a9064fbSMasahiro Yamada 
387*0a9064fbSMasahiro Yamada 
388*0a9064fbSMasahiro Yamada /* Utility Functions */
389*0a9064fbSMasahiro Yamada 
390*0a9064fbSMasahiro Yamada 
391*0a9064fbSMasahiro Yamada static void text_insert_help(struct menu *menu)
392*0a9064fbSMasahiro Yamada {
393*0a9064fbSMasahiro Yamada 	GtkTextBuffer *buffer;
394*0a9064fbSMasahiro Yamada 	GtkTextIter start, end;
395*0a9064fbSMasahiro Yamada 	const char *prompt = _(menu_get_prompt(menu));
396*0a9064fbSMasahiro Yamada 	struct gstr help = str_new();
397*0a9064fbSMasahiro Yamada 
398*0a9064fbSMasahiro Yamada 	menu_get_ext_help(menu, &help);
399*0a9064fbSMasahiro Yamada 
400*0a9064fbSMasahiro Yamada 	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
401*0a9064fbSMasahiro Yamada 	gtk_text_buffer_get_bounds(buffer, &start, &end);
402*0a9064fbSMasahiro Yamada 	gtk_text_buffer_delete(buffer, &start, &end);
403*0a9064fbSMasahiro Yamada 	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
404*0a9064fbSMasahiro Yamada 
405*0a9064fbSMasahiro Yamada 	gtk_text_buffer_get_end_iter(buffer, &end);
406*0a9064fbSMasahiro Yamada 	gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1,
407*0a9064fbSMasahiro Yamada 					 NULL);
408*0a9064fbSMasahiro Yamada 	gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
409*0a9064fbSMasahiro Yamada 	gtk_text_buffer_get_end_iter(buffer, &end);
410*0a9064fbSMasahiro Yamada 	gtk_text_buffer_insert_with_tags(buffer, &end, str_get(&help), -1, tag2,
411*0a9064fbSMasahiro Yamada 					 NULL);
412*0a9064fbSMasahiro Yamada 	str_free(&help);
413*0a9064fbSMasahiro Yamada }
414*0a9064fbSMasahiro Yamada 
415*0a9064fbSMasahiro Yamada 
416*0a9064fbSMasahiro Yamada static void text_insert_msg(const char *title, const char *message)
417*0a9064fbSMasahiro Yamada {
418*0a9064fbSMasahiro Yamada 	GtkTextBuffer *buffer;
419*0a9064fbSMasahiro Yamada 	GtkTextIter start, end;
420*0a9064fbSMasahiro Yamada 	const char *msg = message;
421*0a9064fbSMasahiro Yamada 
422*0a9064fbSMasahiro Yamada 	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
423*0a9064fbSMasahiro Yamada 	gtk_text_buffer_get_bounds(buffer, &start, &end);
424*0a9064fbSMasahiro Yamada 	gtk_text_buffer_delete(buffer, &start, &end);
425*0a9064fbSMasahiro Yamada 	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15);
426*0a9064fbSMasahiro Yamada 
427*0a9064fbSMasahiro Yamada 	gtk_text_buffer_get_end_iter(buffer, &end);
428*0a9064fbSMasahiro Yamada 	gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1,
429*0a9064fbSMasahiro Yamada 					 NULL);
430*0a9064fbSMasahiro Yamada 	gtk_text_buffer_insert_at_cursor(buffer, "\n\n", 2);
431*0a9064fbSMasahiro Yamada 	gtk_text_buffer_get_end_iter(buffer, &end);
432*0a9064fbSMasahiro Yamada 	gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1, tag2,
433*0a9064fbSMasahiro Yamada 					 NULL);
434*0a9064fbSMasahiro Yamada }
435*0a9064fbSMasahiro Yamada 
436*0a9064fbSMasahiro Yamada 
437*0a9064fbSMasahiro Yamada /* Main Windows Callbacks */
438*0a9064fbSMasahiro Yamada 
439*0a9064fbSMasahiro Yamada void on_save_activate(GtkMenuItem * menuitem, gpointer user_data);
440*0a9064fbSMasahiro Yamada gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
441*0a9064fbSMasahiro Yamada 				 gpointer user_data)
442*0a9064fbSMasahiro Yamada {
443*0a9064fbSMasahiro Yamada 	GtkWidget *dialog, *label;
444*0a9064fbSMasahiro Yamada 	gint result;
445*0a9064fbSMasahiro Yamada 
446*0a9064fbSMasahiro Yamada 	if (!conf_get_changed())
447*0a9064fbSMasahiro Yamada 		return FALSE;
448*0a9064fbSMasahiro Yamada 
449*0a9064fbSMasahiro Yamada 	dialog = gtk_dialog_new_with_buttons(_("Warning !"),
450*0a9064fbSMasahiro Yamada 					     GTK_WINDOW(main_wnd),
451*0a9064fbSMasahiro Yamada 					     (GtkDialogFlags)
452*0a9064fbSMasahiro Yamada 					     (GTK_DIALOG_MODAL |
453*0a9064fbSMasahiro Yamada 					      GTK_DIALOG_DESTROY_WITH_PARENT),
454*0a9064fbSMasahiro Yamada 					     GTK_STOCK_OK,
455*0a9064fbSMasahiro Yamada 					     GTK_RESPONSE_YES,
456*0a9064fbSMasahiro Yamada 					     GTK_STOCK_NO,
457*0a9064fbSMasahiro Yamada 					     GTK_RESPONSE_NO,
458*0a9064fbSMasahiro Yamada 					     GTK_STOCK_CANCEL,
459*0a9064fbSMasahiro Yamada 					     GTK_RESPONSE_CANCEL, NULL);
460*0a9064fbSMasahiro Yamada 	gtk_dialog_set_default_response(GTK_DIALOG(dialog),
461*0a9064fbSMasahiro Yamada 					GTK_RESPONSE_CANCEL);
462*0a9064fbSMasahiro Yamada 
463*0a9064fbSMasahiro Yamada 	label = gtk_label_new(_("\nSave configuration ?\n"));
464*0a9064fbSMasahiro Yamada 	gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
465*0a9064fbSMasahiro Yamada 	gtk_widget_show(label);
466*0a9064fbSMasahiro Yamada 
467*0a9064fbSMasahiro Yamada 	result = gtk_dialog_run(GTK_DIALOG(dialog));
468*0a9064fbSMasahiro Yamada 	switch (result) {
469*0a9064fbSMasahiro Yamada 	case GTK_RESPONSE_YES:
470*0a9064fbSMasahiro Yamada 		on_save_activate(NULL, NULL);
471*0a9064fbSMasahiro Yamada 		return FALSE;
472*0a9064fbSMasahiro Yamada 	case GTK_RESPONSE_NO:
473*0a9064fbSMasahiro Yamada 		return FALSE;
474*0a9064fbSMasahiro Yamada 	case GTK_RESPONSE_CANCEL:
475*0a9064fbSMasahiro Yamada 	case GTK_RESPONSE_DELETE_EVENT:
476*0a9064fbSMasahiro Yamada 	default:
477*0a9064fbSMasahiro Yamada 		gtk_widget_destroy(dialog);
478*0a9064fbSMasahiro Yamada 		return TRUE;
479*0a9064fbSMasahiro Yamada 	}
480*0a9064fbSMasahiro Yamada 
481*0a9064fbSMasahiro Yamada 	return FALSE;
482*0a9064fbSMasahiro Yamada }
483*0a9064fbSMasahiro Yamada 
484*0a9064fbSMasahiro Yamada 
485*0a9064fbSMasahiro Yamada void on_window1_destroy(GtkObject * object, gpointer user_data)
486*0a9064fbSMasahiro Yamada {
487*0a9064fbSMasahiro Yamada 	gtk_main_quit();
488*0a9064fbSMasahiro Yamada }
489*0a9064fbSMasahiro Yamada 
490*0a9064fbSMasahiro Yamada 
491*0a9064fbSMasahiro Yamada void
492*0a9064fbSMasahiro Yamada on_window1_size_request(GtkWidget * widget,
493*0a9064fbSMasahiro Yamada 			GtkRequisition * requisition, gpointer user_data)
494*0a9064fbSMasahiro Yamada {
495*0a9064fbSMasahiro Yamada 	static gint old_h;
496*0a9064fbSMasahiro Yamada 	gint w, h;
497*0a9064fbSMasahiro Yamada 
498*0a9064fbSMasahiro Yamada 	if (widget->window == NULL)
499*0a9064fbSMasahiro Yamada 		gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
500*0a9064fbSMasahiro Yamada 	else
501*0a9064fbSMasahiro Yamada 		gdk_window_get_size(widget->window, &w, &h);
502*0a9064fbSMasahiro Yamada 
503*0a9064fbSMasahiro Yamada 	if (h == old_h)
504*0a9064fbSMasahiro Yamada 		return;
505*0a9064fbSMasahiro Yamada 	old_h = h;
506*0a9064fbSMasahiro Yamada 
507*0a9064fbSMasahiro Yamada 	gtk_paned_set_position(GTK_PANED(vpaned), 2 * h / 3);
508*0a9064fbSMasahiro Yamada }
509*0a9064fbSMasahiro Yamada 
510*0a9064fbSMasahiro Yamada 
511*0a9064fbSMasahiro Yamada /* Menu & Toolbar Callbacks */
512*0a9064fbSMasahiro Yamada 
513*0a9064fbSMasahiro Yamada 
514*0a9064fbSMasahiro Yamada static void
515*0a9064fbSMasahiro Yamada load_filename(GtkFileSelection * file_selector, gpointer user_data)
516*0a9064fbSMasahiro Yamada {
517*0a9064fbSMasahiro Yamada 	const gchar *fn;
518*0a9064fbSMasahiro Yamada 
519*0a9064fbSMasahiro Yamada 	fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
520*0a9064fbSMasahiro Yamada 					     (user_data));
521*0a9064fbSMasahiro Yamada 
522*0a9064fbSMasahiro Yamada 	if (conf_read(fn))
523*0a9064fbSMasahiro Yamada 		text_insert_msg(_("Error"), _("Unable to load configuration !"));
524*0a9064fbSMasahiro Yamada 	else
525*0a9064fbSMasahiro Yamada 		display_tree(&rootmenu);
526*0a9064fbSMasahiro Yamada }
527*0a9064fbSMasahiro Yamada 
528*0a9064fbSMasahiro Yamada void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
529*0a9064fbSMasahiro Yamada {
530*0a9064fbSMasahiro Yamada 	GtkWidget *fs;
531*0a9064fbSMasahiro Yamada 
532*0a9064fbSMasahiro Yamada 	fs = gtk_file_selection_new(_("Load file..."));
533*0a9064fbSMasahiro Yamada 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
534*0a9064fbSMasahiro Yamada 			 "clicked",
535*0a9064fbSMasahiro Yamada 			 G_CALLBACK(load_filename), (gpointer) fs);
536*0a9064fbSMasahiro Yamada 	g_signal_connect_swapped(GTK_OBJECT
537*0a9064fbSMasahiro Yamada 				 (GTK_FILE_SELECTION(fs)->ok_button),
538*0a9064fbSMasahiro Yamada 				 "clicked", G_CALLBACK(gtk_widget_destroy),
539*0a9064fbSMasahiro Yamada 				 (gpointer) fs);
540*0a9064fbSMasahiro Yamada 	g_signal_connect_swapped(GTK_OBJECT
541*0a9064fbSMasahiro Yamada 				 (GTK_FILE_SELECTION(fs)->cancel_button),
542*0a9064fbSMasahiro Yamada 				 "clicked", G_CALLBACK(gtk_widget_destroy),
543*0a9064fbSMasahiro Yamada 				 (gpointer) fs);
544*0a9064fbSMasahiro Yamada 	gtk_widget_show(fs);
545*0a9064fbSMasahiro Yamada }
546*0a9064fbSMasahiro Yamada 
547*0a9064fbSMasahiro Yamada 
548*0a9064fbSMasahiro Yamada void on_save_activate(GtkMenuItem * menuitem, gpointer user_data)
549*0a9064fbSMasahiro Yamada {
550*0a9064fbSMasahiro Yamada 	if (conf_write(NULL))
551*0a9064fbSMasahiro Yamada 		text_insert_msg(_("Error"), _("Unable to save configuration !"));
552*0a9064fbSMasahiro Yamada }
553*0a9064fbSMasahiro Yamada 
554*0a9064fbSMasahiro Yamada 
555*0a9064fbSMasahiro Yamada static void
556*0a9064fbSMasahiro Yamada store_filename(GtkFileSelection * file_selector, gpointer user_data)
557*0a9064fbSMasahiro Yamada {
558*0a9064fbSMasahiro Yamada 	const gchar *fn;
559*0a9064fbSMasahiro Yamada 
560*0a9064fbSMasahiro Yamada 	fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
561*0a9064fbSMasahiro Yamada 					     (user_data));
562*0a9064fbSMasahiro Yamada 
563*0a9064fbSMasahiro Yamada 	if (conf_write(fn))
564*0a9064fbSMasahiro Yamada 		text_insert_msg(_("Error"), _("Unable to save configuration !"));
565*0a9064fbSMasahiro Yamada 
566*0a9064fbSMasahiro Yamada 	gtk_widget_destroy(GTK_WIDGET(user_data));
567*0a9064fbSMasahiro Yamada }
568*0a9064fbSMasahiro Yamada 
569*0a9064fbSMasahiro Yamada void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
570*0a9064fbSMasahiro Yamada {
571*0a9064fbSMasahiro Yamada 	GtkWidget *fs;
572*0a9064fbSMasahiro Yamada 
573*0a9064fbSMasahiro Yamada 	fs = gtk_file_selection_new(_("Save file as..."));
574*0a9064fbSMasahiro Yamada 	g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
575*0a9064fbSMasahiro Yamada 			 "clicked",
576*0a9064fbSMasahiro Yamada 			 G_CALLBACK(store_filename), (gpointer) fs);
577*0a9064fbSMasahiro Yamada 	g_signal_connect_swapped(GTK_OBJECT
578*0a9064fbSMasahiro Yamada 				 (GTK_FILE_SELECTION(fs)->ok_button),
579*0a9064fbSMasahiro Yamada 				 "clicked", G_CALLBACK(gtk_widget_destroy),
580*0a9064fbSMasahiro Yamada 				 (gpointer) fs);
581*0a9064fbSMasahiro Yamada 	g_signal_connect_swapped(GTK_OBJECT
582*0a9064fbSMasahiro Yamada 				 (GTK_FILE_SELECTION(fs)->cancel_button),
583*0a9064fbSMasahiro Yamada 				 "clicked", G_CALLBACK(gtk_widget_destroy),
584*0a9064fbSMasahiro Yamada 				 (gpointer) fs);
585*0a9064fbSMasahiro Yamada 	gtk_widget_show(fs);
586*0a9064fbSMasahiro Yamada }
587*0a9064fbSMasahiro Yamada 
588*0a9064fbSMasahiro Yamada 
589*0a9064fbSMasahiro Yamada void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
590*0a9064fbSMasahiro Yamada {
591*0a9064fbSMasahiro Yamada 	if (!on_window1_delete_event(NULL, NULL, NULL))
592*0a9064fbSMasahiro Yamada 		gtk_widget_destroy(GTK_WIDGET(main_wnd));
593*0a9064fbSMasahiro Yamada }
594*0a9064fbSMasahiro Yamada 
595*0a9064fbSMasahiro Yamada 
596*0a9064fbSMasahiro Yamada void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
597*0a9064fbSMasahiro Yamada {
598*0a9064fbSMasahiro Yamada 	GtkTreeViewColumn *col;
599*0a9064fbSMasahiro Yamada 
600*0a9064fbSMasahiro Yamada 	show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
601*0a9064fbSMasahiro Yamada 	col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME);
602*0a9064fbSMasahiro Yamada 	if (col)
603*0a9064fbSMasahiro Yamada 		gtk_tree_view_column_set_visible(col, show_name);
604*0a9064fbSMasahiro Yamada }
605*0a9064fbSMasahiro Yamada 
606*0a9064fbSMasahiro Yamada 
607*0a9064fbSMasahiro Yamada void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
608*0a9064fbSMasahiro Yamada {
609*0a9064fbSMasahiro Yamada 	GtkTreeViewColumn *col;
610*0a9064fbSMasahiro Yamada 
611*0a9064fbSMasahiro Yamada 	show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
612*0a9064fbSMasahiro Yamada 	col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO);
613*0a9064fbSMasahiro Yamada 	if (col)
614*0a9064fbSMasahiro Yamada 		gtk_tree_view_column_set_visible(col, show_range);
615*0a9064fbSMasahiro Yamada 	col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD);
616*0a9064fbSMasahiro Yamada 	if (col)
617*0a9064fbSMasahiro Yamada 		gtk_tree_view_column_set_visible(col, show_range);
618*0a9064fbSMasahiro Yamada 	col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES);
619*0a9064fbSMasahiro Yamada 	if (col)
620*0a9064fbSMasahiro Yamada 		gtk_tree_view_column_set_visible(col, show_range);
621*0a9064fbSMasahiro Yamada 
622*0a9064fbSMasahiro Yamada }
623*0a9064fbSMasahiro Yamada 
624*0a9064fbSMasahiro Yamada 
625*0a9064fbSMasahiro Yamada void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
626*0a9064fbSMasahiro Yamada {
627*0a9064fbSMasahiro Yamada 	GtkTreeViewColumn *col;
628*0a9064fbSMasahiro Yamada 
629*0a9064fbSMasahiro Yamada 	show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
630*0a9064fbSMasahiro Yamada 	col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE);
631*0a9064fbSMasahiro Yamada 	if (col)
632*0a9064fbSMasahiro Yamada 		gtk_tree_view_column_set_visible(col, show_value);
633*0a9064fbSMasahiro Yamada }
634*0a9064fbSMasahiro Yamada 
635*0a9064fbSMasahiro Yamada 
636*0a9064fbSMasahiro Yamada void
637*0a9064fbSMasahiro Yamada on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data)
638*0a9064fbSMasahiro Yamada {
639*0a9064fbSMasahiro Yamada 	opt_mode = OPT_NORMAL;
640*0a9064fbSMasahiro Yamada 	gtk_tree_store_clear(tree2);
641*0a9064fbSMasahiro Yamada 	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
642*0a9064fbSMasahiro Yamada }
643*0a9064fbSMasahiro Yamada 
644*0a9064fbSMasahiro Yamada 
645*0a9064fbSMasahiro Yamada void
646*0a9064fbSMasahiro Yamada on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data)
647*0a9064fbSMasahiro Yamada {
648*0a9064fbSMasahiro Yamada 	opt_mode = OPT_ALL;
649*0a9064fbSMasahiro Yamada 	gtk_tree_store_clear(tree2);
650*0a9064fbSMasahiro Yamada 	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
651*0a9064fbSMasahiro Yamada }
652*0a9064fbSMasahiro Yamada 
653*0a9064fbSMasahiro Yamada 
654*0a9064fbSMasahiro Yamada void
655*0a9064fbSMasahiro Yamada on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data)
656*0a9064fbSMasahiro Yamada {
657*0a9064fbSMasahiro Yamada 	opt_mode = OPT_PROMPT;
658*0a9064fbSMasahiro Yamada 	gtk_tree_store_clear(tree2);
659*0a9064fbSMasahiro Yamada 	display_tree(&rootmenu);	/* instead of update_tree to speed-up */
660*0a9064fbSMasahiro Yamada }
661*0a9064fbSMasahiro Yamada 
662*0a9064fbSMasahiro Yamada 
663*0a9064fbSMasahiro Yamada void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
664*0a9064fbSMasahiro Yamada {
665*0a9064fbSMasahiro Yamada 	GtkWidget *dialog;
666*0a9064fbSMasahiro Yamada 	const gchar *intro_text = _(
667*0a9064fbSMasahiro Yamada 	    "Welcome to gkc, the GTK+ graphical configuration tool\n"
668*0a9064fbSMasahiro Yamada 	    "For each option, a blank box indicates the feature is disabled, a\n"
669*0a9064fbSMasahiro Yamada 	    "check indicates it is enabled, and a dot indicates that it is to\n"
670*0a9064fbSMasahiro Yamada 	    "be compiled as a module.  Clicking on the box will cycle through the three states.\n"
671*0a9064fbSMasahiro Yamada 	    "\n"
672*0a9064fbSMasahiro Yamada 	    "If you do not see an option (e.g., a device driver) that you\n"
673*0a9064fbSMasahiro Yamada 	    "believe should be present, try turning on Show All Options\n"
674*0a9064fbSMasahiro Yamada 	    "under the Options menu.\n"
675*0a9064fbSMasahiro Yamada 	    "Although there is no cross reference yet to help you figure out\n"
676*0a9064fbSMasahiro Yamada 	    "what other options must be enabled to support the option you\n"
677*0a9064fbSMasahiro Yamada 	    "are interested in, you can still view the help of a grayed-out\n"
678*0a9064fbSMasahiro Yamada 	    "option.\n"
679*0a9064fbSMasahiro Yamada 	    "\n"
680*0a9064fbSMasahiro Yamada 	    "Toggling Show Debug Info under the Options menu will show \n"
681*0a9064fbSMasahiro Yamada 	    "the dependencies, which you can then match by examining other options.");
682*0a9064fbSMasahiro Yamada 
683*0a9064fbSMasahiro Yamada 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
684*0a9064fbSMasahiro Yamada 					GTK_DIALOG_DESTROY_WITH_PARENT,
685*0a9064fbSMasahiro Yamada 					GTK_MESSAGE_INFO,
686*0a9064fbSMasahiro Yamada 					GTK_BUTTONS_CLOSE, "%s", intro_text);
687*0a9064fbSMasahiro Yamada 	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
688*0a9064fbSMasahiro Yamada 				 G_CALLBACK(gtk_widget_destroy),
689*0a9064fbSMasahiro Yamada 				 GTK_OBJECT(dialog));
690*0a9064fbSMasahiro Yamada 	gtk_widget_show_all(dialog);
691*0a9064fbSMasahiro Yamada }
692*0a9064fbSMasahiro Yamada 
693*0a9064fbSMasahiro Yamada 
694*0a9064fbSMasahiro Yamada void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
695*0a9064fbSMasahiro Yamada {
696*0a9064fbSMasahiro Yamada 	GtkWidget *dialog;
697*0a9064fbSMasahiro Yamada 	const gchar *about_text =
698*0a9064fbSMasahiro Yamada 	    _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
699*0a9064fbSMasahiro Yamada 	      "Based on the source code from Roman Zippel.\n");
700*0a9064fbSMasahiro Yamada 
701*0a9064fbSMasahiro Yamada 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
702*0a9064fbSMasahiro Yamada 					GTK_DIALOG_DESTROY_WITH_PARENT,
703*0a9064fbSMasahiro Yamada 					GTK_MESSAGE_INFO,
704*0a9064fbSMasahiro Yamada 					GTK_BUTTONS_CLOSE, "%s", about_text);
705*0a9064fbSMasahiro Yamada 	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
706*0a9064fbSMasahiro Yamada 				 G_CALLBACK(gtk_widget_destroy),
707*0a9064fbSMasahiro Yamada 				 GTK_OBJECT(dialog));
708*0a9064fbSMasahiro Yamada 	gtk_widget_show_all(dialog);
709*0a9064fbSMasahiro Yamada }
710*0a9064fbSMasahiro Yamada 
711*0a9064fbSMasahiro Yamada 
712*0a9064fbSMasahiro Yamada void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
713*0a9064fbSMasahiro Yamada {
714*0a9064fbSMasahiro Yamada 	GtkWidget *dialog;
715*0a9064fbSMasahiro Yamada 	const gchar *license_text =
716*0a9064fbSMasahiro Yamada 	    _("gkc is released under the terms of the GNU GPL v2.\n"
717*0a9064fbSMasahiro Yamada 	      "For more information, please see the source code or\n"
718*0a9064fbSMasahiro Yamada 	      "visit http://www.fsf.org/licenses/licenses.html\n");
719*0a9064fbSMasahiro Yamada 
720*0a9064fbSMasahiro Yamada 	dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd),
721*0a9064fbSMasahiro Yamada 					GTK_DIALOG_DESTROY_WITH_PARENT,
722*0a9064fbSMasahiro Yamada 					GTK_MESSAGE_INFO,
723*0a9064fbSMasahiro Yamada 					GTK_BUTTONS_CLOSE, "%s", license_text);
724*0a9064fbSMasahiro Yamada 	g_signal_connect_swapped(GTK_OBJECT(dialog), "response",
725*0a9064fbSMasahiro Yamada 				 G_CALLBACK(gtk_widget_destroy),
726*0a9064fbSMasahiro Yamada 				 GTK_OBJECT(dialog));
727*0a9064fbSMasahiro Yamada 	gtk_widget_show_all(dialog);
728*0a9064fbSMasahiro Yamada }
729*0a9064fbSMasahiro Yamada 
730*0a9064fbSMasahiro Yamada 
731*0a9064fbSMasahiro Yamada void on_back_clicked(GtkButton * button, gpointer user_data)
732*0a9064fbSMasahiro Yamada {
733*0a9064fbSMasahiro Yamada 	enum prop_type ptype;
734*0a9064fbSMasahiro Yamada 
735*0a9064fbSMasahiro Yamada 	current = current->parent;
736*0a9064fbSMasahiro Yamada 	ptype = current->prompt ? current->prompt->type : P_UNKNOWN;
737*0a9064fbSMasahiro Yamada 	if (ptype != P_MENU)
738*0a9064fbSMasahiro Yamada 		current = current->parent;
739*0a9064fbSMasahiro Yamada 	display_tree_part();
740*0a9064fbSMasahiro Yamada 
741*0a9064fbSMasahiro Yamada 	if (current == &rootmenu)
742*0a9064fbSMasahiro Yamada 		gtk_widget_set_sensitive(back_btn, FALSE);
743*0a9064fbSMasahiro Yamada }
744*0a9064fbSMasahiro Yamada 
745*0a9064fbSMasahiro Yamada 
746*0a9064fbSMasahiro Yamada void on_load_clicked(GtkButton * button, gpointer user_data)
747*0a9064fbSMasahiro Yamada {
748*0a9064fbSMasahiro Yamada 	on_load1_activate(NULL, user_data);
749*0a9064fbSMasahiro Yamada }
750*0a9064fbSMasahiro Yamada 
751*0a9064fbSMasahiro Yamada 
752*0a9064fbSMasahiro Yamada void on_single_clicked(GtkButton * button, gpointer user_data)
753*0a9064fbSMasahiro Yamada {
754*0a9064fbSMasahiro Yamada 	view_mode = SINGLE_VIEW;
755*0a9064fbSMasahiro Yamada 	gtk_widget_hide(tree1_w);
756*0a9064fbSMasahiro Yamada 	current = &rootmenu;
757*0a9064fbSMasahiro Yamada 	display_tree_part();
758*0a9064fbSMasahiro Yamada }
759*0a9064fbSMasahiro Yamada 
760*0a9064fbSMasahiro Yamada 
761*0a9064fbSMasahiro Yamada void on_split_clicked(GtkButton * button, gpointer user_data)
762*0a9064fbSMasahiro Yamada {
763*0a9064fbSMasahiro Yamada 	gint w, h;
764*0a9064fbSMasahiro Yamada 	view_mode = SPLIT_VIEW;
765*0a9064fbSMasahiro Yamada 	gtk_widget_show(tree1_w);
766*0a9064fbSMasahiro Yamada 	gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h);
767*0a9064fbSMasahiro Yamada 	gtk_paned_set_position(GTK_PANED(hpaned), w / 2);
768*0a9064fbSMasahiro Yamada 	if (tree2)
769*0a9064fbSMasahiro Yamada 		gtk_tree_store_clear(tree2);
770*0a9064fbSMasahiro Yamada 	display_list();
771*0a9064fbSMasahiro Yamada 
772*0a9064fbSMasahiro Yamada 	/* Disable back btn, like in full mode. */
773*0a9064fbSMasahiro Yamada 	gtk_widget_set_sensitive(back_btn, FALSE);
774*0a9064fbSMasahiro Yamada }
775*0a9064fbSMasahiro Yamada 
776*0a9064fbSMasahiro Yamada 
777*0a9064fbSMasahiro Yamada void on_full_clicked(GtkButton * button, gpointer user_data)
778*0a9064fbSMasahiro Yamada {
779*0a9064fbSMasahiro Yamada 	view_mode = FULL_VIEW;
780*0a9064fbSMasahiro Yamada 	gtk_widget_hide(tree1_w);
781*0a9064fbSMasahiro Yamada 	if (tree2)
782*0a9064fbSMasahiro Yamada 		gtk_tree_store_clear(tree2);
783*0a9064fbSMasahiro Yamada 	display_tree(&rootmenu);
784*0a9064fbSMasahiro Yamada 	gtk_widget_set_sensitive(back_btn, FALSE);
785*0a9064fbSMasahiro Yamada }
786*0a9064fbSMasahiro Yamada 
787*0a9064fbSMasahiro Yamada 
788*0a9064fbSMasahiro Yamada void on_collapse_clicked(GtkButton * button, gpointer user_data)
789*0a9064fbSMasahiro Yamada {
790*0a9064fbSMasahiro Yamada 	gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w));
791*0a9064fbSMasahiro Yamada }
792*0a9064fbSMasahiro Yamada 
793*0a9064fbSMasahiro Yamada 
794*0a9064fbSMasahiro Yamada void on_expand_clicked(GtkButton * button, gpointer user_data)
795*0a9064fbSMasahiro Yamada {
796*0a9064fbSMasahiro Yamada 	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
797*0a9064fbSMasahiro Yamada }
798*0a9064fbSMasahiro Yamada 
799*0a9064fbSMasahiro Yamada 
800*0a9064fbSMasahiro Yamada /* CTree Callbacks */
801*0a9064fbSMasahiro Yamada 
802*0a9064fbSMasahiro Yamada /* Change hex/int/string value in the cell */
803*0a9064fbSMasahiro Yamada static void renderer_edited(GtkCellRendererText * cell,
804*0a9064fbSMasahiro Yamada 			    const gchar * path_string,
805*0a9064fbSMasahiro Yamada 			    const gchar * new_text, gpointer user_data)
806*0a9064fbSMasahiro Yamada {
807*0a9064fbSMasahiro Yamada 	GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
808*0a9064fbSMasahiro Yamada 	GtkTreeIter iter;
809*0a9064fbSMasahiro Yamada 	const char *old_def, *new_def;
810*0a9064fbSMasahiro Yamada 	struct menu *menu;
811*0a9064fbSMasahiro Yamada 	struct symbol *sym;
812*0a9064fbSMasahiro Yamada 
813*0a9064fbSMasahiro Yamada 	if (!gtk_tree_model_get_iter(model2, &iter, path))
814*0a9064fbSMasahiro Yamada 		return;
815*0a9064fbSMasahiro Yamada 
816*0a9064fbSMasahiro Yamada 	gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
817*0a9064fbSMasahiro Yamada 	sym = menu->sym;
818*0a9064fbSMasahiro Yamada 
819*0a9064fbSMasahiro Yamada 	gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1);
820*0a9064fbSMasahiro Yamada 	new_def = new_text;
821*0a9064fbSMasahiro Yamada 
822*0a9064fbSMasahiro Yamada 	sym_set_string_value(sym, new_def);
823*0a9064fbSMasahiro Yamada 
824*0a9064fbSMasahiro Yamada 	update_tree(&rootmenu, NULL);
825*0a9064fbSMasahiro Yamada 
826*0a9064fbSMasahiro Yamada 	gtk_tree_path_free(path);
827*0a9064fbSMasahiro Yamada }
828*0a9064fbSMasahiro Yamada 
829*0a9064fbSMasahiro Yamada /* Change the value of a symbol and update the tree */
830*0a9064fbSMasahiro Yamada static void change_sym_value(struct menu *menu, gint col)
831*0a9064fbSMasahiro Yamada {
832*0a9064fbSMasahiro Yamada 	struct symbol *sym = menu->sym;
833*0a9064fbSMasahiro Yamada 	tristate newval;
834*0a9064fbSMasahiro Yamada 
835*0a9064fbSMasahiro Yamada 	if (!sym)
836*0a9064fbSMasahiro Yamada 		return;
837*0a9064fbSMasahiro Yamada 
838*0a9064fbSMasahiro Yamada 	if (col == COL_NO)
839*0a9064fbSMasahiro Yamada 		newval = no;
840*0a9064fbSMasahiro Yamada 	else if (col == COL_MOD)
841*0a9064fbSMasahiro Yamada 		newval = mod;
842*0a9064fbSMasahiro Yamada 	else if (col == COL_YES)
843*0a9064fbSMasahiro Yamada 		newval = yes;
844*0a9064fbSMasahiro Yamada 	else
845*0a9064fbSMasahiro Yamada 		return;
846*0a9064fbSMasahiro Yamada 
847*0a9064fbSMasahiro Yamada 	switch (sym_get_type(sym)) {
848*0a9064fbSMasahiro Yamada 	case S_BOOLEAN:
849*0a9064fbSMasahiro Yamada 	case S_TRISTATE:
850*0a9064fbSMasahiro Yamada 		if (!sym_tristate_within_range(sym, newval))
851*0a9064fbSMasahiro Yamada 			newval = yes;
852*0a9064fbSMasahiro Yamada 		sym_set_tristate_value(sym, newval);
853*0a9064fbSMasahiro Yamada 		if (view_mode == FULL_VIEW)
854*0a9064fbSMasahiro Yamada 			update_tree(&rootmenu, NULL);
855*0a9064fbSMasahiro Yamada 		else if (view_mode == SPLIT_VIEW) {
856*0a9064fbSMasahiro Yamada 			update_tree(browsed, NULL);
857*0a9064fbSMasahiro Yamada 			display_list();
858*0a9064fbSMasahiro Yamada 		}
859*0a9064fbSMasahiro Yamada 		else if (view_mode == SINGLE_VIEW)
860*0a9064fbSMasahiro Yamada 			display_tree_part();	//fixme: keep exp/coll
861*0a9064fbSMasahiro Yamada 		break;
862*0a9064fbSMasahiro Yamada 	case S_INT:
863*0a9064fbSMasahiro Yamada 	case S_HEX:
864*0a9064fbSMasahiro Yamada 	case S_STRING:
865*0a9064fbSMasahiro Yamada 	default:
866*0a9064fbSMasahiro Yamada 		break;
867*0a9064fbSMasahiro Yamada 	}
868*0a9064fbSMasahiro Yamada }
869*0a9064fbSMasahiro Yamada 
870*0a9064fbSMasahiro Yamada static void toggle_sym_value(struct menu *menu)
871*0a9064fbSMasahiro Yamada {
872*0a9064fbSMasahiro Yamada 	if (!menu->sym)
873*0a9064fbSMasahiro Yamada 		return;
874*0a9064fbSMasahiro Yamada 
875*0a9064fbSMasahiro Yamada 	sym_toggle_tristate_value(menu->sym);
876*0a9064fbSMasahiro Yamada 	if (view_mode == FULL_VIEW)
877*0a9064fbSMasahiro Yamada 		update_tree(&rootmenu, NULL);
878*0a9064fbSMasahiro Yamada 	else if (view_mode == SPLIT_VIEW) {
879*0a9064fbSMasahiro Yamada 		update_tree(browsed, NULL);
880*0a9064fbSMasahiro Yamada 		display_list();
881*0a9064fbSMasahiro Yamada 	}
882*0a9064fbSMasahiro Yamada 	else if (view_mode == SINGLE_VIEW)
883*0a9064fbSMasahiro Yamada 		display_tree_part();	//fixme: keep exp/coll
884*0a9064fbSMasahiro Yamada }
885*0a9064fbSMasahiro Yamada 
886*0a9064fbSMasahiro Yamada static gint column2index(GtkTreeViewColumn * column)
887*0a9064fbSMasahiro Yamada {
888*0a9064fbSMasahiro Yamada 	gint i;
889*0a9064fbSMasahiro Yamada 
890*0a9064fbSMasahiro Yamada 	for (i = 0; i < COL_NUMBER; i++) {
891*0a9064fbSMasahiro Yamada 		GtkTreeViewColumn *col;
892*0a9064fbSMasahiro Yamada 
893*0a9064fbSMasahiro Yamada 		col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i);
894*0a9064fbSMasahiro Yamada 		if (col == column)
895*0a9064fbSMasahiro Yamada 			return i;
896*0a9064fbSMasahiro Yamada 	}
897*0a9064fbSMasahiro Yamada 
898*0a9064fbSMasahiro Yamada 	return -1;
899*0a9064fbSMasahiro Yamada }
900*0a9064fbSMasahiro Yamada 
901*0a9064fbSMasahiro Yamada 
902*0a9064fbSMasahiro Yamada /* User click: update choice (full) or goes down (single) */
903*0a9064fbSMasahiro Yamada gboolean
904*0a9064fbSMasahiro Yamada on_treeview2_button_press_event(GtkWidget * widget,
905*0a9064fbSMasahiro Yamada 				GdkEventButton * event, gpointer user_data)
906*0a9064fbSMasahiro Yamada {
907*0a9064fbSMasahiro Yamada 	GtkTreeView *view = GTK_TREE_VIEW(widget);
908*0a9064fbSMasahiro Yamada 	GtkTreePath *path;
909*0a9064fbSMasahiro Yamada 	GtkTreeViewColumn *column;
910*0a9064fbSMasahiro Yamada 	GtkTreeIter iter;
911*0a9064fbSMasahiro Yamada 	struct menu *menu;
912*0a9064fbSMasahiro Yamada 	gint col;
913*0a9064fbSMasahiro Yamada 
914*0a9064fbSMasahiro Yamada #if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK
915*0a9064fbSMasahiro Yamada 	gint tx = (gint) event->x;
916*0a9064fbSMasahiro Yamada 	gint ty = (gint) event->y;
917*0a9064fbSMasahiro Yamada 	gint cx, cy;
918*0a9064fbSMasahiro Yamada 
919*0a9064fbSMasahiro Yamada 	gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
920*0a9064fbSMasahiro Yamada 				      &cy);
921*0a9064fbSMasahiro Yamada #else
922*0a9064fbSMasahiro Yamada 	gtk_tree_view_get_cursor(view, &path, &column);
923*0a9064fbSMasahiro Yamada #endif
924*0a9064fbSMasahiro Yamada 	if (path == NULL)
925*0a9064fbSMasahiro Yamada 		return FALSE;
926*0a9064fbSMasahiro Yamada 
927*0a9064fbSMasahiro Yamada 	if (!gtk_tree_model_get_iter(model2, &iter, path))
928*0a9064fbSMasahiro Yamada 		return FALSE;
929*0a9064fbSMasahiro Yamada 	gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
930*0a9064fbSMasahiro Yamada 
931*0a9064fbSMasahiro Yamada 	col = column2index(column);
932*0a9064fbSMasahiro Yamada 	if (event->type == GDK_2BUTTON_PRESS) {
933*0a9064fbSMasahiro Yamada 		enum prop_type ptype;
934*0a9064fbSMasahiro Yamada 		ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
935*0a9064fbSMasahiro Yamada 
936*0a9064fbSMasahiro Yamada 		if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) {
937*0a9064fbSMasahiro Yamada 			// goes down into menu
938*0a9064fbSMasahiro Yamada 			current = menu;
939*0a9064fbSMasahiro Yamada 			display_tree_part();
940*0a9064fbSMasahiro Yamada 			gtk_widget_set_sensitive(back_btn, TRUE);
941*0a9064fbSMasahiro Yamada 		} else if ((col == COL_OPTION)) {
942*0a9064fbSMasahiro Yamada 			toggle_sym_value(menu);
943*0a9064fbSMasahiro Yamada 			gtk_tree_view_expand_row(view, path, TRUE);
944*0a9064fbSMasahiro Yamada 		}
945*0a9064fbSMasahiro Yamada 	} else {
946*0a9064fbSMasahiro Yamada 		if (col == COL_VALUE) {
947*0a9064fbSMasahiro Yamada 			toggle_sym_value(menu);
948*0a9064fbSMasahiro Yamada 			gtk_tree_view_expand_row(view, path, TRUE);
949*0a9064fbSMasahiro Yamada 		} else if (col == COL_NO || col == COL_MOD
950*0a9064fbSMasahiro Yamada 			   || col == COL_YES) {
951*0a9064fbSMasahiro Yamada 			change_sym_value(menu, col);
952*0a9064fbSMasahiro Yamada 			gtk_tree_view_expand_row(view, path, TRUE);
953*0a9064fbSMasahiro Yamada 		}
954*0a9064fbSMasahiro Yamada 	}
955*0a9064fbSMasahiro Yamada 
956*0a9064fbSMasahiro Yamada 	return FALSE;
957*0a9064fbSMasahiro Yamada }
958*0a9064fbSMasahiro Yamada 
959*0a9064fbSMasahiro Yamada /* Key pressed: update choice */
960*0a9064fbSMasahiro Yamada gboolean
961*0a9064fbSMasahiro Yamada on_treeview2_key_press_event(GtkWidget * widget,
962*0a9064fbSMasahiro Yamada 			     GdkEventKey * event, gpointer user_data)
963*0a9064fbSMasahiro Yamada {
964*0a9064fbSMasahiro Yamada 	GtkTreeView *view = GTK_TREE_VIEW(widget);
965*0a9064fbSMasahiro Yamada 	GtkTreePath *path;
966*0a9064fbSMasahiro Yamada 	GtkTreeViewColumn *column;
967*0a9064fbSMasahiro Yamada 	GtkTreeIter iter;
968*0a9064fbSMasahiro Yamada 	struct menu *menu;
969*0a9064fbSMasahiro Yamada 	gint col;
970*0a9064fbSMasahiro Yamada 
971*0a9064fbSMasahiro Yamada 	gtk_tree_view_get_cursor(view, &path, &column);
972*0a9064fbSMasahiro Yamada 	if (path == NULL)
973*0a9064fbSMasahiro Yamada 		return FALSE;
974*0a9064fbSMasahiro Yamada 
975*0a9064fbSMasahiro Yamada 	if (event->keyval == GDK_space) {
976*0a9064fbSMasahiro Yamada 		if (gtk_tree_view_row_expanded(view, path))
977*0a9064fbSMasahiro Yamada 			gtk_tree_view_collapse_row(view, path);
978*0a9064fbSMasahiro Yamada 		else
979*0a9064fbSMasahiro Yamada 			gtk_tree_view_expand_row(view, path, FALSE);
980*0a9064fbSMasahiro Yamada 		return TRUE;
981*0a9064fbSMasahiro Yamada 	}
982*0a9064fbSMasahiro Yamada 	if (event->keyval == GDK_KP_Enter) {
983*0a9064fbSMasahiro Yamada 	}
984*0a9064fbSMasahiro Yamada 	if (widget == tree1_w)
985*0a9064fbSMasahiro Yamada 		return FALSE;
986*0a9064fbSMasahiro Yamada 
987*0a9064fbSMasahiro Yamada 	gtk_tree_model_get_iter(model2, &iter, path);
988*0a9064fbSMasahiro Yamada 	gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
989*0a9064fbSMasahiro Yamada 
990*0a9064fbSMasahiro Yamada 	if (!strcasecmp(event->string, "n"))
991*0a9064fbSMasahiro Yamada 		col = COL_NO;
992*0a9064fbSMasahiro Yamada 	else if (!strcasecmp(event->string, "m"))
993*0a9064fbSMasahiro Yamada 		col = COL_MOD;
994*0a9064fbSMasahiro Yamada 	else if (!strcasecmp(event->string, "y"))
995*0a9064fbSMasahiro Yamada 		col = COL_YES;
996*0a9064fbSMasahiro Yamada 	else
997*0a9064fbSMasahiro Yamada 		col = -1;
998*0a9064fbSMasahiro Yamada 	change_sym_value(menu, col);
999*0a9064fbSMasahiro Yamada 
1000*0a9064fbSMasahiro Yamada 	return FALSE;
1001*0a9064fbSMasahiro Yamada }
1002*0a9064fbSMasahiro Yamada 
1003*0a9064fbSMasahiro Yamada 
1004*0a9064fbSMasahiro Yamada /* Row selection changed: update help */
1005*0a9064fbSMasahiro Yamada void
1006*0a9064fbSMasahiro Yamada on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
1007*0a9064fbSMasahiro Yamada {
1008*0a9064fbSMasahiro Yamada 	GtkTreeSelection *selection;
1009*0a9064fbSMasahiro Yamada 	GtkTreeIter iter;
1010*0a9064fbSMasahiro Yamada 	struct menu *menu;
1011*0a9064fbSMasahiro Yamada 
1012*0a9064fbSMasahiro Yamada 	selection = gtk_tree_view_get_selection(treeview);
1013*0a9064fbSMasahiro Yamada 	if (gtk_tree_selection_get_selected(selection, &model2, &iter)) {
1014*0a9064fbSMasahiro Yamada 		gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1);
1015*0a9064fbSMasahiro Yamada 		text_insert_help(menu);
1016*0a9064fbSMasahiro Yamada 	}
1017*0a9064fbSMasahiro Yamada }
1018*0a9064fbSMasahiro Yamada 
1019*0a9064fbSMasahiro Yamada 
1020*0a9064fbSMasahiro Yamada /* User click: display sub-tree in the right frame. */
1021*0a9064fbSMasahiro Yamada gboolean
1022*0a9064fbSMasahiro Yamada on_treeview1_button_press_event(GtkWidget * widget,
1023*0a9064fbSMasahiro Yamada 				GdkEventButton * event, gpointer user_data)
1024*0a9064fbSMasahiro Yamada {
1025*0a9064fbSMasahiro Yamada 	GtkTreeView *view = GTK_TREE_VIEW(widget);
1026*0a9064fbSMasahiro Yamada 	GtkTreePath *path;
1027*0a9064fbSMasahiro Yamada 	GtkTreeViewColumn *column;
1028*0a9064fbSMasahiro Yamada 	GtkTreeIter iter;
1029*0a9064fbSMasahiro Yamada 	struct menu *menu;
1030*0a9064fbSMasahiro Yamada 
1031*0a9064fbSMasahiro Yamada 	gint tx = (gint) event->x;
1032*0a9064fbSMasahiro Yamada 	gint ty = (gint) event->y;
1033*0a9064fbSMasahiro Yamada 	gint cx, cy;
1034*0a9064fbSMasahiro Yamada 
1035*0a9064fbSMasahiro Yamada 	gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
1036*0a9064fbSMasahiro Yamada 				      &cy);
1037*0a9064fbSMasahiro Yamada 	if (path == NULL)
1038*0a9064fbSMasahiro Yamada 		return FALSE;
1039*0a9064fbSMasahiro Yamada 
1040*0a9064fbSMasahiro Yamada 	gtk_tree_model_get_iter(model1, &iter, path);
1041*0a9064fbSMasahiro Yamada 	gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1);
1042*0a9064fbSMasahiro Yamada 
1043*0a9064fbSMasahiro Yamada 	if (event->type == GDK_2BUTTON_PRESS) {
1044*0a9064fbSMasahiro Yamada 		toggle_sym_value(menu);
1045*0a9064fbSMasahiro Yamada 		current = menu;
1046*0a9064fbSMasahiro Yamada 		display_tree_part();
1047*0a9064fbSMasahiro Yamada 	} else {
1048*0a9064fbSMasahiro Yamada 		browsed = menu;
1049*0a9064fbSMasahiro Yamada 		display_tree_part();
1050*0a9064fbSMasahiro Yamada 	}
1051*0a9064fbSMasahiro Yamada 
1052*0a9064fbSMasahiro Yamada 	gtk_widget_realize(tree2_w);
1053*0a9064fbSMasahiro Yamada 	gtk_tree_view_set_cursor(view, path, NULL, FALSE);
1054*0a9064fbSMasahiro Yamada 	gtk_widget_grab_focus(tree2_w);
1055*0a9064fbSMasahiro Yamada 
1056*0a9064fbSMasahiro Yamada 	return FALSE;
1057*0a9064fbSMasahiro Yamada }
1058*0a9064fbSMasahiro Yamada 
1059*0a9064fbSMasahiro Yamada 
1060*0a9064fbSMasahiro Yamada /* Fill a row of strings */
1061*0a9064fbSMasahiro Yamada static gchar **fill_row(struct menu *menu)
1062*0a9064fbSMasahiro Yamada {
1063*0a9064fbSMasahiro Yamada 	static gchar *row[COL_NUMBER];
1064*0a9064fbSMasahiro Yamada 	struct symbol *sym = menu->sym;
1065*0a9064fbSMasahiro Yamada 	const char *def;
1066*0a9064fbSMasahiro Yamada 	int stype;
1067*0a9064fbSMasahiro Yamada 	tristate val;
1068*0a9064fbSMasahiro Yamada 	enum prop_type ptype;
1069*0a9064fbSMasahiro Yamada 	int i;
1070*0a9064fbSMasahiro Yamada 
1071*0a9064fbSMasahiro Yamada 	for (i = COL_OPTION; i <= COL_COLOR; i++)
1072*0a9064fbSMasahiro Yamada 		g_free(row[i]);
1073*0a9064fbSMasahiro Yamada 	bzero(row, sizeof(row));
1074*0a9064fbSMasahiro Yamada 
1075*0a9064fbSMasahiro Yamada 	row[COL_OPTION] =
1076*0a9064fbSMasahiro Yamada 	    g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
1077*0a9064fbSMasahiro Yamada 			    sym && !sym_has_value(sym) ? "(NEW)" : "");
1078*0a9064fbSMasahiro Yamada 
1079*0a9064fbSMasahiro Yamada 	if (opt_mode == OPT_ALL && !menu_is_visible(menu))
1080*0a9064fbSMasahiro Yamada 		row[COL_COLOR] = g_strdup("DarkGray");
1081*0a9064fbSMasahiro Yamada 	else if (opt_mode == OPT_PROMPT &&
1082*0a9064fbSMasahiro Yamada 			menu_has_prompt(menu) && !menu_is_visible(menu))
1083*0a9064fbSMasahiro Yamada 		row[COL_COLOR] = g_strdup("DarkGray");
1084*0a9064fbSMasahiro Yamada 	else
1085*0a9064fbSMasahiro Yamada 		row[COL_COLOR] = g_strdup("Black");
1086*0a9064fbSMasahiro Yamada 
1087*0a9064fbSMasahiro Yamada 	ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
1088*0a9064fbSMasahiro Yamada 	switch (ptype) {
1089*0a9064fbSMasahiro Yamada 	case P_MENU:
1090*0a9064fbSMasahiro Yamada 		row[COL_PIXBUF] = (gchar *) xpm_menu;
1091*0a9064fbSMasahiro Yamada 		if (view_mode == SINGLE_VIEW)
1092*0a9064fbSMasahiro Yamada 			row[COL_PIXVIS] = GINT_TO_POINTER(TRUE);
1093*0a9064fbSMasahiro Yamada 		row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1094*0a9064fbSMasahiro Yamada 		break;
1095*0a9064fbSMasahiro Yamada 	case P_COMMENT:
1096*0a9064fbSMasahiro Yamada 		row[COL_PIXBUF] = (gchar *) xpm_void;
1097*0a9064fbSMasahiro Yamada 		row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1098*0a9064fbSMasahiro Yamada 		row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1099*0a9064fbSMasahiro Yamada 		break;
1100*0a9064fbSMasahiro Yamada 	default:
1101*0a9064fbSMasahiro Yamada 		row[COL_PIXBUF] = (gchar *) xpm_void;
1102*0a9064fbSMasahiro Yamada 		row[COL_PIXVIS] = GINT_TO_POINTER(FALSE);
1103*0a9064fbSMasahiro Yamada 		row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1104*0a9064fbSMasahiro Yamada 		break;
1105*0a9064fbSMasahiro Yamada 	}
1106*0a9064fbSMasahiro Yamada 
1107*0a9064fbSMasahiro Yamada 	if (!sym)
1108*0a9064fbSMasahiro Yamada 		return row;
1109*0a9064fbSMasahiro Yamada 	row[COL_NAME] = g_strdup(sym->name);
1110*0a9064fbSMasahiro Yamada 
1111*0a9064fbSMasahiro Yamada 	sym_calc_value(sym);
1112*0a9064fbSMasahiro Yamada 	sym->flags &= ~SYMBOL_CHANGED;
1113*0a9064fbSMasahiro Yamada 
1114*0a9064fbSMasahiro Yamada 	if (sym_is_choice(sym)) {	// parse childs for getting final value
1115*0a9064fbSMasahiro Yamada 		struct menu *child;
1116*0a9064fbSMasahiro Yamada 		struct symbol *def_sym = sym_get_choice_value(sym);
1117*0a9064fbSMasahiro Yamada 		struct menu *def_menu = NULL;
1118*0a9064fbSMasahiro Yamada 
1119*0a9064fbSMasahiro Yamada 		row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1120*0a9064fbSMasahiro Yamada 
1121*0a9064fbSMasahiro Yamada 		for (child = menu->list; child; child = child->next) {
1122*0a9064fbSMasahiro Yamada 			if (menu_is_visible(child)
1123*0a9064fbSMasahiro Yamada 			    && child->sym == def_sym)
1124*0a9064fbSMasahiro Yamada 				def_menu = child;
1125*0a9064fbSMasahiro Yamada 		}
1126*0a9064fbSMasahiro Yamada 
1127*0a9064fbSMasahiro Yamada 		if (def_menu)
1128*0a9064fbSMasahiro Yamada 			row[COL_VALUE] =
1129*0a9064fbSMasahiro Yamada 			    g_strdup(_(menu_get_prompt(def_menu)));
1130*0a9064fbSMasahiro Yamada 	}
1131*0a9064fbSMasahiro Yamada 	if (sym->flags & SYMBOL_CHOICEVAL)
1132*0a9064fbSMasahiro Yamada 		row[COL_BTNRAD] = GINT_TO_POINTER(TRUE);
1133*0a9064fbSMasahiro Yamada 
1134*0a9064fbSMasahiro Yamada 	stype = sym_get_type(sym);
1135*0a9064fbSMasahiro Yamada 	switch (stype) {
1136*0a9064fbSMasahiro Yamada 	case S_BOOLEAN:
1137*0a9064fbSMasahiro Yamada 		if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE)
1138*0a9064fbSMasahiro Yamada 			row[COL_BTNVIS] = GINT_TO_POINTER(TRUE);
1139*0a9064fbSMasahiro Yamada 		if (sym_is_choice(sym))
1140*0a9064fbSMasahiro Yamada 			break;
1141*0a9064fbSMasahiro Yamada 		/* fall through */
1142*0a9064fbSMasahiro Yamada 	case S_TRISTATE:
1143*0a9064fbSMasahiro Yamada 		val = sym_get_tristate_value(sym);
1144*0a9064fbSMasahiro Yamada 		switch (val) {
1145*0a9064fbSMasahiro Yamada 		case no:
1146*0a9064fbSMasahiro Yamada 			row[COL_NO] = g_strdup("N");
1147*0a9064fbSMasahiro Yamada 			row[COL_VALUE] = g_strdup("N");
1148*0a9064fbSMasahiro Yamada 			row[COL_BTNACT] = GINT_TO_POINTER(FALSE);
1149*0a9064fbSMasahiro Yamada 			row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1150*0a9064fbSMasahiro Yamada 			break;
1151*0a9064fbSMasahiro Yamada 		case mod:
1152*0a9064fbSMasahiro Yamada 			row[COL_MOD] = g_strdup("M");
1153*0a9064fbSMasahiro Yamada 			row[COL_VALUE] = g_strdup("M");
1154*0a9064fbSMasahiro Yamada 			row[COL_BTNINC] = GINT_TO_POINTER(TRUE);
1155*0a9064fbSMasahiro Yamada 			break;
1156*0a9064fbSMasahiro Yamada 		case yes:
1157*0a9064fbSMasahiro Yamada 			row[COL_YES] = g_strdup("Y");
1158*0a9064fbSMasahiro Yamada 			row[COL_VALUE] = g_strdup("Y");
1159*0a9064fbSMasahiro Yamada 			row[COL_BTNACT] = GINT_TO_POINTER(TRUE);
1160*0a9064fbSMasahiro Yamada 			row[COL_BTNINC] = GINT_TO_POINTER(FALSE);
1161*0a9064fbSMasahiro Yamada 			break;
1162*0a9064fbSMasahiro Yamada 		}
1163*0a9064fbSMasahiro Yamada 
1164*0a9064fbSMasahiro Yamada 		if (val != no && sym_tristate_within_range(sym, no))
1165*0a9064fbSMasahiro Yamada 			row[COL_NO] = g_strdup("_");
1166*0a9064fbSMasahiro Yamada 		if (val != mod && sym_tristate_within_range(sym, mod))
1167*0a9064fbSMasahiro Yamada 			row[COL_MOD] = g_strdup("_");
1168*0a9064fbSMasahiro Yamada 		if (val != yes && sym_tristate_within_range(sym, yes))
1169*0a9064fbSMasahiro Yamada 			row[COL_YES] = g_strdup("_");
1170*0a9064fbSMasahiro Yamada 		break;
1171*0a9064fbSMasahiro Yamada 	case S_INT:
1172*0a9064fbSMasahiro Yamada 	case S_HEX:
1173*0a9064fbSMasahiro Yamada 	case S_STRING:
1174*0a9064fbSMasahiro Yamada 		def = sym_get_string_value(sym);
1175*0a9064fbSMasahiro Yamada 		row[COL_VALUE] = g_strdup(def);
1176*0a9064fbSMasahiro Yamada 		row[COL_EDIT] = GINT_TO_POINTER(TRUE);
1177*0a9064fbSMasahiro Yamada 		row[COL_BTNVIS] = GINT_TO_POINTER(FALSE);
1178*0a9064fbSMasahiro Yamada 		break;
1179*0a9064fbSMasahiro Yamada 	}
1180*0a9064fbSMasahiro Yamada 
1181*0a9064fbSMasahiro Yamada 	return row;
1182*0a9064fbSMasahiro Yamada }
1183*0a9064fbSMasahiro Yamada 
1184*0a9064fbSMasahiro Yamada 
1185*0a9064fbSMasahiro Yamada /* Set the node content with a row of strings */
1186*0a9064fbSMasahiro Yamada static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row)
1187*0a9064fbSMasahiro Yamada {
1188*0a9064fbSMasahiro Yamada 	GdkColor color;
1189*0a9064fbSMasahiro Yamada 	gboolean success;
1190*0a9064fbSMasahiro Yamada 	GdkPixbuf *pix;
1191*0a9064fbSMasahiro Yamada 
1192*0a9064fbSMasahiro Yamada 	pix = gdk_pixbuf_new_from_xpm_data((const char **)
1193*0a9064fbSMasahiro Yamada 					   row[COL_PIXBUF]);
1194*0a9064fbSMasahiro Yamada 
1195*0a9064fbSMasahiro Yamada 	gdk_color_parse(row[COL_COLOR], &color);
1196*0a9064fbSMasahiro Yamada 	gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1,
1197*0a9064fbSMasahiro Yamada 				  FALSE, FALSE, &success);
1198*0a9064fbSMasahiro Yamada 
1199*0a9064fbSMasahiro Yamada 	gtk_tree_store_set(tree, node,
1200*0a9064fbSMasahiro Yamada 			   COL_OPTION, row[COL_OPTION],
1201*0a9064fbSMasahiro Yamada 			   COL_NAME, row[COL_NAME],
1202*0a9064fbSMasahiro Yamada 			   COL_NO, row[COL_NO],
1203*0a9064fbSMasahiro Yamada 			   COL_MOD, row[COL_MOD],
1204*0a9064fbSMasahiro Yamada 			   COL_YES, row[COL_YES],
1205*0a9064fbSMasahiro Yamada 			   COL_VALUE, row[COL_VALUE],
1206*0a9064fbSMasahiro Yamada 			   COL_MENU, (gpointer) menu,
1207*0a9064fbSMasahiro Yamada 			   COL_COLOR, &color,
1208*0a9064fbSMasahiro Yamada 			   COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]),
1209*0a9064fbSMasahiro Yamada 			   COL_PIXBUF, pix,
1210*0a9064fbSMasahiro Yamada 			   COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]),
1211*0a9064fbSMasahiro Yamada 			   COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]),
1212*0a9064fbSMasahiro Yamada 			   COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]),
1213*0a9064fbSMasahiro Yamada 			   COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]),
1214*0a9064fbSMasahiro Yamada 			   COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]),
1215*0a9064fbSMasahiro Yamada 			   -1);
1216*0a9064fbSMasahiro Yamada 
1217*0a9064fbSMasahiro Yamada 	g_object_unref(pix);
1218*0a9064fbSMasahiro Yamada }
1219*0a9064fbSMasahiro Yamada 
1220*0a9064fbSMasahiro Yamada 
1221*0a9064fbSMasahiro Yamada /* Add a node to the tree */
1222*0a9064fbSMasahiro Yamada static void place_node(struct menu *menu, char **row)
1223*0a9064fbSMasahiro Yamada {
1224*0a9064fbSMasahiro Yamada 	GtkTreeIter *parent = parents[indent - 1];
1225*0a9064fbSMasahiro Yamada 	GtkTreeIter *node = parents[indent];
1226*0a9064fbSMasahiro Yamada 
1227*0a9064fbSMasahiro Yamada 	gtk_tree_store_append(tree, node, parent);
1228*0a9064fbSMasahiro Yamada 	set_node(node, menu, row);
1229*0a9064fbSMasahiro Yamada }
1230*0a9064fbSMasahiro Yamada 
1231*0a9064fbSMasahiro Yamada 
1232*0a9064fbSMasahiro Yamada /* Find a node in the GTK+ tree */
1233*0a9064fbSMasahiro Yamada static GtkTreeIter found;
1234*0a9064fbSMasahiro Yamada 
1235*0a9064fbSMasahiro Yamada /*
1236*0a9064fbSMasahiro Yamada  * Find a menu in the GtkTree starting at parent.
1237*0a9064fbSMasahiro Yamada  */
1238*0a9064fbSMasahiro Yamada GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent,
1239*0a9064fbSMasahiro Yamada 				    struct menu *tofind)
1240*0a9064fbSMasahiro Yamada {
1241*0a9064fbSMasahiro Yamada 	GtkTreeIter iter;
1242*0a9064fbSMasahiro Yamada 	GtkTreeIter *child = &iter;
1243*0a9064fbSMasahiro Yamada 	gboolean valid;
1244*0a9064fbSMasahiro Yamada 	GtkTreeIter *ret;
1245*0a9064fbSMasahiro Yamada 
1246*0a9064fbSMasahiro Yamada 	valid = gtk_tree_model_iter_children(model2, child, parent);
1247*0a9064fbSMasahiro Yamada 	while (valid) {
1248*0a9064fbSMasahiro Yamada 		struct menu *menu;
1249*0a9064fbSMasahiro Yamada 
1250*0a9064fbSMasahiro Yamada 		gtk_tree_model_get(model2, child, 6, &menu, -1);
1251*0a9064fbSMasahiro Yamada 
1252*0a9064fbSMasahiro Yamada 		if (menu == tofind) {
1253*0a9064fbSMasahiro Yamada 			memcpy(&found, child, sizeof(GtkTreeIter));
1254*0a9064fbSMasahiro Yamada 			return &found;
1255*0a9064fbSMasahiro Yamada 		}
1256*0a9064fbSMasahiro Yamada 
1257*0a9064fbSMasahiro Yamada 		ret = gtktree_iter_find_node(child, tofind);
1258*0a9064fbSMasahiro Yamada 		if (ret)
1259*0a9064fbSMasahiro Yamada 			return ret;
1260*0a9064fbSMasahiro Yamada 
1261*0a9064fbSMasahiro Yamada 		valid = gtk_tree_model_iter_next(model2, child);
1262*0a9064fbSMasahiro Yamada 	}
1263*0a9064fbSMasahiro Yamada 
1264*0a9064fbSMasahiro Yamada 	return NULL;
1265*0a9064fbSMasahiro Yamada }
1266*0a9064fbSMasahiro Yamada 
1267*0a9064fbSMasahiro Yamada 
1268*0a9064fbSMasahiro Yamada /*
1269*0a9064fbSMasahiro Yamada  * Update the tree by adding/removing entries
1270*0a9064fbSMasahiro Yamada  * Does not change other nodes
1271*0a9064fbSMasahiro Yamada  */
1272*0a9064fbSMasahiro Yamada static void update_tree(struct menu *src, GtkTreeIter * dst)
1273*0a9064fbSMasahiro Yamada {
1274*0a9064fbSMasahiro Yamada 	struct menu *child1;
1275*0a9064fbSMasahiro Yamada 	GtkTreeIter iter, tmp;
1276*0a9064fbSMasahiro Yamada 	GtkTreeIter *child2 = &iter;
1277*0a9064fbSMasahiro Yamada 	gboolean valid;
1278*0a9064fbSMasahiro Yamada 	GtkTreeIter *sibling;
1279*0a9064fbSMasahiro Yamada 	struct symbol *sym;
1280*0a9064fbSMasahiro Yamada 	struct menu *menu1, *menu2;
1281*0a9064fbSMasahiro Yamada 
1282*0a9064fbSMasahiro Yamada 	if (src == &rootmenu)
1283*0a9064fbSMasahiro Yamada 		indent = 1;
1284*0a9064fbSMasahiro Yamada 
1285*0a9064fbSMasahiro Yamada 	valid = gtk_tree_model_iter_children(model2, child2, dst);
1286*0a9064fbSMasahiro Yamada 	for (child1 = src->list; child1; child1 = child1->next) {
1287*0a9064fbSMasahiro Yamada 
1288*0a9064fbSMasahiro Yamada 		sym = child1->sym;
1289*0a9064fbSMasahiro Yamada 
1290*0a9064fbSMasahiro Yamada 	      reparse:
1291*0a9064fbSMasahiro Yamada 		menu1 = child1;
1292*0a9064fbSMasahiro Yamada 		if (valid)
1293*0a9064fbSMasahiro Yamada 			gtk_tree_model_get(model2, child2, COL_MENU,
1294*0a9064fbSMasahiro Yamada 					   &menu2, -1);
1295*0a9064fbSMasahiro Yamada 		else
1296*0a9064fbSMasahiro Yamada 			menu2 = NULL;	// force adding of a first child
1297*0a9064fbSMasahiro Yamada 
1298*0a9064fbSMasahiro Yamada #ifdef DEBUG
1299*0a9064fbSMasahiro Yamada 		printf("%*c%s | %s\n", indent, ' ',
1300*0a9064fbSMasahiro Yamada 		       menu1 ? menu_get_prompt(menu1) : "nil",
1301*0a9064fbSMasahiro Yamada 		       menu2 ? menu_get_prompt(menu2) : "nil");
1302*0a9064fbSMasahiro Yamada #endif
1303*0a9064fbSMasahiro Yamada 
1304*0a9064fbSMasahiro Yamada 		if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
1305*0a9064fbSMasahiro Yamada 		    (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
1306*0a9064fbSMasahiro Yamada 		    (opt_mode == OPT_ALL    && !menu_get_prompt(child1))) {
1307*0a9064fbSMasahiro Yamada 
1308*0a9064fbSMasahiro Yamada 			/* remove node */
1309*0a9064fbSMasahiro Yamada 			if (gtktree_iter_find_node(dst, menu1) != NULL) {
1310*0a9064fbSMasahiro Yamada 				memcpy(&tmp, child2, sizeof(GtkTreeIter));
1311*0a9064fbSMasahiro Yamada 				valid = gtk_tree_model_iter_next(model2,
1312*0a9064fbSMasahiro Yamada 								 child2);
1313*0a9064fbSMasahiro Yamada 				gtk_tree_store_remove(tree2, &tmp);
1314*0a9064fbSMasahiro Yamada 				if (!valid)
1315*0a9064fbSMasahiro Yamada 					return;		/* next parent */
1316*0a9064fbSMasahiro Yamada 				else
1317*0a9064fbSMasahiro Yamada 					goto reparse;	/* next child */
1318*0a9064fbSMasahiro Yamada 			} else
1319*0a9064fbSMasahiro Yamada 				continue;
1320*0a9064fbSMasahiro Yamada 		}
1321*0a9064fbSMasahiro Yamada 
1322*0a9064fbSMasahiro Yamada 		if (menu1 != menu2) {
1323*0a9064fbSMasahiro Yamada 			if (gtktree_iter_find_node(dst, menu1) == NULL) {	// add node
1324*0a9064fbSMasahiro Yamada 				if (!valid && !menu2)
1325*0a9064fbSMasahiro Yamada 					sibling = NULL;
1326*0a9064fbSMasahiro Yamada 				else
1327*0a9064fbSMasahiro Yamada 					sibling = child2;
1328*0a9064fbSMasahiro Yamada 				gtk_tree_store_insert_before(tree2,
1329*0a9064fbSMasahiro Yamada 							     child2,
1330*0a9064fbSMasahiro Yamada 							     dst, sibling);
1331*0a9064fbSMasahiro Yamada 				set_node(child2, menu1, fill_row(menu1));
1332*0a9064fbSMasahiro Yamada 				if (menu2 == NULL)
1333*0a9064fbSMasahiro Yamada 					valid = TRUE;
1334*0a9064fbSMasahiro Yamada 			} else {	// remove node
1335*0a9064fbSMasahiro Yamada 				memcpy(&tmp, child2, sizeof(GtkTreeIter));
1336*0a9064fbSMasahiro Yamada 				valid = gtk_tree_model_iter_next(model2,
1337*0a9064fbSMasahiro Yamada 								 child2);
1338*0a9064fbSMasahiro Yamada 				gtk_tree_store_remove(tree2, &tmp);
1339*0a9064fbSMasahiro Yamada 				if (!valid)
1340*0a9064fbSMasahiro Yamada 					return;	// next parent
1341*0a9064fbSMasahiro Yamada 				else
1342*0a9064fbSMasahiro Yamada 					goto reparse;	// next child
1343*0a9064fbSMasahiro Yamada 			}
1344*0a9064fbSMasahiro Yamada 		} else if (sym && (sym->flags & SYMBOL_CHANGED)) {
1345*0a9064fbSMasahiro Yamada 			set_node(child2, menu1, fill_row(menu1));
1346*0a9064fbSMasahiro Yamada 		}
1347*0a9064fbSMasahiro Yamada 
1348*0a9064fbSMasahiro Yamada 		indent++;
1349*0a9064fbSMasahiro Yamada 		update_tree(child1, child2);
1350*0a9064fbSMasahiro Yamada 		indent--;
1351*0a9064fbSMasahiro Yamada 
1352*0a9064fbSMasahiro Yamada 		valid = gtk_tree_model_iter_next(model2, child2);
1353*0a9064fbSMasahiro Yamada 	}
1354*0a9064fbSMasahiro Yamada }
1355*0a9064fbSMasahiro Yamada 
1356*0a9064fbSMasahiro Yamada 
1357*0a9064fbSMasahiro Yamada /* Display the whole tree (single/split/full view) */
1358*0a9064fbSMasahiro Yamada static void display_tree(struct menu *menu)
1359*0a9064fbSMasahiro Yamada {
1360*0a9064fbSMasahiro Yamada 	struct symbol *sym;
1361*0a9064fbSMasahiro Yamada 	struct property *prop;
1362*0a9064fbSMasahiro Yamada 	struct menu *child;
1363*0a9064fbSMasahiro Yamada 	enum prop_type ptype;
1364*0a9064fbSMasahiro Yamada 
1365*0a9064fbSMasahiro Yamada 	if (menu == &rootmenu) {
1366*0a9064fbSMasahiro Yamada 		indent = 1;
1367*0a9064fbSMasahiro Yamada 		current = &rootmenu;
1368*0a9064fbSMasahiro Yamada 	}
1369*0a9064fbSMasahiro Yamada 
1370*0a9064fbSMasahiro Yamada 	for (child = menu->list; child; child = child->next) {
1371*0a9064fbSMasahiro Yamada 		prop = child->prompt;
1372*0a9064fbSMasahiro Yamada 		sym = child->sym;
1373*0a9064fbSMasahiro Yamada 		ptype = prop ? prop->type : P_UNKNOWN;
1374*0a9064fbSMasahiro Yamada 
1375*0a9064fbSMasahiro Yamada 		if (sym)
1376*0a9064fbSMasahiro Yamada 			sym->flags &= ~SYMBOL_CHANGED;
1377*0a9064fbSMasahiro Yamada 
1378*0a9064fbSMasahiro Yamada 		if ((view_mode == SPLIT_VIEW)
1379*0a9064fbSMasahiro Yamada 		    && !(child->flags & MENU_ROOT) && (tree == tree1))
1380*0a9064fbSMasahiro Yamada 			continue;
1381*0a9064fbSMasahiro Yamada 
1382*0a9064fbSMasahiro Yamada 		if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT)
1383*0a9064fbSMasahiro Yamada 		    && (tree == tree2))
1384*0a9064fbSMasahiro Yamada 			continue;
1385*0a9064fbSMasahiro Yamada 
1386*0a9064fbSMasahiro Yamada 		if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
1387*0a9064fbSMasahiro Yamada 		    (opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
1388*0a9064fbSMasahiro Yamada 		    (opt_mode == OPT_ALL    && menu_get_prompt(child)))
1389*0a9064fbSMasahiro Yamada 			place_node(child, fill_row(child));
1390*0a9064fbSMasahiro Yamada #ifdef DEBUG
1391*0a9064fbSMasahiro Yamada 		printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
1392*0a9064fbSMasahiro Yamada 		printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : "");
1393*0a9064fbSMasahiro Yamada 		printf("%s", prop_get_type_name(ptype));
1394*0a9064fbSMasahiro Yamada 		printf(" | ");
1395*0a9064fbSMasahiro Yamada 		if (sym) {
1396*0a9064fbSMasahiro Yamada 			printf("%s", sym_type_name(sym->type));
1397*0a9064fbSMasahiro Yamada 			printf(" | ");
1398*0a9064fbSMasahiro Yamada 			printf("%s", dbg_sym_flags(sym->flags));
1399*0a9064fbSMasahiro Yamada 			printf("\n");
1400*0a9064fbSMasahiro Yamada 		} else
1401*0a9064fbSMasahiro Yamada 			printf("\n");
1402*0a9064fbSMasahiro Yamada #endif
1403*0a9064fbSMasahiro Yamada 		if ((view_mode != FULL_VIEW) && (ptype == P_MENU)
1404*0a9064fbSMasahiro Yamada 		    && (tree == tree2))
1405*0a9064fbSMasahiro Yamada 			continue;
1406*0a9064fbSMasahiro Yamada /*
1407*0a9064fbSMasahiro Yamada 		if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
1408*0a9064fbSMasahiro Yamada 		    || (view_mode == FULL_VIEW)
1409*0a9064fbSMasahiro Yamada 		    || (view_mode == SPLIT_VIEW))*/
1410*0a9064fbSMasahiro Yamada 
1411*0a9064fbSMasahiro Yamada 		/* Change paned position if the view is not in 'split mode' */
1412*0a9064fbSMasahiro Yamada 		if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) {
1413*0a9064fbSMasahiro Yamada 			gtk_paned_set_position(GTK_PANED(hpaned), 0);
1414*0a9064fbSMasahiro Yamada 		}
1415*0a9064fbSMasahiro Yamada 
1416*0a9064fbSMasahiro Yamada 		if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
1417*0a9064fbSMasahiro Yamada 		    || (view_mode == FULL_VIEW)
1418*0a9064fbSMasahiro Yamada 		    || (view_mode == SPLIT_VIEW)) {
1419*0a9064fbSMasahiro Yamada 			indent++;
1420*0a9064fbSMasahiro Yamada 			display_tree(child);
1421*0a9064fbSMasahiro Yamada 			indent--;
1422*0a9064fbSMasahiro Yamada 		}
1423*0a9064fbSMasahiro Yamada 	}
1424*0a9064fbSMasahiro Yamada }
1425*0a9064fbSMasahiro Yamada 
1426*0a9064fbSMasahiro Yamada /* Display a part of the tree starting at current node (single/split view) */
1427*0a9064fbSMasahiro Yamada static void display_tree_part(void)
1428*0a9064fbSMasahiro Yamada {
1429*0a9064fbSMasahiro Yamada 	if (tree2)
1430*0a9064fbSMasahiro Yamada 		gtk_tree_store_clear(tree2);
1431*0a9064fbSMasahiro Yamada 	if (view_mode == SINGLE_VIEW)
1432*0a9064fbSMasahiro Yamada 		display_tree(current);
1433*0a9064fbSMasahiro Yamada 	else if (view_mode == SPLIT_VIEW)
1434*0a9064fbSMasahiro Yamada 		display_tree(browsed);
1435*0a9064fbSMasahiro Yamada 	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w));
1436*0a9064fbSMasahiro Yamada }
1437*0a9064fbSMasahiro Yamada 
1438*0a9064fbSMasahiro Yamada /* Display the list in the left frame (split view) */
1439*0a9064fbSMasahiro Yamada static void display_list(void)
1440*0a9064fbSMasahiro Yamada {
1441*0a9064fbSMasahiro Yamada 	if (tree1)
1442*0a9064fbSMasahiro Yamada 		gtk_tree_store_clear(tree1);
1443*0a9064fbSMasahiro Yamada 
1444*0a9064fbSMasahiro Yamada 	tree = tree1;
1445*0a9064fbSMasahiro Yamada 	display_tree(&rootmenu);
1446*0a9064fbSMasahiro Yamada 	gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w));
1447*0a9064fbSMasahiro Yamada 	tree = tree2;
1448*0a9064fbSMasahiro Yamada }
1449*0a9064fbSMasahiro Yamada 
1450*0a9064fbSMasahiro Yamada void fixup_rootmenu(struct menu *menu)
1451*0a9064fbSMasahiro Yamada {
1452*0a9064fbSMasahiro Yamada 	struct menu *child;
1453*0a9064fbSMasahiro Yamada 	static int menu_cnt = 0;
1454*0a9064fbSMasahiro Yamada 
1455*0a9064fbSMasahiro Yamada 	menu->flags |= MENU_ROOT;
1456*0a9064fbSMasahiro Yamada 	for (child = menu->list; child; child = child->next) {
1457*0a9064fbSMasahiro Yamada 		if (child->prompt && child->prompt->type == P_MENU) {
1458*0a9064fbSMasahiro Yamada 			menu_cnt++;
1459*0a9064fbSMasahiro Yamada 			fixup_rootmenu(child);
1460*0a9064fbSMasahiro Yamada 			menu_cnt--;
1461*0a9064fbSMasahiro Yamada 		} else if (!menu_cnt)
1462*0a9064fbSMasahiro Yamada 			fixup_rootmenu(child);
1463*0a9064fbSMasahiro Yamada 	}
1464*0a9064fbSMasahiro Yamada }
1465*0a9064fbSMasahiro Yamada 
1466*0a9064fbSMasahiro Yamada 
1467*0a9064fbSMasahiro Yamada /* Main */
1468*0a9064fbSMasahiro Yamada int main(int ac, char *av[])
1469*0a9064fbSMasahiro Yamada {
1470*0a9064fbSMasahiro Yamada 	const char *name;
1471*0a9064fbSMasahiro Yamada 	char *env;
1472*0a9064fbSMasahiro Yamada 	gchar *glade_file;
1473*0a9064fbSMasahiro Yamada 
1474*0a9064fbSMasahiro Yamada 	bindtextdomain(PACKAGE, LOCALEDIR);
1475*0a9064fbSMasahiro Yamada 	bind_textdomain_codeset(PACKAGE, "UTF-8");
1476*0a9064fbSMasahiro Yamada 	textdomain(PACKAGE);
1477*0a9064fbSMasahiro Yamada 
1478*0a9064fbSMasahiro Yamada 	/* GTK stuffs */
1479*0a9064fbSMasahiro Yamada 	gtk_set_locale();
1480*0a9064fbSMasahiro Yamada 	gtk_init(&ac, &av);
1481*0a9064fbSMasahiro Yamada 	glade_init();
1482*0a9064fbSMasahiro Yamada 
1483*0a9064fbSMasahiro Yamada 	//add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps");
1484*0a9064fbSMasahiro Yamada 	//add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");
1485*0a9064fbSMasahiro Yamada 
1486*0a9064fbSMasahiro Yamada 	/* Determine GUI path */
1487*0a9064fbSMasahiro Yamada 	env = getenv(SRCTREE);
1488*0a9064fbSMasahiro Yamada 	if (env)
1489*0a9064fbSMasahiro Yamada 		glade_file = g_strconcat(env, "/scripts/kconfig/gconf.glade", NULL);
1490*0a9064fbSMasahiro Yamada 	else if (av[0][0] == '/')
1491*0a9064fbSMasahiro Yamada 		glade_file = g_strconcat(av[0], ".glade", NULL);
1492*0a9064fbSMasahiro Yamada 	else
1493*0a9064fbSMasahiro Yamada 		glade_file = g_strconcat(g_get_current_dir(), "/", av[0], ".glade", NULL);
1494*0a9064fbSMasahiro Yamada 
1495*0a9064fbSMasahiro Yamada 	/* Conf stuffs */
1496*0a9064fbSMasahiro Yamada 	if (ac > 1 && av[1][0] == '-') {
1497*0a9064fbSMasahiro Yamada 		switch (av[1][1]) {
1498*0a9064fbSMasahiro Yamada 		case 'a':
1499*0a9064fbSMasahiro Yamada 			//showAll = 1;
1500*0a9064fbSMasahiro Yamada 			break;
1501*0a9064fbSMasahiro Yamada 		case 'h':
1502*0a9064fbSMasahiro Yamada 		case '?':
1503*0a9064fbSMasahiro Yamada 			printf("%s <config>\n", av[0]);
1504*0a9064fbSMasahiro Yamada 			exit(0);
1505*0a9064fbSMasahiro Yamada 		}
1506*0a9064fbSMasahiro Yamada 		name = av[2];
1507*0a9064fbSMasahiro Yamada 	} else
1508*0a9064fbSMasahiro Yamada 		name = av[1];
1509*0a9064fbSMasahiro Yamada 
1510*0a9064fbSMasahiro Yamada 	conf_parse(name);
1511*0a9064fbSMasahiro Yamada 	fixup_rootmenu(&rootmenu);
1512*0a9064fbSMasahiro Yamada 	conf_read(NULL);
1513*0a9064fbSMasahiro Yamada 
1514*0a9064fbSMasahiro Yamada 	/* Load the interface and connect signals */
1515*0a9064fbSMasahiro Yamada 	init_main_window(glade_file);
1516*0a9064fbSMasahiro Yamada 	init_tree_model();
1517*0a9064fbSMasahiro Yamada 	init_left_tree();
1518*0a9064fbSMasahiro Yamada 	init_right_tree();
1519*0a9064fbSMasahiro Yamada 
1520*0a9064fbSMasahiro Yamada 	switch (view_mode) {
1521*0a9064fbSMasahiro Yamada 	case SINGLE_VIEW:
1522*0a9064fbSMasahiro Yamada 		display_tree_part();
1523*0a9064fbSMasahiro Yamada 		break;
1524*0a9064fbSMasahiro Yamada 	case SPLIT_VIEW:
1525*0a9064fbSMasahiro Yamada 		display_list();
1526*0a9064fbSMasahiro Yamada 		break;
1527*0a9064fbSMasahiro Yamada 	case FULL_VIEW:
1528*0a9064fbSMasahiro Yamada 		display_tree(&rootmenu);
1529*0a9064fbSMasahiro Yamada 		break;
1530*0a9064fbSMasahiro Yamada 	}
1531*0a9064fbSMasahiro Yamada 
1532*0a9064fbSMasahiro Yamada 	gtk_main();
1533*0a9064fbSMasahiro Yamada 
1534*0a9064fbSMasahiro Yamada 	return 0;
1535*0a9064fbSMasahiro Yamada }
1536*0a9064fbSMasahiro Yamada 
1537*0a9064fbSMasahiro Yamada static void conf_changed(void)
1538*0a9064fbSMasahiro Yamada {
1539*0a9064fbSMasahiro Yamada 	bool changed = conf_get_changed();
1540*0a9064fbSMasahiro Yamada 	gtk_widget_set_sensitive(save_btn, changed);
1541*0a9064fbSMasahiro Yamada 	gtk_widget_set_sensitive(save_menu_item, changed);
1542*0a9064fbSMasahiro Yamada }
1543