Split code into gconf.c and gconf_treeview_model. gconf.c now only contains ui init and ui signal callback code, all tree/model code is in the second file. Issues with split view are fixed. --- scripts/kconfig/gconfig/Makefile | 10 +- scripts/kconfig/gconfig/gconf.c | 1103 +++++------------------- scripts/kconfig/gconfig/gconf.h | 80 ++ scripts/kconfig/gconfig/gconf.ui | 16 +- scripts/kconfig/gconfig/gconf_treeview_model.c | 714 +++++++++++++++ scripts/kconfig/gconfig/gconf_treeview_model.h | 43 + scripts/kconfig/gconfig/util.h | 33 + 7 files changed, 1082 insertions(+), 917 deletions(-) create mode 100644 scripts/kconfig/gconfig/gconf.h create mode 100644 scripts/kconfig/gconfig/gconf_treeview_model.c create mode 100644 scripts/kconfig/gconfig/gconf_treeview_model.h create mode 100644 scripts/kconfig/gconfig/util.h diff --git a/scripts/kconfig/gconfig/Makefile b/scripts/kconfig/gconfig/Makefile index 282c500..f2ca18e 100644 --- a/scripts/kconfig/gconfig/Makefile +++ b/scripts/kconfig/gconfig/Makefile @@ -13,7 +13,7 @@ gconfig: $(obj)/gconf # Based on GTK which needs to be installed to compile it # object files used by all kconfig flavours listed above -gconf-objs := gconfig/gconf.o zconf.tab.o +gconf-objs := gconfig/gconf.o gconfig/gconf_treeview_model.o zconf.tab.o ifeq ($(MAKECMDGOALS),gconfig) gconf-target := 1 @@ -30,8 +30,12 @@ HOSTLOADLIBES_gconf = `pkg-config --libs gtk+-3.0 gmodule-2.0` HOSTCFLAGS_gconf.o = `pkg-config --cflags gtk+-3.0 gmodule-2.0` \ -Wno-missing-prototypes -DGTK_DISABLE_SINGLE_INCLUDES \ -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED \ - -DGSEAL_ENABLE - + -DGSEAL_ENABLE -std=c99 +HOSTCFLAGS_gconf_treeview_model.o = `pkg-config --cflags gtk+-3.0 gmodule-2.0` \ + -Wno-missing-prototypes -DGTK_DISABLE_SINGLE_INCLUDES \ + -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED \ + -DGSEAL_ENABLE -std=c99 + $(obj)/gconfig/gconf.o: $(obj)/gconfig/.tmp_gtkcheck ifeq ($(gconf-target),1) diff --git a/scripts/kconfig/gconfig/gconf.c b/scripts/kconfig/gconfig/gconf.c index 5eb765c..9d7825e 100644 --- a/scripts/kconfig/gconfig/gconf.c +++ b/scripts/kconfig/gconfig/gconf.c @@ -1,113 +1,21 @@ -/* Hey EMACS -*- linux-c -*- */ /* * + * Copyright (C) 2013 David Gräff <david.graeff@xxxxxx> * Copyright (C) 2002-2003 Romain Lievin <roms@xxxxxxxxx> * Released under the terms of the GNU GPL v2.0. * */ -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <stdlib.h> -#include <locale.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <time.h> - -#include <gtk/gtk.h> -#include <glib.h> -#include <gdk/gdk.h> - -#include "../lkc.h" +#include "gconf.h" +#include "gconf_treeview_model.h" +#define IMAGES_TOOLBAR #include "../images.c" -//#define DEBUG - -enum { - SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW -}; - -enum { - OPT_NORMAL, OPT_ALL, OPT_PROMPT -}; - -static gint view_mode = FULL_VIEW; -static gboolean show_name = TRUE; -static gboolean show_range = TRUE; -static gboolean show_value = TRUE; -static gboolean resizeable = FALSE; -static int opt_mode = OPT_NORMAL; - -GtkWidget *main_wnd = NULL; -GtkWidget *tree1_w = NULL; // left frame -GtkWidget *tree2_w = NULL; // right frame -GtkWidget *text_w = NULL; -GtkWidget *hpaned = NULL; -GtkWidget *vpaned = NULL; -GtkWidget *back_btn = NULL; -GtkWidget *save_btn = NULL; -GtkWidget *save_menu_item = NULL; - +enum view_mode_enum view_mode = FULL_VIEW; +struct gconfwindow_s gconfwindow; GtkTextTag *tag1, *tag2; -GdkColor color; - -static GtkTreeIter *parents[256]; -static gint indent; - -static struct menu *current; // current node for SINGLE view -static struct menu *browsed; // browsed node for SPLIT view - -enum { - COL_OPTION, COL_NAME, COL_NO, COL_MOD, COL_YES, COL_VALUE, - COL_MENU, COL_COLOR, COL_EDIT, COL_PIXBUF, - COL_PIXVIS, COL_BTNVIS, COL_BTNACT, COL_BTNINC, COL_BTNRAD, - COL_NUMBER -}; - -static void display_list(void); -static void display_tree(struct menu *menu, GtkTreeStore* tree); -static void display_tree_part(void); -static void update_tree(struct menu *src, GtkTreeIter * dst, GtkTreeStore* tree); -static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row, GtkTreeStore* tree); -static gchar **fill_row(struct menu *menu); -static void conf_changed(void); - -/* Helping/Debugging Functions */ - -const char *dbg_sym_flags(int val) -{ - static char buf[256]; - - bzero(buf, 256); - - if (val & SYMBOL_CONST) - strcat(buf, "const/"); - if (val & SYMBOL_CHECK) - strcat(buf, "check/"); - if (val & SYMBOL_CHOICE) - strcat(buf, "choice/"); - if (val & SYMBOL_CHOICEVAL) - strcat(buf, "choiceval/"); - if (val & SYMBOL_VALID) - strcat(buf, "valid/"); - if (val & SYMBOL_OPTIONAL) - strcat(buf, "optional/"); - if (val & SYMBOL_WRITE) - strcat(buf, "write/"); - if (val & SYMBOL_CHANGED) - strcat(buf, "changed/"); - if (val & SYMBOL_AUTO) - strcat(buf, "auto/"); - - buf[strlen(buf) - 1] = '\0'; - - return buf; -} -void replace_button_icon(GtkBuilder * builder, +static void replace_button_icon(GtkBuilder * builder, gchar * btn_name, const char ** xpm) { GdkPixbuf * pixmap; @@ -122,12 +30,26 @@ void replace_button_icon(GtkBuilder * builder, gtk_tool_button_set_icon_widget(button, image); } +static void conf_changed(void) +{ + bool changed = conf_get_changed(); + gtk_widget_set_sensitive(gconfwindow.save_btn, changed); + gtk_widget_set_sensitive(gconfwindow.save_menu_item, changed); +} + /* Main Window Initialization */ -void init_main_window(const gchar * ui_file) +static void init_main_window(const gchar * ui_file) { GtkBuilder *builder; GtkWidget *widget; GtkTextBuffer *txtbuf; + + // init default values for options + gconfwindow.show_name = TRUE; + gconfwindow.show_range = TRUE; + gconfwindow.show_value = TRUE; + gconfwindow.resizeable = FALSE; + gconfwindow.opt_mode = OPT_NORMAL; builder = gtk_builder_new(); int result = gtk_builder_add_from_file(builder, ui_file, NULL); @@ -135,30 +57,29 @@ void init_main_window(const gchar * ui_file) g_error(_("GUI loading failed !\n")); gtk_builder_connect_signals (builder, NULL); - main_wnd = GTK_WIDGET(gtk_builder_get_object(builder, "window1")); - hpaned = GTK_WIDGET(gtk_builder_get_object(builder, "hpaned1")); - vpaned = GTK_WIDGET(gtk_builder_get_object(builder, "vpaned1")); - tree1_w = GTK_WIDGET(gtk_builder_get_object(builder, "treeview1")); - tree2_w = GTK_WIDGET(gtk_builder_get_object(builder, "treeview2")); - text_w = GTK_WIDGET(gtk_builder_get_object(builder, "textview3")); + gconfwindow.main_wnd = GTK_WIDGET(gtk_builder_get_object(builder, "window1")); + gconfwindow.hpaned = GTK_WIDGET(gtk_builder_get_object(builder, "hpaned1")); + gconfwindow.tree1_w = GTK_WIDGET(gtk_builder_get_object(builder, "treeview1")); + gconfwindow.tree2_w = GTK_WIDGET(gtk_builder_get_object(builder, "treeview2")); + gconfwindow.text_w = GTK_WIDGET(gtk_builder_get_object(builder, "textview3")); - back_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button1")); - gtk_widget_set_sensitive(back_btn, FALSE); + gconfwindow.back_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button1")); + gtk_widget_set_sensitive(gconfwindow.back_btn, FALSE); widget = GTK_WIDGET(gtk_builder_get_object(builder, "show_name1")); gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, - show_name); + gconfwindow.show_name); widget = GTK_WIDGET(gtk_builder_get_object(builder, "show_range1")); gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, - show_range); + gconfwindow.show_range); widget = GTK_WIDGET(gtk_builder_get_object(builder, "show_data1")); gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget, - show_value); + gconfwindow.show_value); - save_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button3")); - save_menu_item = GTK_WIDGET(gtk_builder_get_object(builder, "save1")); + gconfwindow.save_btn = GTK_WIDGET(gtk_builder_get_object(builder, "button3")); + gconfwindow.save_menu_item = GTK_WIDGET(gtk_builder_get_object(builder, "save1")); conf_set_changed_callback(conf_changed); widget = GTK_WIDGET(gtk_builder_get_object(builder, "toolbar1")); @@ -169,7 +90,7 @@ void init_main_window(const gchar * ui_file) g_object_unref (G_OBJECT (builder)); - txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gconfwindow.text_w)); tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1", "foreground", "red", "weight", PANGO_WEIGHT_BOLD, @@ -178,9 +99,9 @@ void init_main_window(const gchar * ui_file) /*"style", PANGO_STYLE_OBLIQUE, */ NULL); - gtk_window_set_title(GTK_WINDOW(main_wnd), rootmenu.prompt->text); + gtk_window_set_title(GTK_WINDOW(gconfwindow.main_wnd), rootmenu.prompt->text); - gtk_widget_show(main_wnd); + gtk_widget_show(gconfwindow.main_wnd); } /** @@ -191,205 +112,37 @@ void show_data(void) { switch (view_mode) { case SINGLE_VIEW: - gtk_widget_hide(tree1_w); - current = &rootmenu; - display_tree_part(); + gtk_widget_hide(gconfwindow.tree1_w); + display_tree_part(&rootmenu); break; case SPLIT_VIEW: { - gtk_widget_show(tree1_w); + gtk_widget_show(gconfwindow.tree1_w); gint w, h; - gtk_window_get_default_size(GTK_WINDOW(main_wnd), &w, &h); - gtk_paned_set_position(GTK_PANED(hpaned), w / 2); + gtk_window_get_default_size(GTK_WINDOW(gconfwindow.main_wnd), &w, &h); + gtk_paned_set_position(GTK_PANED(gconfwindow.hpaned), w / 2); // Clear right frame, the user has to choose a subtree first - GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w))); + GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w))); gtk_tree_store_clear(tree2); // Display tree in left frame display_list(); /* Disable back btn, like in full mode. */ - gtk_widget_set_sensitive(back_btn, FALSE); + gtk_widget_set_sensitive(gconfwindow.back_btn, FALSE); break; } case FULL_VIEW: { - gtk_widget_hide(tree1_w); - GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w))); + gtk_widget_hide(gconfwindow.tree1_w); + GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w))); gtk_tree_store_clear(tree2); display_tree(&rootmenu, tree2); - gtk_widget_set_sensitive(back_btn, FALSE); + gtk_widget_set_sensitive(gconfwindow.back_btn, FALSE); break; } } } -void init_left_tree(void) -{ - GtkTreeView *view = GTK_TREE_VIEW(tree1_w); - GtkCellRenderer *renderer; - GtkTreeSelection *sel; - GtkTreeViewColumn *column; - - GtkTreeStore *tree1; - GtkTreeModel *model1; - tree1 = gtk_tree_store_new(COL_NUMBER, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_POINTER, GDK_TYPE_COLOR, - G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN); - model1 = GTK_TREE_MODEL(tree1); - - gtk_tree_view_set_model(view, model1); - gtk_tree_view_set_headers_visible(view, TRUE); - gtk_tree_view_set_rules_hint(view, TRUE); - - column = gtk_tree_view_column_new(); - gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_title(column, _("Options")); - - renderer = gtk_cell_renderer_toggle_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "active", COL_BTNACT, - "inconsistent", COL_BTNINC, - "visible", COL_BTNVIS, - "radio", COL_BTNRAD, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "text", COL_OPTION, - "foreground-gdk", - COL_COLOR, NULL); - - sel = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); - gtk_widget_realize(tree1_w); -} - -static void renderer_edited(GtkCellRendererText * cell, - const gchar * path_string, - const gchar * new_text, gpointer user_data); - -void init_right_tree(void) -{ - GtkTreeView *view = GTK_TREE_VIEW(tree2_w); - GtkCellRenderer *renderer; - GtkTreeSelection *sel; - GtkTreeViewColumn *column; - gint i; - - GtkTreeStore *tree2; - GtkTreeModel *model2; - tree2 = gtk_tree_store_new(COL_NUMBER, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_POINTER, GDK_TYPE_COLOR, - G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, - G_TYPE_BOOLEAN); - model2 = GTK_TREE_MODEL(tree2); - - gtk_tree_view_set_model(view, model2); - gtk_tree_view_set_headers_visible(view, TRUE); - gtk_tree_view_set_rules_hint(view, TRUE); - - column = gtk_tree_view_column_new(); - gtk_tree_view_append_column(view, column); - gtk_tree_view_column_set_title(column, _("Options")); - - renderer = gtk_cell_renderer_pixbuf_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "pixbuf", COL_PIXBUF, - "visible", COL_PIXVIS, NULL); - renderer = gtk_cell_renderer_toggle_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "active", COL_BTNACT, - "inconsistent", COL_BTNINC, - "visible", COL_BTNVIS, - "radio", COL_BTNRAD, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), - renderer, FALSE); - gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), - renderer, - "text", COL_OPTION, - "foreground-gdk", - COL_COLOR, NULL); - - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - _("Name"), renderer, - "text", COL_NAME, - "foreground-gdk", - COL_COLOR, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - "N", renderer, - "text", COL_NO, - "foreground-gdk", - COL_COLOR, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - "M", renderer, - "text", COL_MOD, - "foreground-gdk", - COL_COLOR, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - "Y", renderer, - "text", COL_YES, - "foreground-gdk", - COL_COLOR, NULL); - renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(view, -1, - _("Value"), renderer, - "text", COL_VALUE, - "editable", - COL_EDIT, - "foreground-gdk", - COL_COLOR, NULL); - g_signal_connect(G_OBJECT(renderer), "edited", - G_CALLBACK(renderer_edited), NULL); - - column = gtk_tree_view_get_column(view, COL_NAME); - gtk_tree_view_column_set_visible(column, show_name); - column = gtk_tree_view_get_column(view, COL_NO); - gtk_tree_view_column_set_visible(column, show_range); - column = gtk_tree_view_get_column(view, COL_MOD); - gtk_tree_view_column_set_visible(column, show_range); - column = gtk_tree_view_get_column(view, COL_YES); - gtk_tree_view_column_set_visible(column, show_range); - column = gtk_tree_view_get_column(view, COL_VALUE); - gtk_tree_view_column_set_visible(column, show_value); - - if (resizeable) { - for (i = 0; i < COL_VALUE; i++) { - column = gtk_tree_view_get_column(view, i); - gtk_tree_view_column_set_resizable(column, TRUE); - } - } - - sel = gtk_tree_view_get_selection(view); - gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); -} - - /* Utility Functions */ @@ -402,10 +155,10 @@ static void text_insert_help(struct menu *menu) menu_get_ext_help(menu, &help); - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gconfwindow.text_w)); gtk_text_buffer_get_bounds(buffer, &start, &end); gtk_text_buffer_delete(buffer, &start, &end); - gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(gconfwindow.text_w), 15); gtk_text_buffer_get_end_iter(buffer, &end); gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1, tag1, @@ -424,10 +177,10 @@ static void text_insert_msg(const char *title, const char *message) GtkTextIter start, end; const char *msg = message; - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w)); + buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gconfwindow.text_w)); gtk_text_buffer_get_bounds(buffer, &start, &end); gtk_text_buffer_delete(buffer, &start, &end); - gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_w), 15); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(gconfwindow.text_w), 15); gtk_text_buffer_get_end_iter(buffer, &end); gtk_text_buffer_insert_with_tags(buffer, &end, title, -1, tag1, @@ -451,7 +204,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, return FALSE; dialog = gtk_dialog_new_with_buttons(_("Warning !"), - GTK_WINDOW(main_wnd), + GTK_WINDOW(gconfwindow.main_wnd), (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), @@ -499,7 +252,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new (_("Load file..."), - GTK_WINDOW(main_wnd), + GTK_WINDOW(gconfwindow.main_wnd), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, @@ -528,7 +281,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) GtkWidget *dialog; dialog = gtk_file_chooser_dialog_new (_("Save File as..."), - GTK_WINDOW(main_wnd), + GTK_WINDOW(gconfwindow.main_wnd), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, @@ -550,7 +303,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data) { if (!on_window1_delete_event(NULL, NULL, NULL)) - gtk_widget_destroy(GTK_WIDGET(main_wnd)); + gtk_widget_destroy(GTK_WIDGET(gconfwindow.main_wnd)); } @@ -558,10 +311,10 @@ void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkTreeViewColumn *col; - show_name = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NAME); + gconfwindow.show_name = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(gconfwindow.tree2_w), COL_NAME); if (col) - gtk_tree_view_column_set_visible(col, show_name); + gtk_tree_view_column_set_visible(col, gconfwindow.show_name); } @@ -569,16 +322,16 @@ void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkTreeViewColumn *col; - show_range = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_NO); + gconfwindow.show_range = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(gconfwindow.tree2_w), COL_NO); if (col) - gtk_tree_view_column_set_visible(col, show_range); - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_MOD); + gtk_tree_view_column_set_visible(col, gconfwindow.show_range); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(gconfwindow.tree2_w), COL_MOD); if (col) - gtk_tree_view_column_set_visible(col, show_range); - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_YES); + gtk_tree_view_column_set_visible(col, gconfwindow.show_range); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(gconfwindow.tree2_w), COL_YES); if (col) - gtk_tree_view_column_set_visible(col, show_range); + gtk_tree_view_column_set_visible(col, gconfwindow.show_range); } @@ -587,18 +340,18 @@ void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data) { GtkTreeViewColumn *col; - show_value = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), COL_VALUE); + gconfwindow.show_value = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)); + col = gtk_tree_view_get_column(GTK_TREE_VIEW(gconfwindow.tree2_w), COL_VALUE); if (col) - gtk_tree_view_column_set_visible(col, show_value); + gtk_tree_view_column_set_visible(col, gconfwindow.show_value); } void on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data) { - opt_mode = OPT_NORMAL; - GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w))); + gconfwindow.opt_mode = OPT_NORMAL; + GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w))); gtk_tree_store_clear(tree2); display_tree(&rootmenu, tree2); /* instead of update_tree to speed-up */ } @@ -607,8 +360,8 @@ on_set_option_mode1_activate(GtkMenuItem *menuitem, gpointer user_data) void on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data) { - opt_mode = OPT_ALL; - GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w))); + gconfwindow.opt_mode = OPT_ALL; + GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w))); gtk_tree_store_clear(tree2); display_tree(&rootmenu, tree2); /* instead of update_tree to speed-up */ } @@ -617,8 +370,8 @@ on_set_option_mode2_activate(GtkMenuItem *menuitem, gpointer user_data) void on_set_option_mode3_activate(GtkMenuItem *menuitem, gpointer user_data) { - opt_mode = OPT_PROMPT; - GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w))); + gconfwindow.opt_mode = OPT_PROMPT; + GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w))); gtk_tree_store_clear(tree2); display_tree(&rootmenu, tree2); /* instead of update_tree to speed-up */ } @@ -644,7 +397,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) "Toggling Show Debug Info under the Options menu will show \n" "the dependencies, which you can then match by examining other options."); - dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + dialog = gtk_message_dialog_new(GTK_WINDOW(gconfwindow.main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", intro_text); @@ -663,7 +416,7 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) "gkc is copyright (c) 2002 Romain Lievin <roms@xxxxxxxxxxxxxx>.\n" "Based on the source code from Roman Zippel.\n"); - dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + dialog = gtk_message_dialog_new(GTK_WINDOW(gconfwindow.main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", about_text); @@ -682,7 +435,7 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) "For more information, please see the source code or\n" "visit http://www.fsf.org/licenses/licenses.html\n"); - dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), + dialog = gtk_message_dialog_new(GTK_WINDOW(gconfwindow.main_wnd), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", license_text); @@ -697,14 +450,15 @@ void on_back_clicked(GtkButton * button, gpointer user_data) { enum prop_type ptype; - current = current->parent; + struct menu *current = getCurrentMenu()->parent; ptype = current->prompt ? current->prompt->type : P_UNKNOWN; if (ptype != P_MENU) current = current->parent; - display_tree_part(); - + if (current == &rootmenu) - gtk_widget_set_sensitive(back_btn, FALSE); + gtk_widget_set_sensitive(gconfwindow.back_btn, FALSE); + + display_tree_part(current); } @@ -737,175 +491,70 @@ void on_full_clicked(GtkButton * button, gpointer user_data) void on_collapse_clicked(GtkButton * button, gpointer user_data) { - gtk_tree_view_collapse_all(GTK_TREE_VIEW(tree2_w)); + gtk_tree_view_collapse_all(GTK_TREE_VIEW(gconfwindow.tree2_w)); } void on_expand_clicked(GtkButton * button, gpointer user_data) { - gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); + gtk_tree_view_expand_all(GTK_TREE_VIEW(gconfwindow.tree2_w)); } - -/* CTree Callbacks */ - -/* Change hex/int/string value in the cell */ -static void renderer_edited(GtkCellRendererText * cell, - const gchar * path_string, - const gchar * new_text, gpointer user_data) +/** + * If you click on one of the columns N|M|Y this method is called + * by the toggle signal handler (via a proxy methods below) + */ +void changeEnabledToogle(int colChangable, int colValue, gchar *path_str) { - GtkTreePath *path = gtk_tree_path_new_from_string(path_string); - GtkTreeIter iter; - const char *old_def, *new_def; + GtkTreeIter iter; struct menu *menu; - struct symbol *sym; - - GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w)); - GtkTreeStore* tree2 = GTK_TREE_STORE(model2); - - if (!gtk_tree_model_get_iter(model2, &iter, path)) - return; - - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - sym = menu->sym; - - gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1); - new_def = new_text; - - sym_set_string_value(sym, new_def); - - update_tree(&rootmenu, NULL, tree2); - - gtk_tree_path_free(path); -} - -/* Change the value of a symbol and update the tree */ -static void change_sym_value(struct menu *menu, gint col, GtkTreeStore* tree) -{ - struct symbol *sym = menu->sym; - tristate newval; - - if (!sym) + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w)); + gtk_tree_model_get_iter (model2, &iter, path); + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); // get menu data + // get changable state + gboolean enabled; + gtk_tree_model_get(model2, &iter, colChangable, &enabled, -1); + if (!enabled) // not changable, do nothing return; - - if (col == COL_NO) - newval = no; - else if (col == COL_MOD) - newval = mod; - else if (col == COL_YES) - newval = yes; + + if (colValue != -1) + change_sym_value(menu, colValue, GTK_TREE_STORE(model2)); else - return; - - switch (sym_get_type(sym)) { - case S_BOOLEAN: - case S_TRISTATE: - if (!sym_tristate_within_range(sym, newval)) - newval = yes; - sym_set_tristate_value(sym, newval); - if (view_mode == FULL_VIEW) - update_tree(&rootmenu, NULL, tree); - else if (view_mode == SPLIT_VIEW) { - update_tree(browsed, NULL, tree); - display_list(); - } - else if (view_mode == SINGLE_VIEW) - display_tree_part(); //fixme: keep exp/coll - break; - case S_INT: - case S_HEX: - case S_STRING: - default: - break; - } + toggle_sym_value(menu, GTK_TREE_STORE(model2)); + + gtk_tree_view_expand_row(GTK_TREE_VIEW (gconfwindow.tree2_w), path, TRUE); + gtk_tree_path_free (path); } -static void toggle_sym_value(struct menu *menu, GtkTreeStore* tree) +void on_treeview2_makeDisable_clicked(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data) { - if (!menu->sym) - return; - - sym_toggle_tristate_value(menu->sym); - if (view_mode == FULL_VIEW) - update_tree(&rootmenu, NULL, tree); - else if (view_mode == SPLIT_VIEW) { - update_tree(browsed, NULL, tree); - display_list(); - } - else if (view_mode == SINGLE_VIEW) - display_tree_part(); //fixme: keep exp/coll -} + changeEnabledToogle(COL_NO_EN, COL_NO, path_str); +}; -static gint column2index(GtkTreeViewColumn * column) +void on_treeview2_makeModule_clicked(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data) { - gint i; - - for (i = 0; i < COL_NUMBER; i++) { - GtkTreeViewColumn *col; - - col = gtk_tree_view_get_column(GTK_TREE_VIEW(tree2_w), i); - if (col == column) - return i; - } - - return -1; -} - + changeEnabledToogle(COL_MOD_EN, COL_MOD, path_str); +}; -/* User click: update choice (full) or goes down (single) */ -gboolean -on_treeview2_button_press_event(GtkWidget * widget, - GdkEventButton * event, gpointer user_data) +void on_treeview2_makeEnable_clicked(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data) { - GtkTreeView *view = GTK_TREE_VIEW(widget); - GtkTreeModel* model2 = gtk_tree_view_get_model(view); - GtkTreeStore* tree2 = GTK_TREE_STORE(model2); - GtkTreePath *path; - GtkTreeViewColumn *column; - GtkTreeIter iter; - struct menu *menu; - gint col; - - - gtk_tree_view_get_cursor(view, &path, &column); - if (path == NULL) - return FALSE; - - if (!gtk_tree_model_get_iter(model2, &iter, path)) - return FALSE; - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - - col = column2index(column); - if (event->type == GDK_2BUTTON_PRESS) { - enum prop_type ptype; - ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; - - if (ptype == P_MENU && view_mode != FULL_VIEW && col == COL_OPTION) { - // goes down into menu - current = menu; - display_tree_part(); - gtk_widget_set_sensitive(back_btn, TRUE); - } else if ((col == COL_OPTION)) { - toggle_sym_value(menu, tree2); - gtk_tree_view_expand_row(view, path, TRUE); - } - } else { - if (col == COL_VALUE) { - toggle_sym_value(menu, tree2); - gtk_tree_view_expand_row(view, path, TRUE); - } else if (col == COL_NO || col == COL_MOD - || col == COL_YES) { - change_sym_value(menu, col, tree2); - gtk_tree_view_expand_row(view, path, TRUE); - } - } + changeEnabledToogle(COL_YES_EN, COL_YES, path_str); +}; - return FALSE; +void +on_treeview2_toggleEnable_clicked(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data) +{ + changeEnabledToogle(COL_BTNVISIBLE, -1, path_str); } /* Key pressed: update choice */ gboolean -on_treeview2_key_press_event(GtkWidget * widget, +on_treeviews_key_press_event(GtkWidget * widget, GdkEventKey * event, gpointer user_data) { GtkTreeView *view = GTK_TREE_VIEW(widget); @@ -930,17 +579,17 @@ on_treeview2_key_press_event(GtkWidget * widget, } if (event->keyval == GDK_KEY_KP_Enter) { } - if (widget == tree1_w) + if (widget == gconfwindow.tree1_w) return FALSE; gtk_tree_model_get_iter(model2, &iter, path); gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - if (!strcasecmp(event->string, "n")) + if (!strncasecmp(event->string, "n", 1)) col = COL_NO; - else if (!strcasecmp(event->string, "m")) + else if (!strncasecmp(event->string, "m", 1)) col = COL_MOD; - else if (!strcasecmp(event->string, "y")) + else if (!strncasecmp(event->string, "y", 1)) col = COL_YES; else col = -1; @@ -950,453 +599,96 @@ on_treeview2_key_press_event(GtkWidget * widget, } -/* Row selection changed: update help */ -void -on_treeview2_selection_changed(GtkTreeSelection *selection, gpointer user_data) +/* User click: goes down (single) */ +gboolean +on_treeview2_button_press_event(GtkWidget * widget, + GdkEventButton * event, gpointer user_data) { - GtkTreeIter iter; - struct menu *menu; - - GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w)); - if (gtk_tree_selection_get_selected(selection, &model2, &iter)) { - gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); - text_insert_help(menu); + if (event->type != GDK_2BUTTON_PRESS || view_mode == FULL_VIEW) { + return FALSE; } -} - -/* User click: display sub-tree in the right frame. */ -void -on_treeview1_selection_changed(GtkTreeSelection *selection, gpointer user_data) -{ + + GtkTreeView *view = GTK_TREE_VIEW(widget); + GtkTreeModel* model2 = gtk_tree_view_get_model(view); + GtkTreePath *path; + GtkTreeViewColumn *column; GtkTreeIter iter; struct menu *menu; - GtkTreeModel* model1 = gtk_tree_view_get_model(GTK_TREE_VIEW (tree1_w)); - if (gtk_tree_selection_get_selected(selection, &model1, &iter)) { - gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1); - - text_insert_help(menu); - -// GtkTreeStore* tree1 = GTK_TREE_STORE(model1); - - browsed = menu; - display_tree_part(); - -// gtk_widget_realize(tree2_w); - gtk_widget_grab_focus(tree2_w); - } -} + gtk_tree_view_get_cursor(view, &path, &column); + if (path == NULL) + return FALSE; + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return FALSE; + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); -/* Fill a row of strings */ -static gchar **fill_row(struct menu *menu) -{ - static gchar *row[COL_NUMBER]; - struct symbol *sym = menu->sym; - const char *def; - int stype; - tristate val; enum prop_type ptype; - int i; - - for (i = COL_OPTION; i <= COL_COLOR; i++) - g_free(row[i]); - bzero(row, sizeof(row)); - - row[COL_OPTION] = - g_strdup_printf("%s %s", _(menu_get_prompt(menu)), - sym && !sym_has_value(sym) ? "(NEW)" : ""); - - if (opt_mode == OPT_ALL && !menu_is_visible(menu)) - row[COL_COLOR] = g_strdup("DarkGray"); - else if (opt_mode == OPT_PROMPT && - menu_has_prompt(menu) && !menu_is_visible(menu)) - row[COL_COLOR] = g_strdup("DarkGray"); - else - row[COL_COLOR] = g_strdup("Black"); - ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; - switch (ptype) { - case P_MENU: - row[COL_PIXBUF] = (gchar *) xpm_menu; - if (view_mode == SINGLE_VIEW) - row[COL_PIXVIS] = GINT_TO_POINTER(TRUE); - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - break; - case P_COMMENT: - row[COL_PIXBUF] = (gchar *) xpm_void; - row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - break; - default: - row[COL_PIXBUF] = (gchar *) xpm_void; - row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); - row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); - break; - } - if (!sym) - return row; - row[COL_NAME] = g_strdup(sym->name); - - sym_calc_value(sym); - sym->flags &= ~SYMBOL_CHANGED; - - if (sym_is_choice(sym)) { // parse childs for getting final value - struct menu *child; - struct symbol *def_sym = sym_get_choice_value(sym); - struct menu *def_menu = NULL; - - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - - for (child = menu->list; child; child = child->next) { - if (menu_is_visible(child) - && child->sym == def_sym) - def_menu = child; - } - - if (def_menu) - row[COL_VALUE] = - g_strdup(_(menu_get_prompt(def_menu))); - } - if (sym->flags & SYMBOL_CHOICEVAL) - row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); - - stype = sym_get_type(sym); - switch (stype) { - case S_BOOLEAN: - if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) - row[COL_BTNVIS] = GINT_TO_POINTER(TRUE); - if (sym_is_choice(sym)) - break; - /* fall through */ - case S_TRISTATE: - val = sym_get_tristate_value(sym); - switch (val) { - case no: - row[COL_NO] = g_strdup("N"); - row[COL_VALUE] = g_strdup("N"); - row[COL_BTNACT] = GINT_TO_POINTER(FALSE); - row[COL_BTNINC] = GINT_TO_POINTER(FALSE); - break; - case mod: - row[COL_MOD] = g_strdup("M"); - row[COL_VALUE] = g_strdup("M"); - row[COL_BTNINC] = GINT_TO_POINTER(TRUE); - break; - case yes: - row[COL_YES] = g_strdup("Y"); - row[COL_VALUE] = g_strdup("Y"); - row[COL_BTNACT] = GINT_TO_POINTER(TRUE); - row[COL_BTNINC] = GINT_TO_POINTER(FALSE); - break; - } - - if (val != no && sym_tristate_within_range(sym, no)) - row[COL_NO] = g_strdup("_"); - if (val != mod && sym_tristate_within_range(sym, mod)) - row[COL_MOD] = g_strdup("_"); - if (val != yes && sym_tristate_within_range(sym, yes)) - row[COL_YES] = g_strdup("_"); - break; - case S_INT: - case S_HEX: - case S_STRING: - def = sym_get_string_value(sym); - row[COL_VALUE] = g_strdup(def); - row[COL_EDIT] = GINT_TO_POINTER(TRUE); - row[COL_BTNVIS] = GINT_TO_POINTER(FALSE); - break; + if (ptype == P_MENU) { + // goes down into menu + display_tree_part(menu); + gtk_widget_set_sensitive(gconfwindow.back_btn, TRUE); } - - return row; -} - - -/* Set the node content with a row of strings */ -static void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row, GtkTreeStore* tree) -{ - GdkColor color; - GdkPixbuf *pix; - - pix = gdk_pixbuf_new_from_xpm_data((const char **) - row[COL_PIXBUF]); - - gdk_color_parse(row[COL_COLOR], &color); -// gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1, -// FALSE, FALSE, &success); - - gtk_tree_store_set(tree, node, - COL_OPTION, row[COL_OPTION], - COL_NAME, row[COL_NAME], - COL_NO, row[COL_NO], - COL_MOD, row[COL_MOD], - COL_YES, row[COL_YES], - COL_VALUE, row[COL_VALUE], - COL_MENU, (gpointer) menu, - COL_COLOR, &color, - COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]), - COL_PIXBUF, pix, - COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]), - COL_BTNVIS, GPOINTER_TO_INT(row[COL_BTNVIS]), - COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]), - COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]), - COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]), - -1); - - g_object_unref(pix); -} - - -/* Add a node to the tree */ -static void place_node(struct menu *menu, char **row, GtkTreeStore* tree) -{ - GtkTreeIter *parent = parents[indent - 1]; - GtkTreeIter *node = parents[indent]; - - gtk_tree_store_append(tree, node, parent); - set_node(node, menu, row, tree); + + return FALSE; } -/* Find a node in the GTK+ tree */ -static GtkTreeIter found; - -/* - * Find a menu in the GtkTree starting at parent. - */ -GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, - struct menu *tofind) +/* Row selection changed: update help */ +void +on_treeview2_selection_changed(GtkTreeSelection *selection, gpointer user_data) { GtkTreeIter iter; - GtkTreeIter *child = &iter; - gboolean valid; - GtkTreeIter *ret; - - GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w)); - valid = gtk_tree_model_iter_children(model2, child, parent); - while (valid) { - struct menu *menu; - - gtk_tree_model_get(model2, child, 6, &menu, -1); - - if (menu == tofind) { - memcpy(&found, child, sizeof(GtkTreeIter)); - return &found; - } - - ret = gtktree_iter_find_node(child, tofind); - if (ret) - return ret; - - valid = gtk_tree_model_iter_next(model2, child); - } - - return NULL; -} - - -/* - * Update the tree by adding/removing entries - * Does not change other nodes - */ -static void update_tree(struct menu *src, GtkTreeIter * dst, GtkTreeStore* tree) -{ - struct menu *child1; - GtkTreeIter iter, tmp; - GtkTreeIter *child2 = &iter; - gboolean valid; - GtkTreeIter *sibling; - struct symbol *sym; - struct menu *menu1, *menu2; - - if (src == &rootmenu) - indent = 1; - - GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w)); - valid = gtk_tree_model_iter_children(model2, child2, dst); - for (child1 = src->list; child1; child1 = child1->next) { - - sym = child1->sym; - - reparse: - menu1 = child1; - if (valid) - gtk_tree_model_get(model2, child2, COL_MENU, - &menu2, -1); - else - menu2 = NULL; // force adding of a first child - -#ifdef DEBUG - printf("%*c%s | %s\n", indent, ' ', - menu1 ? menu_get_prompt(menu1) : "nil", - menu2 ? menu_get_prompt(menu2) : "nil"); -#endif - - if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || - (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) || - (opt_mode == OPT_ALL && !menu_get_prompt(child1))) { - - /* remove node */ - if (gtktree_iter_find_node(dst, menu1) != NULL) { - memcpy(&tmp, child2, sizeof(GtkTreeIter)); - valid = gtk_tree_model_iter_next(model2, - child2); - gtk_tree_store_remove(tree, &tmp); - if (!valid) - return; /* next parent */ - else - goto reparse; /* next child */ - } else - continue; - } - - if (menu1 != menu2) { - if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node - if (!valid && !menu2) - sibling = NULL; - else - sibling = child2; - gtk_tree_store_insert_before(tree, - child2, - dst, sibling); - set_node(child2, menu1, fill_row(menu1), tree); - if (menu2 == NULL) - valid = TRUE; - } else { // remove node - memcpy(&tmp, child2, sizeof(GtkTreeIter)); - valid = gtk_tree_model_iter_next(model2, - child2); - gtk_tree_store_remove(tree, &tmp); - if (!valid) - return; // next parent - else - goto reparse; // next child - } - } else if (sym && (sym->flags & SYMBOL_CHANGED)) { - set_node(child2, menu1, fill_row(menu1), tree); - } - - indent++; - update_tree(child1, child2, tree); - indent--; + struct menu *menu; - valid = gtk_tree_model_iter_next(model2, child2); + GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w)); + if (gtk_tree_selection_get_selected(selection, &model2, &iter)) { + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + text_insert_help(menu); } } - -/* Display the whole tree (single/split/full view) */ -static void display_tree(struct menu *menu, GtkTreeStore* tree) +/* User click: display sub-tree in the right frame. */ +void +on_treeview1_selection_changed(GtkTreeSelection *selection, gpointer user_data) { - struct symbol *sym; - struct property *prop; - struct menu *child; - enum prop_type ptype; - GtkTreeStore* tree1 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree1_w))); - GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w))); - - if (menu == &rootmenu) { - indent = 1; - current = &rootmenu; - } + GtkTreeIter iter; + struct menu *menu; - for (child = menu->list; child; child = child->next) { - prop = child->prompt; - sym = child->sym; - ptype = prop ? prop->type : P_UNKNOWN; - - if (sym) - sym->flags &= ~SYMBOL_CHANGED; - - if ((view_mode == SPLIT_VIEW) - && !(child->flags & MENU_ROOT) && (tree == tree1)) - continue; - - if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) - && (tree == tree2)) - continue; - - if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) || - (opt_mode == OPT_PROMPT && menu_has_prompt(child)) || - (opt_mode == OPT_ALL && menu_get_prompt(child))) - place_node(child, fill_row(child), tree); -#ifdef DEBUG - printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); - printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); - printf("%s", prop_get_type_name(ptype)); - printf(" | "); - if (sym) { - printf("%s", sym_type_name(sym->type)); - printf(" | "); - printf("%s", dbg_sym_flags(sym->flags)); - printf("\n"); - } else - printf("\n"); -#endif - if ((view_mode != FULL_VIEW) && (ptype == P_MENU) - && (tree == tree2)) - continue; -/* - if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) - || (view_mode == FULL_VIEW) - || (view_mode == SPLIT_VIEW))*/ + GtkTreeModel* model1 = gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree1_w)); + if (gtk_tree_selection_get_selected(selection, &model1, &iter)) { + gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1); - /* Change paned position if the view is not in 'split mode' */ - if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) { - gtk_paned_set_position(GTK_PANED(hpaned), 0); - } + display_tree_part(menu); + text_insert_help(menu); - if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) - || (view_mode == FULL_VIEW) - || (view_mode == SPLIT_VIEW)) { - indent++; - display_tree(child, tree); - indent--; - } + gtk_widget_realize(gconfwindow.tree2_w); + gtk_widget_grab_focus(gconfwindow.tree2_w); } } -/* Display a part of the tree starting at current node (single/split view) */ -static void display_tree_part(void) -{ - GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree2_w))); - gtk_tree_store_clear(tree2); - - if (view_mode == SINGLE_VIEW) - display_tree(current, tree2); - else if (view_mode == SPLIT_VIEW) - display_tree(browsed, tree2); - gtk_tree_view_expand_all(GTK_TREE_VIEW(tree2_w)); -} - -/* Display the list in the left frame (split view) */ -static void display_list(void) -{ - GtkTreeStore* tree1 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (tree1_w))); - gtk_tree_store_clear(tree1); - - display_tree(&rootmenu, tree1); - gtk_tree_view_expand_all(GTK_TREE_VIEW(tree1_w)); -} - -void fixup_rootmenu(struct menu *menu) +/* User clicked on checkbox in treeview 1. */ +void +on_treeview1_checkbox_toggle(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data) { - struct menu *child; - static int menu_cnt = 0; - - menu->flags |= MENU_ROOT; - for (child = menu->list; child; child = child->next) { - if (child->prompt && child->prompt->type == P_MENU) { - menu_cnt++; - fixup_rootmenu(child); - menu_cnt--; - } else if (!menu_cnt) - fixup_rootmenu(child); - } + GtkTreeIter iter; + struct menu *menu; + GtkTreePath *path = gtk_tree_path_new_from_string (path_str); + if (path == NULL) + return; + + GtkTreeModel* model1 = gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree1_w)); + GtkTreeStore* tree1 = GTK_TREE_STORE(model1); + gtk_tree_model_get_iter (model1, &iter, path); + gtk_tree_path_free (path); + gtk_tree_model_get(model1, &iter, COL_MENU, &menu, -1); // get menu data + toggle_sym_value(menu, tree1); // toggle value internally + display_tree_part(menu); // show new tree } - /* Main */ int main(int ac, char *av[]) { @@ -1435,21 +727,24 @@ int main(int ac, char *av[]) printf("%s <config>\n", av[0]); exit(0); } + } + + if (ac > 2 && av[1][0] == '-') { name = av[2]; - } else + } else if(ac>1) { name = av[1]; + } else { + printf("No config file!\n"); + exit(0); + } conf_parse(name); fixup_rootmenu(&rootmenu); conf_read(NULL); - - /* Prepare GtkTreeIter */ - gint i; - for (parents[0] = NULL, i = 1; i < 256; i++) - parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter)); /* Load the interface and connect signals */ init_main_window(ui_file); + init_node_parents(); init_left_tree(); init_right_tree(); show_data(); @@ -1459,9 +754,3 @@ int main(int ac, char *av[]) return 0; } -static void conf_changed(void) -{ - bool changed = conf_get_changed(); - gtk_widget_set_sensitive(save_btn, changed); - gtk_widget_set_sensitive(save_menu_item, changed); -} diff --git a/scripts/kconfig/gconfig/gconf.h b/scripts/kconfig/gconfig/gconf.h new file mode 100644 index 0000000..206c154 --- /dev/null +++ b/scripts/kconfig/gconfig/gconf.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (C) 2013 David Gräff <david.graeff@xxxxxx> + * Copyright (C) 2002-2003 Romain Lievin <roms@xxxxxxxxx> + * Released under the terms of the GNU GPL v2.0. + * + */ + +#ifndef GCONF_H_ +#define GCONF_H_ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdlib.h> +#include <locale.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <strings.h> +#include <time.h> + +#include <gtk/gtk.h> +#include <glib.h> +#include <gdk/gdk.h> + +#include "../lkc.h" + +//#define DEBUG + +extern enum view_mode_enum { + SINGLE_VIEW, SPLIT_VIEW, FULL_VIEW +} view_mode; + +enum { + OPT_NORMAL, OPT_ALL, OPT_PROMPT +}; +enum { + COL_OPTION, COL_NAME, + COL_NO, COL_MOD, COL_YES, + COL_VALUE, + COL_MENU, COL_COLOR, COL_EDIT, + COL_PIXBUF, COL_PIXVIS, + COL_BTNVISIBLE, COL_BTNACT, + COL_BTNINC, COL_BTNRAD, + COL_NO_EN, COL_MOD_EN, COL_YES_EN, + COL_NUMBER +}; + +extern struct gconfwindow_s { + // widget pointer variables + GtkWidget *main_wnd; + GtkWidget *tree1_w; // left frame + GtkWidget *tree2_w; // right frame + GtkWidget *text_w; + GtkWidget *hpaned; + GtkWidget *back_btn; + GtkWidget *save_btn; + GtkWidget *save_menu_item; + // option variables + gboolean show_name; + gboolean show_range; + gboolean show_value; + gboolean resizeable; + int opt_mode; + +} gconfwindow; + +void on_treeview2_makeDisable_clicked(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data); +void on_treeview2_makeModule_clicked(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data); +void on_treeview2_makeEnable_clicked(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data); +void on_treeview1_checkbox_toggle(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data); +void on_treeview2_toggleEnable_clicked(GtkCellRendererToggle *cell, gchar *path_str, + gpointer data); +#endif \ No newline at end of file diff --git a/scripts/kconfig/gconfig/gconf.ui b/scripts/kconfig/gconfig/gconf.ui index 6aa29f7..0effd9f 100644 --- a/scripts/kconfig/gconfig/gconf.ui +++ b/scripts/kconfig/gconfig/gconf.ui @@ -19,7 +19,7 @@ <property name="can_focus">False</property> <property name="title" translatable="yes">Gtk Kernel Configurator</property> <property name="default_width">640</property> - <property name="default_height">250</property> + <property name="default_height">480</property> <signal name="destroy" handler="on_window1_destroy" swapped="no"/> <signal name="delete-event" handler="on_window1_delete_event" swapped="no"/> <child> @@ -437,17 +437,18 @@ <property name="width_request">100</property> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="margin_right">3</property> + <property name="margin_left">3</property> <property name="shadow_type">in</property> <property name="min_content_width">150</property> <child> <object class="GtkTreeView" id="treeview1"> + <property name="width_request">100</property> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="events">GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_STRUCTURE_MASK</property> + <property name="events">GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK</property> <property name="headers_clickable">False</property> <property name="enable_search">False</property> - <signal name="key-press-event" handler="on_treeview2_key_press_event" swapped="no"/> + <signal name="key-press-event" handler="on_treeviews_key_press_event" swapped="no"/> <child internal-child="selection"> <object class="GtkTreeSelection" id="treeview-selection3"> <signal name="changed" handler="on_treeview1_selection_changed" swapped="no"/> @@ -465,7 +466,7 @@ <object class="GtkVPaned" id="vpaned1"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="margin_left">3</property> + <property name="margin_right">3</property> <property name="hexpand">True</property> <child> <object class="GtkScrolledWindow" id="scrolledwindow2"> @@ -476,10 +477,10 @@ <object class="GtkTreeView" id="treeview2"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="events">GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_STRUCTURE_MASK</property> + <property name="events">GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK</property> <property name="enable_search">False</property> <signal name="button-press-event" handler="on_treeview2_button_press_event" swapped="no"/> - <signal name="key-press-event" handler="on_treeview2_key_press_event" swapped="no"/> + <signal name="key-press-event" handler="on_treeviews_key_press_event" swapped="no"/> <child internal-child="selection"> <object class="GtkTreeSelection" id="treeview-selection4"> <signal name="changed" handler="on_treeview2_selection_changed" swapped="no"/> @@ -500,6 +501,7 @@ <property name="can_focus">False</property> <property name="hscrollbar_policy">never</property> <property name="shadow_type">in</property> + <property name="min_content_height">80</property> <child> <object class="GtkTextView" id="textview3"> <property name="visible">True</property> diff --git a/scripts/kconfig/gconfig/gconf_treeview_model.c b/scripts/kconfig/gconfig/gconf_treeview_model.c new file mode 100644 index 0000000..c7689b3 --- /dev/null +++ b/scripts/kconfig/gconfig/gconf_treeview_model.c @@ -0,0 +1,714 @@ +/* + * + * Copyright (C) 2013 David Gräff <david.graeff@xxxxxx> + * Copyright (C) 2002-2003 Romain Lievin <roms@xxxxxxxxx> + * Released under the terms of the GNU GPL v2.0. + * + */ + +#include "gconf_treeview_model.h" +#define IMAGES_TREEVIEW +#include "../images.c" + +static GtkTreeIter *parents[256]; +static gint indent; + + +void init_left_tree(void) +{ + GtkTreeView *view = GTK_TREE_VIEW(gconfwindow.tree1_w); + GtkCellRenderer *renderer; + GtkTreeSelection *sel; + GtkTreeViewColumn *column; + + GtkTreeStore *tree1; + GtkTreeModel *model1; + tree1 = gtk_tree_store_new(COL_NUMBER, + G_TYPE_STRING, G_TYPE_STRING, //Option, Name + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, // COL_NO, COL_MOD, COL_YES + G_TYPE_STRING, // COL_VALUE + G_TYPE_POINTER, GDK_TYPE_COLOR, G_TYPE_BOOLEAN, // COL_MENU, COL_COLOR, COL_EDIT + GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, // COL_PIXBUF, COL_PIXVIS + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, //COL_BTNVISIBLE, COL_BTNACT + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, // COL_BTNINC, COL_BTNRAD, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN // COL_NO_EN, COL_MOD_EN, COL_YES_EN + ); + model1 = GTK_TREE_MODEL(tree1); + + gtk_tree_view_set_model(view, model1); + gtk_tree_view_set_headers_visible(view, TRUE); + gtk_tree_view_set_rules_hint(view, TRUE); + + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_title(column, _("Options")); + + renderer = gtk_cell_renderer_toggle_new(); + g_signal_connect (G_OBJECT(renderer), "toggled", G_CALLBACK + (on_treeview1_checkbox_toggle), NULL); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "active", COL_BTNACT, + "inconsistent", COL_BTNINC, + "visible", COL_BTNVISIBLE, + "radio", COL_BTNRAD, NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "text", COL_OPTION, + "foreground-gdk", + COL_COLOR, NULL); + + sel = gtk_tree_view_get_selection(view); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); + gtk_widget_realize(gconfwindow.tree1_w); +} + +void init_right_tree(void) +{ + GtkTreeView *view = GTK_TREE_VIEW(gconfwindow.tree2_w); + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + GtkTreeStore *tree2; + GtkTreeModel *model2; + tree2 = gtk_tree_store_new(COL_NUMBER, + G_TYPE_STRING, G_TYPE_STRING, //Option, Name + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, // COL_NO, COL_MOD, COL_YES + G_TYPE_STRING, // COL_VALUE + G_TYPE_POINTER, GDK_TYPE_COLOR, G_TYPE_BOOLEAN, // COL_MENU, COL_COLOR, COL_EDIT + GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN, // COL_PIXBUF, COL_PIXVIS + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, //COL_BTNVISIBLE, COL_BTNACT + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, // COL_BTNINC, COL_BTNRAD, + G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN // COL_NO_EN, COL_MOD_EN, COL_YES_EN + ); + model2 = GTK_TREE_MODEL(tree2); + + gtk_tree_view_set_model(view, model2); + gtk_tree_view_set_headers_visible(view, TRUE); + gtk_tree_view_set_rules_hint(view, TRUE); + + // The option name column with the expand icon and enabled checkbox + column = gtk_tree_view_column_new(); + gtk_tree_view_append_column(view, column); + gtk_tree_view_column_set_title(column, _("Options")); + + // The expand icon + renderer = gtk_cell_renderer_pixbuf_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "pixbuf", COL_PIXBUF, + "visible", COL_PIXVIS, NULL); + // The enabled/module/disabled checkbox + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "active", COL_BTNACT, + "inconsistent", COL_BTNINC, + "visible", COL_BTNVISIBLE, + "radio", COL_BTNRAD, NULL); + g_signal_connect (G_OBJECT(renderer), "toggled", G_CALLBACK + (on_treeview2_toggleEnable_clicked), NULL); + // The options name + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), + renderer, FALSE); + gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column), + renderer, + "text", COL_OPTION, + "foreground-gdk", + COL_COLOR, NULL); + + // The internal name column + // The internal name + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + _("Name"), renderer, + "text", COL_NAME, + "foreground-gdk", + COL_COLOR, NULL); + column = gtk_tree_view_get_column(view, COL_NAME); + gtk_tree_view_column_set_visible(column, gconfwindow.show_name); + + // Range column (Disable) + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "N", renderer, + "active", COL_NO, + "visible", COL_NO_EN, + NULL); + column = gtk_tree_view_get_column(view, COL_NO); + gtk_tree_view_column_set_visible(column, gconfwindow.show_range); + gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(renderer), TRUE); + g_signal_connect (G_OBJECT(renderer), "toggled", G_CALLBACK + (on_treeview2_makeDisable_clicked), NULL); + + // Range column (Module) + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "M", renderer, + "active", COL_MOD, + "visible", COL_MOD_EN, + NULL); + column = gtk_tree_view_get_column(view, COL_MOD); + gtk_tree_view_column_set_visible(column, gconfwindow.show_range); + gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(renderer), TRUE); + g_signal_connect (G_OBJECT(renderer), "toggled", G_CALLBACK + (on_treeview2_makeModule_clicked), NULL); + + // Range column (Enable) + renderer = gtk_cell_renderer_toggle_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + "Y", renderer, + "active", COL_YES, + "visible", COL_YES_EN, + NULL); + column = gtk_tree_view_get_column(view, COL_YES); + gtk_tree_view_column_set_visible(column, gconfwindow.show_range); + gtk_cell_renderer_toggle_set_radio(GTK_CELL_RENDERER_TOGGLE(renderer), TRUE); + g_signal_connect (G_OBJECT(renderer), "toggled", G_CALLBACK + (on_treeview2_makeEnable_clicked), NULL); + + // Current value column + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(view, -1, + _("Value"), renderer, + "text", COL_VALUE, + "editable", + COL_EDIT, + "foreground-gdk", + COL_COLOR, NULL); + column = gtk_tree_view_get_column(view, COL_VALUE); + gtk_tree_view_column_set_visible(column, gconfwindow.show_value); + g_signal_connect(G_OBJECT(renderer), "edited", + G_CALLBACK(renderer_edited), NULL); + + if (gconfwindow.resizeable) { + for (int i = 0; i < COL_VALUE; i++) { + column = gtk_tree_view_get_column(view, i); + gtk_tree_view_column_set_resizable(column, TRUE); + } + } + + GtkTreeSelection *sel = gtk_tree_view_get_selection(view); + gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); +} + +/* CTree Callbacks */ + +/* Change hex/int/string value in the cell */ +void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data) +{ + GtkTreePath *path = gtk_tree_path_new_from_string(path_string); + GtkTreeIter iter; + const char *old_def, *new_def; + struct menu *menu; + struct symbol *sym; + + GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w)); + GtkTreeStore* tree2 = GTK_TREE_STORE(model2); + + if (!gtk_tree_model_get_iter(model2, &iter, path)) + return; + + gtk_tree_model_get(model2, &iter, COL_MENU, &menu, -1); + sym = menu->sym; + + gtk_tree_model_get(model2, &iter, COL_VALUE, &old_def, -1); + new_def = new_text; + + sym_set_string_value(sym, new_def); + + update_tree(&rootmenu, NULL, tree2); + + gtk_tree_path_free(path); +} + +struct menu *currentMenu = 0; // currentMenu node + +struct menu *getCurrentMenu(void) { + return currentMenu; +} + +/* Change the value of a symbol and update the tree */ +void change_sym_value(struct menu *menu, gint col, GtkTreeStore* tree) +{ + struct symbol *sym = menu->sym; + tristate newval; + + if (!sym) + return; + + if (col == COL_NO) + newval = no; + else if (col == COL_MOD) + newval = mod; + else if (col == COL_YES) + newval = yes; + else + return; + + switch (sym_get_type(sym)) { + case S_BOOLEAN: + case S_TRISTATE: + if (!sym_tristate_within_range(sym, newval)) + newval = yes; + sym_set_tristate_value(sym, newval); + if (view_mode == FULL_VIEW) + update_tree(&rootmenu, NULL, tree); + else if (view_mode == SPLIT_VIEW) { + update_tree(currentMenu, NULL, tree); + display_list(); + } + else if (view_mode == SINGLE_VIEW) + display_tree_part(currentMenu); //fixme: keep exp/coll + break; + case S_INT: + case S_HEX: + case S_STRING: + default: + break; + } +} + +void toggle_sym_value(struct menu *menu, GtkTreeStore* tree) +{ + if (!menu->sym) + return; + + sym_toggle_tristate_value(menu->sym); + if (view_mode == FULL_VIEW) + update_tree(&rootmenu, NULL, tree); + else if (view_mode == SPLIT_VIEW) { + update_tree(currentMenu, NULL, tree); + display_list(); + } + else if (view_mode == SINGLE_VIEW) + display_tree_part(currentMenu); //fixme: keep exp/coll +} + + +/* Fill a row of strings */ +gchar **fill_row(struct menu *menu) +{ + static gchar *row[COL_NUMBER]; + struct symbol *sym = menu->sym; + const char *def; + int stype; + tristate val; + enum prop_type ptype; + + g_free(row[COL_OPTION]); + g_free(row[COL_NAME]); + g_free(row[COL_VALUE]); + g_free(row[COL_MENU]); + g_free(row[COL_COLOR]); + + bzero(row, sizeof(row)); + + row[COL_OPTION] = + g_strdup_printf("%s %s", _(menu_get_prompt(menu)), + sym && !sym_has_value(sym) ? "(NEW)" : ""); + + if (gconfwindow.opt_mode == OPT_ALL && !menu_is_visible(menu)) + row[COL_COLOR] = g_strdup("DarkGray"); + else if (gconfwindow.opt_mode == OPT_PROMPT && + menu_has_prompt(menu) && !menu_is_visible(menu)) + row[COL_COLOR] = g_strdup("DarkGray"); + else + row[COL_COLOR] = g_strdup("Black"); + + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + switch (ptype) { + case P_MENU: + row[COL_PIXBUF] = (gchar *) xpm_menu; + if (view_mode == SINGLE_VIEW) + row[COL_PIXVIS] = GINT_TO_POINTER(TRUE); + row[COL_BTNVISIBLE] = GINT_TO_POINTER(FALSE); + break; + case P_COMMENT: + row[COL_PIXBUF] = (gchar *) xpm_void; + row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); + row[COL_BTNVISIBLE] = GINT_TO_POINTER(FALSE); + break; + default: + row[COL_PIXBUF] = (gchar *) xpm_void; + row[COL_PIXVIS] = GINT_TO_POINTER(FALSE); + row[COL_BTNVISIBLE] = GINT_TO_POINTER(TRUE); + break; + } + + if (!sym) + return row; + row[COL_NAME] = g_strdup(sym->name); + + sym_calc_value(sym); + sym->flags &= ~SYMBOL_CHANGED; + + if (sym_is_choice(sym)) { // parse childs for getting final value + struct menu *child; + struct symbol *def_sym = sym_get_choice_value(sym); + struct menu *def_menu = NULL; + + row[COL_BTNVISIBLE] = GINT_TO_POINTER(FALSE); + + for (child = menu->list; child; child = child->next) { + if (menu_is_visible(child) + && child->sym == def_sym) + def_menu = child; + } + + if (def_menu) + row[COL_VALUE] = + g_strdup(_(menu_get_prompt(def_menu))); + } + if (sym->flags & SYMBOL_CHOICEVAL) + row[COL_BTNRAD] = GINT_TO_POINTER(TRUE); + + stype = sym_get_type(sym); + switch (stype) { + case S_BOOLEAN: + if (GPOINTER_TO_INT(row[COL_PIXVIS]) == FALSE) + row[COL_BTNVISIBLE] = GINT_TO_POINTER(TRUE); + if (sym_is_choice(sym)) + break; + /* fall through */ + case S_TRISTATE: + val = sym_get_tristate_value(sym); + switch (val) { + case no: + row[COL_NO] = GINT_TO_POINTER(TRUE); + row[COL_VALUE] = g_strdup("[No]"); + row[COL_BTNACT] = GINT_TO_POINTER(FALSE); + row[COL_BTNINC] = GINT_TO_POINTER(FALSE); + break; + case mod: + row[COL_MOD] = GINT_TO_POINTER(TRUE); + row[COL_VALUE] = g_strdup("[Module]"); + row[COL_BTNINC] = GINT_TO_POINTER(TRUE); + break; + case yes: + row[COL_YES] = GINT_TO_POINTER(TRUE); + row[COL_VALUE] = g_strdup("[Yes]"); + row[COL_BTNACT] = GINT_TO_POINTER(TRUE); + row[COL_BTNINC] = GINT_TO_POINTER(FALSE); + break; + } + + row[COL_NO_EN] = GINT_TO_POINTER(sym_tristate_within_range(sym, no)); // No is allowed + row[COL_MOD_EN] = GINT_TO_POINTER(sym_tristate_within_range(sym, mod)); // Mod is allowed + row[COL_YES_EN] = GINT_TO_POINTER(sym_tristate_within_range(sym, yes)); // Yes is allowed + break; + case S_INT: + case S_HEX: + case S_STRING: + def = sym_get_string_value(sym); + row[COL_VALUE] = g_strdup(def); + row[COL_EDIT] = GINT_TO_POINTER(TRUE); + row[COL_BTNVISIBLE] = GINT_TO_POINTER(FALSE); + break; + } + + return row; +} + + +/* Set the node content with a row of strings */ +void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row, GtkTreeStore* tree) +{ + GdkColor color; + GdkPixbuf *pix; + + pix = gdk_pixbuf_new_from_xpm_data((const char **) + row[COL_PIXBUF]); + + gdk_color_parse(row[COL_COLOR], &color); +// gdk_colormap_alloc_colors(gdk_colormap_get_system(), &color, 1, +// FALSE, FALSE, &success); + + gtk_tree_store_set(tree, node, + COL_OPTION, row[COL_OPTION], + COL_NAME, row[COL_NAME], + COL_NO, row[COL_NO], + COL_MOD, row[COL_MOD], + COL_YES, row[COL_YES], + COL_VALUE, row[COL_VALUE], + COL_MENU, (gpointer) menu, + COL_COLOR, &color, + COL_EDIT, GPOINTER_TO_INT(row[COL_EDIT]), + COL_PIXBUF, pix, + COL_PIXVIS, GPOINTER_TO_INT(row[COL_PIXVIS]), + COL_BTNVISIBLE, GPOINTER_TO_INT(row[COL_BTNVISIBLE]), + COL_BTNACT, GPOINTER_TO_INT(row[COL_BTNACT]), + COL_BTNINC, GPOINTER_TO_INT(row[COL_BTNINC]), + COL_BTNRAD, GPOINTER_TO_INT(row[COL_BTNRAD]), + COL_NO_EN, GPOINTER_TO_INT(row[COL_NO_EN]), + COL_MOD_EN, GPOINTER_TO_INT(row[COL_MOD_EN]), + COL_YES_EN, GPOINTER_TO_INT(row[COL_YES_EN]), + -1); + + g_object_unref(pix); +} + +void init_node_parents(void) +{ + /* Prepare GtkTreeIter */ + gint i; + for (parents[0] = NULL, i = 1; i < 256; i++) + parents[i] = (GtkTreeIter *) g_malloc(sizeof(GtkTreeIter)); + +} + +/* Add a node to the tree */ +void place_node(struct menu *menu, char **row, GtkTreeStore* tree) +{ + GtkTreeIter *parent = parents[indent - 1]; + GtkTreeIter *node = parents[indent]; + + gtk_tree_store_append(tree, node, parent); + set_node(node, menu, row, tree); +} + +/* + * Find a menu in the GtkTree starting at parent. + */ +GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, + struct menu *tofind) +{ + static GtkTreeIter found; + GtkTreeIter iter; + GtkTreeIter *child = &iter; + gboolean valid; + GtkTreeIter *ret; + + GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w)); + valid = gtk_tree_model_iter_children(model2, child, parent); + while (valid) { + struct menu *menu; + + gtk_tree_model_get(model2, child, 6, &menu, -1); + + if (menu == tofind) { + memcpy(&found, child, sizeof(GtkTreeIter)); + return &found; + } + + ret = gtktree_iter_find_node(child, tofind); + if (ret) + return ret; + + valid = gtk_tree_model_iter_next(model2, child); + } + + return NULL; +} + + +/* + * Update the tree by adding/removing entries + * Does not change other nodes + */ +void update_tree(struct menu *src, GtkTreeIter * dst, GtkTreeStore* tree) +{ + struct menu *child1; + GtkTreeIter iter, tmp; + GtkTreeIter *child2 = &iter; + gboolean valid; + GtkTreeIter *sibling; + struct symbol *sym; + struct menu *menu1, *menu2; + + if (src == &rootmenu) + indent = 1; + + GtkTreeModel* model2 = gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w)); + valid = gtk_tree_model_iter_children(model2, child2, dst); + for (child1 = src->list; child1; child1 = child1->next) { + + sym = child1->sym; + + reparse: + menu1 = child1; + if (valid) + gtk_tree_model_get(model2, child2, COL_MENU, + &menu2, -1); + else + menu2 = NULL; // force adding of a first child + +#ifdef DEBUG + printf("%*c%s | %s\n", indent, ' ', + menu1 ? menu_get_prompt(menu1) : "nil", + menu2 ? menu_get_prompt(menu2) : "nil"); +#endif + + if ((gconfwindow.opt_mode == OPT_NORMAL && !menu_is_visible(child1)) || + (gconfwindow.opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) || + (gconfwindow.opt_mode == OPT_ALL && !menu_get_prompt(child1))) { + + /* remove node */ + if (gtktree_iter_find_node(dst, menu1) != NULL) { + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree, &tmp); + if (!valid) + return; /* next parent */ + else + goto reparse; /* next child */ + } else + continue; + } + + if (menu1 != menu2) { + if (gtktree_iter_find_node(dst, menu1) == NULL) { // add node + if (!valid && !menu2) + sibling = NULL; + else + sibling = child2; + gtk_tree_store_insert_before(tree, + child2, + dst, sibling); + set_node(child2, menu1, fill_row(menu1), tree); + if (menu2 == NULL) + valid = TRUE; + } else { // remove node + memcpy(&tmp, child2, sizeof(GtkTreeIter)); + valid = gtk_tree_model_iter_next(model2, + child2); + gtk_tree_store_remove(tree, &tmp); + if (!valid) + return; // next parent + else + goto reparse; // next child + } + } else if (sym && (sym->flags & SYMBOL_CHANGED)) { + set_node(child2, menu1, fill_row(menu1), tree); + } + + indent++; + update_tree(child1, child2, tree); + indent--; + + valid = gtk_tree_model_iter_next(model2, child2); + } +} + + +/* Display the whole tree (single/split/full view) */ +void display_tree(struct menu *menu, GtkTreeStore* tree) +{ + struct symbol *sym; + struct property *prop; + struct menu *child; + enum prop_type ptype; + GtkTreeStore* tree1 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree1_w))); + GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w))); + + if (menu == &rootmenu) { + indent = 1; + currentMenu = &rootmenu; + } + + for (child = menu->list; child; child = child->next) { + prop = child->prompt; + sym = child->sym; + ptype = prop ? prop->type : P_UNKNOWN; + + if (sym) + sym->flags &= ~SYMBOL_CHANGED; + + if ((view_mode == SPLIT_VIEW) + && !(child->flags & MENU_ROOT) && (tree == tree1)) + continue; + + if ((view_mode == SPLIT_VIEW) && (child->flags & MENU_ROOT) + && (tree == tree2)) + continue; + + if ((gconfwindow.opt_mode == OPT_NORMAL && menu_is_visible(child)) || + (gconfwindow.opt_mode == OPT_PROMPT && menu_has_prompt(child)) || + (gconfwindow.opt_mode == OPT_ALL && menu_get_prompt(child))) + place_node(child, fill_row(child), tree); +#ifdef DEBUG + printf("%*c%s: ", indent, ' ', menu_get_prompt(child)); + printf("%s", child->flags & MENU_ROOT ? "rootmenu | " : ""); + printf("%s", prop_get_type_name(ptype)); + printf(" | "); + if (sym) { + printf("%s", sym_type_name(sym->type)); + printf(" | "); + printf("%s", dbg_sym_flags(sym->flags)); + printf("\n"); + } else + printf("\n"); +#endif + if ((view_mode != FULL_VIEW) && (ptype == P_MENU) + && (tree == tree2)) + continue; +/* + if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT)) + || (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW))*/ + + /* Change paned position if the view is not in 'split mode' */ + if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) { + gtk_paned_set_position(GTK_PANED(gconfwindow.hpaned), 0); + } + + if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT)) + || (view_mode == FULL_VIEW) + || (view_mode == SPLIT_VIEW)) { + indent++; + display_tree(child, tree); + indent--; + } + } +} + +/* Display a part of the tree starting at current node (single/split view) */ +void display_tree_part(struct menu *menu) +{ + GtkTreeStore* tree2 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree2_w))); + gtk_tree_store_clear(tree2); + + currentMenu = menu; + + display_tree(menu, tree2); + gtk_tree_view_expand_all(GTK_TREE_VIEW(gconfwindow.tree2_w)); +} + +/* Display the list in the left frame (split view) */ +void display_list(void) +{ + GtkTreeStore* tree1 = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW (gconfwindow.tree1_w))); + gtk_tree_store_clear(tree1); + + display_tree(&rootmenu, tree1); + gtk_tree_view_expand_all(GTK_TREE_VIEW(gconfwindow.tree1_w)); +} + +void fixup_rootmenu(struct menu *menu) +{ + struct menu *child; + static int menu_cnt = 0; + + menu->flags |= MENU_ROOT; + for (child = menu->list; child; child = child->next) { + if (child->prompt && child->prompt->type == P_MENU) { + menu_cnt++; + fixup_rootmenu(child); + menu_cnt--; + } else if (!menu_cnt) + fixup_rootmenu(child); + } +} diff --git a/scripts/kconfig/gconfig/gconf_treeview_model.h b/scripts/kconfig/gconfig/gconf_treeview_model.h new file mode 100644 index 0000000..7648da2 --- /dev/null +++ b/scripts/kconfig/gconfig/gconf_treeview_model.h @@ -0,0 +1,43 @@ +/* + * + * Copyright (C) 2013 David Gräff <david.graeff@xxxxxx> + * Copyright (C) 2002-2003 Romain Lievin <roms@xxxxxxxxx> + * Released under the terms of the GNU GPL v2.0. + * + */ + +#ifndef GCONF_TREEVIEW_MODEL_H_ +#define GCONF_TREEVIEW_MODEL_H_ + +#include "gconf.h" + +// tree and model init +void init_right_tree(void); +void init_left_tree(void); + +void renderer_edited(GtkCellRendererText * cell, + const gchar * path_string, + const gchar * new_text, gpointer user_data); + +// model update operations +void change_sym_value(struct menu *menu, gint col, GtkTreeStore* tree); +void toggle_sym_value(struct menu *menu, GtkTreeStore* tree); + +// node operations +void init_node_parents(void); +void set_node(GtkTreeIter * node, struct menu *menu, gchar ** row, GtkTreeStore* tree); +void place_node(struct menu *menu, char **row, GtkTreeStore* tree); +GtkTreeIter *gtktree_iter_find_node(GtkTreeIter * parent, + struct menu *tofind); +gchar **fill_row(struct menu *menu); + +// tree operations +void update_tree(struct menu *src, GtkTreeIter * dst, GtkTreeStore* tree); +void display_tree(struct menu *menu, GtkTreeStore* tree); +void display_tree_part(struct menu *menu); +void display_list(void); +void fixup_rootmenu(struct menu *menu); + +struct menu *getCurrentMenu(void); + +#endif diff --git a/scripts/kconfig/gconfig/util.h b/scripts/kconfig/gconfig/util.h new file mode 100644 index 0000000..876ec26 --- /dev/null +++ b/scripts/kconfig/gconfig/util.h @@ -0,0 +1,33 @@ + +/* Helping/Debugging Functions */ + +#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) +const char *dbg_sym_flags(int val) +{ + static char buf[256]; + + bzero(buf, 256); + + if (val & SYMBOL_CONST) + strcat(buf, "const/"); + if (val & SYMBOL_CHECK) + strcat(buf, "check/"); + if (val & SYMBOL_CHOICE) + strcat(buf, "choice/"); + if (val & SYMBOL_CHOICEVAL) + strcat(buf, "choiceval/"); + if (val & SYMBOL_VALID) + strcat(buf, "valid/"); + if (val & SYMBOL_OPTIONAL) + strcat(buf, "optional/"); + if (val & SYMBOL_WRITE) + strcat(buf, "write/"); + if (val & SYMBOL_CHANGED) + strcat(buf, "changed/"); + if (val & SYMBOL_AUTO) + strcat(buf, "auto/"); + + buf[strlen(buf) - 1] = '\0'; + + return buf; +} -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html