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