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