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