00001
00002
00003
00004
00005
00006
00007
00008
00009
#ifdef HAVE_CONFIG_H
00010
# include <config.h>
00011
#endif
00012
00013
#include "lkc.h"
00014
#include "images.c"
00015
00016
#include <glade/glade.h>
00017
#include <gtk/gtk.h>
00018
#include <glib.h>
00019
#include <gdk/gdkkeysyms.h>
00020
00021
#include <stdio.h>
00022
#include <string.h>
00023
#include <unistd.h>
00024
#include <time.h>
00025
#include <stdlib.h>
00026
00027
00028
00029
enum {
00030
SINGLE_VIEW,
SPLIT_VIEW,
FULL_VIEW
00031 };
00032
00033 static gint
view_mode =
FULL_VIEW;
00034 static gboolean
show_name = TRUE;
00035 static gboolean
show_range = TRUE;
00036 static gboolean
show_value = TRUE;
00037 static gboolean
show_all = FALSE;
00038 static gboolean
show_debug = FALSE;
00039 static gboolean
resizeable = FALSE;
00040
00041 static gboolean
config_changed = FALSE;
00042
00043 static char nohelp_text[] =
00044
"Sorry, no help available for this option yet.\n";
00045
00046 GtkWidget *
main_wnd = NULL;
00047 GtkWidget *
tree1_w = NULL;
00048 GtkWidget *
tree2_w = NULL;
00049 GtkWidget *
text_w = NULL;
00050 GtkWidget *
hpaned = NULL;
00051 GtkWidget *
vpaned = NULL;
00052 GtkWidget *
back_btn = NULL;
00053
00054 GtkTextTag *
tag1, *
tag2;
00055 GdkColor
color;
00056
00057 GtkTreeStore *
tree1, *
tree2, *
tree;
00058 GtkTreeModel *
model1, *
model2;
00059 static GtkTreeIter *
parents[256];
00060 static gint
indent;
00061
00062 static struct menu *
current;
00063 static struct menu *
browsed;
00064
00065
enum {
00066
COL_OPTION,
COL_NAME,
COL_NO,
COL_MOD,
COL_YES,
COL_VALUE,
00067
COL_MENU,
COL_COLOR,
COL_EDIT,
COL_PIXBUF,
00068
COL_PIXVIS,
COL_BTNVIS,
COL_BTNACT,
COL_BTNINC,
COL_BTNRAD,
00069
COL_NUMBER
00070 };
00071
00072
static void display_list(
void);
00073
static void display_tree(
struct menu *
menu);
00074
static void display_tree_part(
void);
00075
static void update_tree(
struct menu *src, GtkTreeIter * dst);
00076
static void set_node(GtkTreeIter * node,
struct menu *
menu, gchar ** row);
00077
static gchar **
fill_row(
struct menu *
menu);
00078
00079
00080
00081
00082
00083 const char *
dbg_print_stype(
int val)
00084 {
00085
static char buf[256];
00086
00087 bzero(buf, 256);
00088
00089
if (val ==
S_UNKNOWN)
00090 strcpy(buf,
"unknown");
00091
if (val ==
S_BOOLEAN)
00092 strcpy(buf,
"boolean");
00093
if (val ==
S_TRISTATE)
00094 strcpy(buf,
"tristate");
00095
if (val ==
S_INT)
00096 strcpy(buf,
"int");
00097
if (val ==
S_HEX)
00098 strcpy(buf,
"hex");
00099
if (val ==
S_STRING)
00100 strcpy(buf,
"string");
00101
if (val ==
S_OTHER)
00102 strcpy(buf,
"other");
00103
00104
#ifdef DEBUG
00105
printf(
"%s", buf);
00106
#endif
00107
00108
return buf;
00109 }
00110
00111 const char *
dbg_print_flags(
int val)
00112 {
00113
static char buf[256];
00114
00115 bzero(buf, 256);
00116
00117
if (val &
SYMBOL_YES)
00118 strcat(buf,
"yes/");
00119
if (val &
SYMBOL_MOD)
00120 strcat(buf,
"mod/");
00121
if (val &
SYMBOL_NO)
00122 strcat(buf,
"no/");
00123
if (val &
SYMBOL_CONST)
00124 strcat(buf,
"const/");
00125
if (val &
SYMBOL_CHECK)
00126 strcat(buf,
"check/");
00127
if (val &
SYMBOL_CHOICE)
00128 strcat(buf,
"choice/");
00129
if (val &
SYMBOL_CHOICEVAL)
00130 strcat(buf,
"choiceval/");
00131
if (val &
SYMBOL_PRINTED)
00132 strcat(buf,
"printed/");
00133
if (val &
SYMBOL_VALID)
00134 strcat(buf,
"valid/");
00135
if (val &
SYMBOL_OPTIONAL)
00136 strcat(buf,
"optional/");
00137
if (val &
SYMBOL_WRITE)
00138 strcat(buf,
"write/");
00139
if (val &
SYMBOL_CHANGED)
00140 strcat(buf,
"changed/");
00141
if (val &
SYMBOL_NEW)
00142 strcat(buf,
"new/");
00143
if (val &
SYMBOL_AUTO)
00144 strcat(buf,
"auto/");
00145
00146 buf[strlen(buf) - 1] =
'\0';
00147
#ifdef DEBUG
00148
printf(
"%s", buf);
00149
#endif
00150
00151
return buf;
00152 }
00153
00154 const char *
dbg_print_ptype(
int val)
00155 {
00156
static char buf[256];
00157
00158 bzero(buf, 256);
00159
00160
if (val ==
P_UNKNOWN)
00161 strcpy(buf,
"unknown");
00162
if (val ==
P_PROMPT)
00163 strcpy(buf,
"prompt");
00164
if (val ==
P_COMMENT)
00165 strcpy(buf,
"comment");
00166
if (val ==
P_MENU)
00167 strcpy(buf,
"menu");
00168
if (val ==
P_DEFAULT)
00169 strcpy(buf,
"default");
00170
if (val ==
P_CHOICE)
00171 strcpy(buf,
"choice");
00172
00173
#ifdef DEBUG
00174
printf(
"%s", buf);
00175
#endif
00176
00177
return buf;
00178 }
00179
00180
00181
00182
00183
00184 void init_main_window(
const gchar * glade_file)
00185 {
00186 GladeXML *xml;
00187 GtkWidget *widget;
00188 GtkTextBuffer *txtbuf;
00189 GdkPixmap *pixmap;
00190 GdkBitmap *mask;
00191 GtkStyle *style;
00192
00193 xml = glade_xml_new(glade_file,
"window1", NULL);
00194
if (!xml)
00195 g_error(
"GUI loading failed !\n");
00196 glade_xml_signal_autoconnect(xml);
00197
00198
main_wnd = glade_xml_get_widget(xml,
"window1");
00199
hpaned = glade_xml_get_widget(xml,
"hpaned1");
00200
vpaned = glade_xml_get_widget(xml,
"vpaned1");
00201
tree1_w = glade_xml_get_widget(xml,
"treeview1");
00202
tree2_w = glade_xml_get_widget(xml,
"treeview2");
00203
text_w = glade_xml_get_widget(xml,
"textview3");
00204
00205
back_btn = glade_xml_get_widget(xml,
"button1");
00206 gtk_widget_set_sensitive(
back_btn, FALSE);
00207
00208 widget = glade_xml_get_widget(xml,
"show_name1");
00209 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
00210
show_name);
00211
00212 widget = glade_xml_get_widget(xml,
"show_range1");
00213 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
00214
show_range);
00215
00216 widget = glade_xml_get_widget(xml,
"show_data1");
00217 gtk_check_menu_item_set_active((GtkCheckMenuItem *) widget,
00218
show_value);
00219
00220 style = gtk_widget_get_style(
main_wnd);
00221 widget = glade_xml_get_widget(xml,
"toolbar1");
00222
00223 pixmap = gdk_pixmap_create_from_xpm_d(
main_wnd->window, &mask,
00224 &style->bg[GTK_STATE_NORMAL],
00225 (gchar **) xpm_single_view);
00226 gtk_image_set_from_pixmap(GTK_IMAGE
00227 (((GtkToolbarChild
00228 *) (g_list_nth(GTK_TOOLBAR(widget)->
00229 children,
00230 5)->data))->icon),
00231 pixmap, mask);
00232 pixmap =
00233 gdk_pixmap_create_from_xpm_d(
main_wnd->window, &mask,
00234 &style->bg[GTK_STATE_NORMAL],
00235 (gchar **) xpm_split_view);
00236 gtk_image_set_from_pixmap(GTK_IMAGE
00237 (((GtkToolbarChild
00238 *) (g_list_nth(GTK_TOOLBAR(widget)->
00239 children,
00240 6)->data))->icon),
00241 pixmap, mask);
00242 pixmap =
00243 gdk_pixmap_create_from_xpm_d(
main_wnd->window, &mask,
00244 &style->bg[GTK_STATE_NORMAL],
00245 (gchar **) xpm_tree_view);
00246 gtk_image_set_from_pixmap(GTK_IMAGE
00247 (((GtkToolbarChild
00248 *) (g_list_nth(GTK_TOOLBAR(widget)->
00249 children,
00250 7)->data))->icon),
00251 pixmap, mask);
00252
00253
switch (
view_mode) {
00254
case SINGLE_VIEW:
00255 widget = glade_xml_get_widget(xml,
"button4");
00256 gtk_button_clicked(GTK_BUTTON(widget));
00257
break;
00258
case SPLIT_VIEW:
00259 widget = glade_xml_get_widget(xml,
"button5");
00260 gtk_button_clicked(GTK_BUTTON(widget));
00261
break;
00262
case FULL_VIEW:
00263 widget = glade_xml_get_widget(xml,
"button6");
00264 gtk_button_clicked(GTK_BUTTON(widget));
00265
break;
00266 }
00267
00268 txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(
text_w));
00269
tag1 = gtk_text_buffer_create_tag(txtbuf,
"mytag1",
00270
"foreground",
"red",
00271
"weight", PANGO_WEIGHT_BOLD,
00272 NULL);
00273
tag2 = gtk_text_buffer_create_tag(txtbuf,
"mytag2",
00274
00275 NULL);
00276 }
00277
00278 void init_tree_model(
void)
00279 {
00280 gint i;
00281
00282
tree =
tree2 = gtk_tree_store_new(
COL_NUMBER,
00283 G_TYPE_STRING, G_TYPE_STRING,
00284 G_TYPE_STRING, G_TYPE_STRING,
00285 G_TYPE_STRING, G_TYPE_STRING,
00286 G_TYPE_POINTER, GDK_TYPE_COLOR,
00287 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
00288 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
00289 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
00290 G_TYPE_BOOLEAN);
00291
model2 = GTK_TREE_MODEL(
tree2);
00292
00293
for (
parents[0] = NULL, i = 1; i < 256; i++)
00294
parents[i] = (GtkTreeIter *) g_malloc(
sizeof(GtkTreeIter));
00295
00296
tree1 = gtk_tree_store_new(
COL_NUMBER,
00297 G_TYPE_STRING, G_TYPE_STRING,
00298 G_TYPE_STRING, G_TYPE_STRING,
00299 G_TYPE_STRING, G_TYPE_STRING,
00300 G_TYPE_POINTER, GDK_TYPE_COLOR,
00301 G_TYPE_BOOLEAN, GDK_TYPE_PIXBUF,
00302 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
00303 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
00304 G_TYPE_BOOLEAN);
00305
model1 = GTK_TREE_MODEL(
tree1);
00306 }
00307
00308 void init_left_tree(
void)
00309 {
00310 GtkTreeView *view = GTK_TREE_VIEW(
tree1_w);
00311 GtkCellRenderer *renderer;
00312 GtkTreeSelection *sel;
00313 GtkTreeViewColumn *column;
00314
00315 gtk_tree_view_set_model(view,
model1);
00316 gtk_tree_view_set_headers_visible(view, TRUE);
00317 gtk_tree_view_set_rules_hint(view, FALSE);
00318
00319 column = gtk_tree_view_column_new();
00320 gtk_tree_view_append_column(view, column);
00321 gtk_tree_view_column_set_title(column,
"Options");
00322
00323 renderer = gtk_cell_renderer_toggle_new();
00324 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
00325 renderer, FALSE);
00326 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
00327 renderer,
00328
"active",
COL_BTNACT,
00329
"inconsistent",
COL_BTNINC,
00330
"visible",
COL_BTNVIS,
00331
"radio",
COL_BTNRAD, NULL);
00332 renderer = gtk_cell_renderer_text_new();
00333 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
00334 renderer, FALSE);
00335 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
00336 renderer,
00337
"text",
COL_OPTION,
00338
"foreground-gdk",
00339
COL_COLOR, NULL);
00340
00341 sel = gtk_tree_view_get_selection(view);
00342 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
00343 gtk_widget_realize(
tree1_w);
00344 }
00345
00346
static void renderer_edited(GtkCellRendererText * cell,
00347
const gchar * path_string,
00348
const gchar * new_text, gpointer user_data);
00349
static void renderer_toggled(GtkCellRendererToggle * cellrenderertoggle,
00350 gchar * arg1, gpointer user_data);
00351
00352 void init_right_tree(
void)
00353 {
00354 GtkTreeView *view = GTK_TREE_VIEW(
tree2_w);
00355 GtkCellRenderer *renderer;
00356 GtkTreeSelection *sel;
00357 GtkTreeViewColumn *column;
00358 gint i;
00359
00360 gtk_tree_view_set_model(view,
model2);
00361 gtk_tree_view_set_headers_visible(view, TRUE);
00362 gtk_tree_view_set_rules_hint(view, FALSE);
00363
00364 column = gtk_tree_view_column_new();
00365 gtk_tree_view_append_column(view, column);
00366 gtk_tree_view_column_set_title(column,
"Options");
00367
00368 renderer = gtk_cell_renderer_pixbuf_new();
00369 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
00370 renderer, FALSE);
00371 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
00372 renderer,
00373
"pixbuf",
COL_PIXBUF,
00374
"visible",
COL_PIXVIS, NULL);
00375 renderer = gtk_cell_renderer_toggle_new();
00376 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
00377 renderer, FALSE);
00378 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
00379 renderer,
00380
"active",
COL_BTNACT,
00381
"inconsistent",
COL_BTNINC,
00382
"visible",
COL_BTNVIS,
00383
"radio",
COL_BTNRAD, NULL);
00384
00385
00386 renderer = gtk_cell_renderer_text_new();
00387 gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column),
00388 renderer, FALSE);
00389 gtk_tree_view_column_set_attributes(GTK_TREE_VIEW_COLUMN(column),
00390 renderer,
00391
"text",
COL_OPTION,
00392
"foreground-gdk",
00393
COL_COLOR, NULL);
00394
00395 renderer = gtk_cell_renderer_text_new();
00396 gtk_tree_view_insert_column_with_attributes(view, -1,
00397
"Name", renderer,
00398
"text",
COL_NAME,
00399
"foreground-gdk",
00400
COL_COLOR, NULL);
00401 renderer = gtk_cell_renderer_text_new();
00402 gtk_tree_view_insert_column_with_attributes(view, -1,
00403
"N", renderer,
00404
"text",
COL_NO,
00405
"foreground-gdk",
00406
COL_COLOR, NULL);
00407 renderer = gtk_cell_renderer_text_new();
00408 gtk_tree_view_insert_column_with_attributes(view, -1,
00409
"M", renderer,
00410
"text",
COL_MOD,
00411
"foreground-gdk",
00412
COL_COLOR, NULL);
00413 renderer = gtk_cell_renderer_text_new();
00414 gtk_tree_view_insert_column_with_attributes(view, -1,
00415
"Y", renderer,
00416
"text",
COL_YES,
00417
"foreground-gdk",
00418
COL_COLOR, NULL);
00419 renderer = gtk_cell_renderer_text_new();
00420 gtk_tree_view_insert_column_with_attributes(view, -1,
00421
"Value", renderer,
00422
"text",
COL_VALUE,
00423
"editable",
00424
COL_EDIT,
00425
"foreground-gdk",
00426
COL_COLOR, NULL);
00427 g_signal_connect(G_OBJECT(renderer),
"edited",
00428 G_CALLBACK(
renderer_edited), NULL);
00429
00430 column = gtk_tree_view_get_column(view,
COL_NAME);
00431 gtk_tree_view_column_set_visible(column,
show_name);
00432 column = gtk_tree_view_get_column(view,
COL_NO);
00433 gtk_tree_view_column_set_visible(column,
show_range);
00434 column = gtk_tree_view_get_column(view,
COL_MOD);
00435 gtk_tree_view_column_set_visible(column,
show_range);
00436 column = gtk_tree_view_get_column(view,
COL_YES);
00437 gtk_tree_view_column_set_visible(column,
show_range);
00438 column = gtk_tree_view_get_column(view,
COL_VALUE);
00439 gtk_tree_view_column_set_visible(column,
show_value);
00440
00441
if (
resizeable) {
00442
for (i = 0; i <
COL_VALUE; i++) {
00443 column = gtk_tree_view_get_column(view, i);
00444 gtk_tree_view_column_set_resizable(column, TRUE);
00445 }
00446 }
00447
00448 sel = gtk_tree_view_get_selection(view);
00449 gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
00450 }
00451
00452
00453
00454
00455
00456 static void text_insert_help(
struct menu *
menu)
00457 {
00458 GtkTextBuffer *
buffer;
00459 GtkTextIter start, end;
00460
const char *prompt =
menu_get_prompt(menu);
00461 gchar *name;
00462
const char *help =
nohelp_text;
00463
00464
if (!menu->
sym)
00465 help =
"";
00466
else if (menu->
sym->
help)
00467 help = menu->
sym->
help;
00468
00469
if (menu->
sym && menu->
sym->
name)
00470 name = g_strdup_printf(menu->
sym->
name);
00471
else
00472 name = g_strdup(
"");
00473
00474 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(
text_w));
00475 gtk_text_buffer_get_bounds(buffer, &start, &end);
00476 gtk_text_buffer_delete(buffer, &start, &end);
00477 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(
text_w), 15);
00478
00479 gtk_text_buffer_get_end_iter(buffer, &end);
00480 gtk_text_buffer_insert_with_tags(buffer, &end, prompt, -1,
tag1,
00481 NULL);
00482 gtk_text_buffer_insert_at_cursor(buffer,
" ", 1);
00483 gtk_text_buffer_get_end_iter(buffer, &end);
00484 gtk_text_buffer_insert_with_tags(buffer, &end, name, -1,
tag1,
00485 NULL);
00486 gtk_text_buffer_insert_at_cursor(buffer,
"\n\n", 2);
00487 gtk_text_buffer_get_end_iter(buffer, &end);
00488 gtk_text_buffer_insert_with_tags(buffer, &end, help, -1,
tag2,
00489 NULL);
00490 }
00491
00492
00493 static void text_insert_msg(
const char *title,
const char *message)
00494 {
00495 GtkTextBuffer *
buffer;
00496 GtkTextIter start, end;
00497
const char *msg = message;
00498
00499 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(
text_w));
00500 gtk_text_buffer_get_bounds(buffer, &start, &end);
00501 gtk_text_buffer_delete(buffer, &start, &end);
00502 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(
text_w), 15);
00503
00504 gtk_text_buffer_get_end_iter(buffer, &end);
00505 gtk_text_buffer_insert_with_tags(buffer, &end, title, -1,
tag1,
00506 NULL);
00507 gtk_text_buffer_insert_at_cursor(buffer,
"\n\n", 2);
00508 gtk_text_buffer_get_end_iter(buffer, &end);
00509 gtk_text_buffer_insert_with_tags(buffer, &end, msg, -1,
tag2,
00510 NULL);
00511 }
00512
00513
00514
00515
00516
void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data);
00517 gboolean
on_window1_delete_event(GtkWidget * widget, GdkEvent * event,
00518 gpointer user_data)
00519 {
00520 GtkWidget *dialog, *
label;
00521 gint result;
00522
00523
if (
config_changed == FALSE)
00524
return FALSE;
00525
00526 dialog = gtk_dialog_new_with_buttons(
"Warning !",
00527 GTK_WINDOW(
main_wnd),
00528 (GtkDialogFlags)
00529 (GTK_DIALOG_MODAL |
00530 GTK_DIALOG_DESTROY_WITH_PARENT),
00531 GTK_STOCK_OK,
00532 GTK_RESPONSE_YES,
00533 GTK_STOCK_NO,
00534 GTK_RESPONSE_NO,
00535 GTK_STOCK_CANCEL,
00536 GTK_RESPONSE_CANCEL, NULL);
00537 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
00538 GTK_RESPONSE_CANCEL);
00539
00540
label = gtk_label_new(
"\nSave configuration ?\n");
00541 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox),
label);
00542 gtk_widget_show(
label);
00543
00544 result = gtk_dialog_run(GTK_DIALOG(dialog));
00545
switch (result) {
00546
case GTK_RESPONSE_YES:
00547
on_save1_activate(NULL, NULL);
00548
return FALSE;
00549
case GTK_RESPONSE_NO:
00550
return FALSE;
00551
case GTK_RESPONSE_CANCEL:
00552
case GTK_RESPONSE_DELETE_EVENT:
00553
default:
00554 gtk_widget_destroy(dialog);
00555
return TRUE;
00556 }
00557
00558
return FALSE;
00559 }
00560
00561
00562 void on_window1_destroy(GtkObject * object, gpointer user_data)
00563 {
00564 gtk_main_quit();
00565 }
00566
00567
00568
void
00569 on_window1_size_request(GtkWidget * widget,
00570 GtkRequisition * requisition, gpointer user_data)
00571 {
00572
static gint old_h;
00573 gint w, h;
00574
00575
if (widget->window == NULL)
00576 gtk_window_get_default_size(GTK_WINDOW(
main_wnd), &w, &h);
00577
else
00578 gdk_window_get_size(widget->window, &w, &h);
00579
00580
if (h == old_h)
00581
return;
00582 old_h = h;
00583
00584 gtk_paned_set_position(GTK_PANED(
vpaned), 2 * h / 3);
00585 }
00586
00587
00588
00589
00590
00591
static void
00592 load_filename(GtkFileSelection * file_selector, gpointer user_data)
00593 {
00594
const gchar *fn;
00595
00596 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
00597 (user_data));
00598
00599
if (
conf_read(fn))
00600
text_insert_msg(
"Error",
"Unable to load configuration !");
00601
else
00602
display_tree(&
rootmenu);
00603 }
00604
00605 void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data)
00606 {
00607 GtkWidget *fs;
00608
00609 fs = gtk_file_selection_new(
"Load file...");
00610 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
00611
"clicked",
00612 G_CALLBACK(
load_filename), (gpointer) fs);
00613 g_signal_connect_swapped(GTK_OBJECT
00614 (GTK_FILE_SELECTION(fs)->ok_button),
00615
"clicked", G_CALLBACK(gtk_widget_destroy),
00616 (gpointer) fs);
00617 g_signal_connect_swapped(GTK_OBJECT
00618 (GTK_FILE_SELECTION(fs)->cancel_button),
00619
"clicked", G_CALLBACK(gtk_widget_destroy),
00620 (gpointer) fs);
00621 gtk_widget_show(fs);
00622 }
00623
00624
00625 void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data)
00626 {
00627
if (
conf_write(NULL))
00628
text_insert_msg(
"Error",
"Unable to save configuration !");
00629
00630
config_changed = FALSE;
00631 }
00632
00633
00634
static void
00635 store_filename(GtkFileSelection * file_selector, gpointer user_data)
00636 {
00637
const gchar *fn;
00638
00639 fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION
00640 (user_data));
00641
00642
if (
conf_write(fn))
00643
text_insert_msg(
"Error",
"Unable to save configuration !");
00644
00645 gtk_widget_destroy(GTK_WIDGET(user_data));
00646 }
00647
00648 void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data)
00649 {
00650 GtkWidget *fs;
00651
00652 fs = gtk_file_selection_new(
"Save file as...");
00653 g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button),
00654
"clicked",
00655 G_CALLBACK(
store_filename), (gpointer) fs);
00656 g_signal_connect_swapped(GTK_OBJECT
00657 (GTK_FILE_SELECTION(fs)->ok_button),
00658
"clicked", G_CALLBACK(gtk_widget_destroy),
00659 (gpointer) fs);
00660 g_signal_connect_swapped(GTK_OBJECT
00661 (GTK_FILE_SELECTION(fs)->cancel_button),
00662
"clicked", G_CALLBACK(gtk_widget_destroy),
00663 (gpointer) fs);
00664 gtk_widget_show(fs);
00665 }
00666
00667
00668 void on_quit1_activate(GtkMenuItem * menuitem, gpointer user_data)
00669 {
00670
if (!
on_window1_delete_event(NULL, NULL, NULL))
00671 gtk_widget_destroy(GTK_WIDGET(
main_wnd));
00672 }
00673
00674
00675 void on_show_name1_activate(GtkMenuItem * menuitem, gpointer user_data)
00676 {
00677 GtkTreeViewColumn *col;
00678
00679
show_name = GTK_CHECK_MENU_ITEM(menuitem)->active;
00680 col = gtk_tree_view_get_column(GTK_TREE_VIEW(
tree2_w),
COL_NAME);
00681
if (col)
00682 gtk_tree_view_column_set_visible(col,
show_name);
00683 }
00684
00685
00686 void on_show_range1_activate(GtkMenuItem * menuitem, gpointer user_data)
00687 {
00688 GtkTreeViewColumn *col;
00689
00690
show_range = GTK_CHECK_MENU_ITEM(menuitem)->active;
00691 col = gtk_tree_view_get_column(GTK_TREE_VIEW(
tree2_w),
COL_NO);
00692
if (col)
00693 gtk_tree_view_column_set_visible(col,
show_range);
00694 col = gtk_tree_view_get_column(GTK_TREE_VIEW(
tree2_w),
COL_MOD);
00695
if (col)
00696 gtk_tree_view_column_set_visible(col,
show_range);
00697 col = gtk_tree_view_get_column(GTK_TREE_VIEW(
tree2_w),
COL_YES);
00698
if (col)
00699 gtk_tree_view_column_set_visible(col,
show_range);
00700
00701 }
00702
00703
00704 void on_show_data1_activate(GtkMenuItem * menuitem, gpointer user_data)
00705 {
00706 GtkTreeViewColumn *col;
00707
00708
show_value = GTK_CHECK_MENU_ITEM(menuitem)->active;
00709 col = gtk_tree_view_get_column(GTK_TREE_VIEW(
tree2_w),
COL_VALUE);
00710
if (col)
00711 gtk_tree_view_column_set_visible(col,
show_value);
00712 }
00713
00714
00715
void
00716 on_show_all_options1_activate(GtkMenuItem * menuitem, gpointer user_data)
00717 {
00718
show_all = GTK_CHECK_MENU_ITEM(menuitem)->active;
00719
00720 gtk_tree_store_clear(
tree2);
00721
display_tree(&
rootmenu);
00722 }
00723
00724
00725
void
00726 on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data)
00727 {
00728
show_debug = GTK_CHECK_MENU_ITEM(menuitem)->active;
00729
update_tree(&
rootmenu, NULL);
00730 }
00731
00732
00733 void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data)
00734 {
00735 GtkWidget *dialog;
00736
const gchar *intro_text =
00737
"Welcome to gkc, the GTK+ graphical configuration tool\n"
00738
"for RTAI.\n"
00739
"For each option, a blank box indicates the feature is disabled, a\n"
00740
"check indicates it is enabled, and a dot indicates that it is to\n"
00741
"be compiled as a module. Clicking on the box will cycle through the three states.\n"
00742
"\n"
00743
"If you do not see an option (e.g., a feature) that you\n"
00744
"believe should be present, try turning on Show All Options\n"
00745
"under the Options menu.\n"
00746
"Although there is no cross reference yet to help you figure out\n"
00747
"what other options must be enabled to support the option you\n"
00748
"are interested in, you can still view the help of a grayed-out\n"
00749
"option.\n"
00750
"\n"
00751
"Toggling Show Debug Info under the Options menu will show \n"
00752
"the dependencies, which you can then match by examining other options.";
00753
00754 dialog = gtk_message_dialog_new(GTK_WINDOW(
main_wnd),
00755 GTK_DIALOG_DESTROY_WITH_PARENT,
00756 GTK_MESSAGE_INFO,
00757 GTK_BUTTONS_CLOSE, intro_text);
00758 g_signal_connect_swapped(GTK_OBJECT(dialog),
"response",
00759 G_CALLBACK(gtk_widget_destroy),
00760 GTK_OBJECT(dialog));
00761 gtk_widget_show_all(dialog);
00762 }
00763
00764
00765 void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data)
00766 {
00767 GtkWidget *dialog;
00768
const gchar *about_text =
00769
"gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n"
00770
"Based on the source code from Roman Zippel.\n";
00771
00772 dialog = gtk_message_dialog_new(GTK_WINDOW(
main_wnd),
00773 GTK_DIALOG_DESTROY_WITH_PARENT,
00774 GTK_MESSAGE_INFO,
00775 GTK_BUTTONS_CLOSE, about_text);
00776 g_signal_connect_swapped(GTK_OBJECT(dialog),
"response",
00777 G_CALLBACK(gtk_widget_destroy),
00778 GTK_OBJECT(dialog));
00779 gtk_widget_show_all(dialog);
00780 }
00781
00782
00783 void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data)
00784 {
00785 GtkWidget *dialog;
00786
const gchar *license_text =
00787
"gkc is released under the terms of the GNU GPL v2.\n"
00788
"For more information, please see the source code or\n"
00789
"visit http://www.fsf.org/licenses/licenses.html\n";
00790
00791 dialog = gtk_message_dialog_new(GTK_WINDOW(
main_wnd),
00792 GTK_DIALOG_DESTROY_WITH_PARENT,
00793 GTK_MESSAGE_INFO,
00794 GTK_BUTTONS_CLOSE, license_text);
00795 g_signal_connect_swapped(GTK_OBJECT(dialog),
"response",
00796 G_CALLBACK(gtk_widget_destroy),
00797 GTK_OBJECT(dialog));
00798 gtk_widget_show_all(dialog);
00799 }
00800
00801
00802 void on_back_pressed(GtkButton * button, gpointer user_data)
00803 {
00804
enum prop_type ptype;
00805
00806
current =
current->
parent;
00807 ptype =
current->
prompt ?
current->
prompt->
type :
P_UNKNOWN;
00808
if (ptype !=
P_MENU)
00809
current =
current->
parent;
00810
display_tree_part();
00811
00812
if (
current == &
rootmenu)
00813 gtk_widget_set_sensitive(
back_btn, FALSE);
00814 }
00815
00816
00817 void on_load_pressed(GtkButton * button, gpointer user_data)
00818 {
00819
on_load1_activate(NULL, user_data);
00820 }
00821
00822
00823 void on_save_pressed(GtkButton * button, gpointer user_data)
00824 {
00825
on_save1_activate(NULL, user_data);
00826 }
00827
00828
00829 void on_single_clicked(GtkButton * button, gpointer user_data)
00830 {
00831
view_mode =
SINGLE_VIEW;
00832 gtk_paned_set_position(GTK_PANED(
hpaned), 0);
00833 gtk_widget_hide(
tree1_w);
00834
current = &
rootmenu;
00835
display_tree_part();
00836 }
00837
00838
00839 void on_split_clicked(GtkButton * button, gpointer user_data)
00840 {
00841 gint w, h;
00842
view_mode =
SPLIT_VIEW;
00843 gtk_widget_show(
tree1_w);
00844 gtk_window_get_default_size(GTK_WINDOW(
main_wnd), &w, &h);
00845 gtk_paned_set_position(GTK_PANED(
hpaned), w / 2);
00846
if (
tree2)
00847 gtk_tree_store_clear(
tree2);
00848
display_list();
00849 }
00850
00851
00852 void on_full_clicked(GtkButton * button, gpointer user_data)
00853 {
00854
view_mode =
FULL_VIEW;
00855 gtk_paned_set_position(GTK_PANED(
hpaned), 0);
00856 gtk_widget_hide(
tree1_w);
00857
if (
tree2)
00858 gtk_tree_store_clear(
tree2);
00859
display_tree(&
rootmenu);
00860 gtk_widget_set_sensitive(
back_btn, FALSE);
00861 }
00862
00863
00864 void on_collapse_pressed(GtkButton * button, gpointer user_data)
00865 {
00866 gtk_tree_view_collapse_all(GTK_TREE_VIEW(
tree2_w));
00867 }
00868
00869
00870 void on_expand_pressed(GtkButton * button, gpointer user_data)
00871 {
00872 gtk_tree_view_expand_all(GTK_TREE_VIEW(
tree2_w));
00873 }
00874
00875
00876
00877
00878
00879 static void renderer_edited(GtkCellRendererText * cell,
00880
const gchar * path_string,
00881
const gchar * new_text, gpointer user_data)
00882 {
00883 GtkTreePath *path = gtk_tree_path_new_from_string(path_string);
00884 GtkTreeIter iter;
00885
const char *old_def, *new_def;
00886
struct menu *
menu;
00887
struct symbol *sym;
00888
00889
if (!gtk_tree_model_get_iter(
model2, &iter, path))
00890
return;
00891
00892 gtk_tree_model_get(
model2, &iter,
COL_MENU, &
menu, -1);
00893 sym =
menu->sym;
00894
00895 gtk_tree_model_get(
model2, &iter,
COL_VALUE, &old_def, -1);
00896 new_def = new_text;
00897
00898
sym_set_string_value(sym, new_def);
00899
00900
config_changed = TRUE;
00901
update_tree(&
rootmenu, NULL);
00902
00903 gtk_tree_path_free(path);
00904 }
00905
00906
00907 static void change_sym_value(
struct menu *
menu, gint col)
00908 {
00909
struct symbol *sym = menu->
sym;
00910
tristate oldval, newval;
00911
00912
if (!sym)
00913
return;
00914
00915
if (col ==
COL_NO)
00916 newval =
no;
00917
else if (col ==
COL_MOD)
00918 newval =
mod;
00919
else if (col ==
COL_YES)
00920 newval =
yes;
00921
else
00922
return;
00923
00924
switch (
sym_get_type(sym)) {
00925
case S_BOOLEAN:
00926
case S_TRISTATE:
00927 oldval =
sym_get_tristate_value(sym);
00928
if (!
sym_tristate_within_range(sym, newval))
00929 newval =
yes;
00930
sym_set_tristate_value(sym, newval);
00931
config_changed = TRUE;
00932
if (
view_mode ==
FULL_VIEW)
00933
update_tree(&
rootmenu, NULL);
00934
else if (
view_mode ==
SPLIT_VIEW) {
00935
update_tree(
browsed, NULL);
00936
display_list();
00937 }
00938
else if (
view_mode ==
SINGLE_VIEW)
00939
display_tree_part();
00940
break;
00941
case S_INT:
00942
case S_HEX:
00943
case S_STRING:
00944
default:
00945
break;
00946 }
00947 }
00948
00949 static void toggle_sym_value(
struct menu *
menu)
00950 {
00951
const tristate next_val[3] = {
no,
mod,
yes };
00952
tristate newval;
00953
00954
if (!menu->
sym)
00955
return;
00956
00957 newval = next_val[(
sym_get_tristate_value(menu->
sym) + 1) % 3];
00958
if (!
sym_tristate_within_range(menu->
sym, newval))
00959 newval =
yes;
00960
sym_set_tristate_value(menu->
sym, newval);
00961
if (
view_mode ==
FULL_VIEW)
00962
update_tree(&
rootmenu, NULL);
00963
else if (
view_mode ==
SPLIT_VIEW) {
00964
update_tree(
browsed, NULL);
00965
display_list();
00966 }
00967
else if (
view_mode ==
SINGLE_VIEW)
00968
display_tree_part();
00969 }
00970
00971 static void renderer_toggled(GtkCellRendererToggle * cell,
00972 gchar * path_string, gpointer user_data)
00973 {
00974 GtkTreePath *path, *sel_path = NULL;
00975 GtkTreeIter iter, sel_iter;
00976 GtkTreeSelection *sel;
00977
struct menu *
menu;
00978
00979 path = gtk_tree_path_new_from_string(path_string);
00980
if (!gtk_tree_model_get_iter(
model2, &iter, path))
00981
return;
00982
00983 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(
tree2_w));
00984
if (gtk_tree_selection_get_selected(sel, NULL, &sel_iter))
00985 sel_path = gtk_tree_model_get_path(
model2, &sel_iter);
00986
if (!sel_path)
00987
goto out1;
00988
if (gtk_tree_path_compare(path, sel_path))
00989
goto out2;
00990
00991 gtk_tree_model_get(
model2, &iter,
COL_MENU, &
menu, -1);
00992
toggle_sym_value(
menu);
00993
00994 out2:
00995 gtk_tree_path_free(sel_path);
00996 out1:
00997 gtk_tree_path_free(path);
00998 }
00999
01000 static gint
column2index(GtkTreeViewColumn * column)
01001 {
01002 gint i;
01003
01004
for (i = 0; i <
COL_NUMBER; i++) {
01005 GtkTreeViewColumn *col;
01006
01007 col = gtk_tree_view_get_column(GTK_TREE_VIEW(
tree2_w), i);
01008
if (col == column)
01009
return i;
01010 }
01011
01012
return -1;
01013 }
01014
01015
01016
01017 gboolean
01018 on_treeview2_button_press_event(GtkWidget * widget,
01019 GdkEventButton * event, gpointer user_data)
01020 {
01021 GtkTreeView *view = GTK_TREE_VIEW(widget);
01022 GtkTreePath *path;
01023 GtkTreeViewColumn *column;
01024 GtkTreeIter iter;
01025
struct menu *
menu;
01026 gint col;
01027
01028
#if GTK_CHECK_VERSION(2,1,4) // bug in ctree with earlier version of GTK
01029
gint tx = (gint) event->x;
01030 gint ty = (gint) event->y;
01031 gint cx, cy;
01032
01033 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
01034 &cy);
01035
#else
01036
gtk_tree_view_get_cursor(view, &path, &column);
01037
#endif
01038
if (path == NULL)
01039
return FALSE;
01040
01041 gtk_tree_model_get_iter(
model2, &iter, path);
01042 gtk_tree_model_get(
model2, &iter,
COL_MENU, &
menu, -1);
01043
01044 col =
column2index(column);
01045
if (event->type == GDK_2BUTTON_PRESS) {
01046
enum prop_type ptype;
01047 ptype =
menu->prompt ?
menu->prompt->type :
P_UNKNOWN;
01048
01049
if (ptype ==
P_MENU &&
view_mode !=
FULL_VIEW && col ==
COL_OPTION) {
01050
01051
current =
menu;
01052
display_tree_part();
01053 gtk_widget_set_sensitive(
back_btn, TRUE);
01054 }
else if ((col ==
COL_OPTION)) {
01055
toggle_sym_value(
menu);
01056 gtk_tree_view_expand_row(view, path, TRUE);
01057 }
01058 }
else {
01059
if (col ==
COL_VALUE) {
01060
toggle_sym_value(
menu);
01061 gtk_tree_view_expand_row(view, path, TRUE);
01062 }
else if (col ==
COL_NO || col ==
COL_MOD
01063 || col ==
COL_YES) {
01064
change_sym_value(
menu, col);
01065 gtk_tree_view_expand_row(view, path, TRUE);
01066 }
01067 }
01068
01069
return FALSE;
01070 }
01071
01072
01073 gboolean
01074 on_treeview2_key_press_event(GtkWidget * widget,
01075 GdkEventKey * event, gpointer user_data)
01076 {
01077 GtkTreeView *view = GTK_TREE_VIEW(widget);
01078 GtkTreePath *path;
01079 GtkTreeViewColumn *column;
01080 GtkTreeIter iter;
01081
struct menu *
menu;
01082 gint col;
01083
01084 gtk_tree_view_get_cursor(view, &path, &column);
01085
if (path == NULL)
01086
return FALSE;
01087
01088
if (event->keyval == GDK_space) {
01089
if (gtk_tree_view_row_expanded(view, path))
01090 gtk_tree_view_collapse_row(view, path);
01091
else
01092 gtk_tree_view_expand_row(view, path, FALSE);
01093
return TRUE;
01094 }
01095
if (event->keyval == GDK_KP_Enter) {
01096 }
01097
if (widget ==
tree1_w)
01098
return FALSE;
01099
01100 gtk_tree_model_get_iter(
model2, &iter, path);
01101 gtk_tree_model_get(
model2, &iter,
COL_MENU, &
menu, -1);
01102
01103
if (!strcasecmp(event->string,
"n"))
01104 col =
COL_NO;
01105
else if (!strcasecmp(event->string,
"m"))
01106 col =
COL_MOD;
01107
else if (!strcasecmp(event->string,
"y"))
01108 col =
COL_YES;
01109
else
01110 col = -1;
01111
change_sym_value(
menu, col);
01112
01113
return FALSE;
01114 }
01115
01116
01117
01118
void
01119 on_treeview2_cursor_changed(GtkTreeView * treeview, gpointer user_data)
01120 {
01121 GtkTreeSelection *selection;
01122 GtkTreeIter iter;
01123
struct menu *
menu;
01124
01125 selection = gtk_tree_view_get_selection(treeview);
01126
if (gtk_tree_selection_get_selected(selection, &
model2, &iter)) {
01127 gtk_tree_model_get(
model2, &iter,
COL_MENU, &
menu, -1);
01128
text_insert_help(
menu);
01129 }
01130 }
01131
01132
01133
01134 gboolean
01135 on_treeview1_button_press_event(GtkWidget * widget,
01136 GdkEventButton * event, gpointer user_data)
01137 {
01138 GtkTreeView *view = GTK_TREE_VIEW(widget);
01139 GtkTreePath *path;
01140 GtkTreeViewColumn *column;
01141 GtkTreeIter iter;
01142
struct menu *
menu;
01143
01144 gint tx = (gint) event->x;
01145 gint ty = (gint) event->y;
01146 gint cx, cy;
01147
01148 gtk_tree_view_get_path_at_pos(view, tx, ty, &path, &column, &cx,
01149 &cy);
01150
if (path == NULL)
01151
return FALSE;
01152
01153 gtk_tree_model_get_iter(
model1, &iter, path);
01154 gtk_tree_model_get(
model1, &iter,
COL_MENU, &
menu, -1);
01155
01156
if (event->type == GDK_2BUTTON_PRESS) {
01157
toggle_sym_value(
menu);
01158
current =
menu;
01159
display_tree_part();
01160 }
else {
01161
browsed =
menu;
01162
display_tree_part();
01163 }
01164
01165 gtk_widget_realize(
tree2_w);
01166 gtk_tree_view_set_cursor(view, path, NULL, FALSE);
01167 gtk_widget_grab_focus(GTK_TREE_VIEW(
tree2_w));
01168
01169
return FALSE;
01170 }
01171
01172
01173
01174
01175
01176
01177 static gchar **
fill_row(
struct menu *
menu)
01178 {
01179
static gchar *row[
COL_NUMBER];
01180
struct symbol *sym = menu->
sym;
01181
const char *def;
01182
int stype;
01183
tristate val;
01184
enum prop_type ptype;
01185
int i;
01186
01187
for (i =
COL_OPTION; i <=
COL_COLOR; i++)
01188 g_free(row[i]);
01189 bzero(row,
sizeof(row));
01190
01191 row[
COL_OPTION] =
01192 g_strdup_printf(
"%s %s",
menu_get_prompt(menu),
01193 sym ? (sym->
01194
flags &
SYMBOL_NEW ?
"(NEW)" :
"") :
01195
"");
01196
01197
if (
show_all && !
menu_is_visible(menu))
01198 row[
COL_COLOR] = g_strdup(
"DarkGray");
01199
else
01200 row[
COL_COLOR] = g_strdup(
"Black");
01201
01202 ptype = menu->
prompt ? menu->
prompt->
type :
P_UNKNOWN;
01203
switch (ptype) {
01204
case P_MENU:
01205 row[
COL_PIXBUF] = (gchar *) xpm_menu;
01206
if (
view_mode ==
SINGLE_VIEW)
01207 row[
COL_PIXVIS] = GINT_TO_POINTER(TRUE);
01208 row[
COL_BTNVIS] = GINT_TO_POINTER(FALSE);
01209
break;
01210
case P_COMMENT:
01211 row[
COL_PIXBUF] = (gchar *) xpm_void;
01212 row[
COL_PIXVIS] = GINT_TO_POINTER(FALSE);
01213 row[
COL_BTNVIS] = GINT_TO_POINTER(FALSE);
01214
break;
01215
default:
01216 row[
COL_PIXBUF] = (gchar *) xpm_void;
01217 row[
COL_PIXVIS] = GINT_TO_POINTER(FALSE);
01218 row[
COL_BTNVIS] = GINT_TO_POINTER(TRUE);
01219
break;
01220 }
01221
01222
if (!sym)
01223
return row;
01224 row[
COL_NAME] = g_strdup(sym->name);
01225
01226
sym_calc_value(sym);
01227 sym->flags &= ~
SYMBOL_CHANGED;
01228
01229
if (
sym_is_choice(sym)) {
01230
struct menu *child;
01231
struct symbol *def_sym =
sym_get_choice_value(sym);
01232
struct menu *def_menu = NULL;
01233
01234 row[
COL_BTNVIS] = GINT_TO_POINTER(FALSE);
01235
01236
for (child = menu->
list; child; child = child->
next) {
01237
if (
menu_is_visible(child)
01238 && child->sym == def_sym)
01239 def_menu = child;
01240 }
01241
01242
if (def_menu)
01243 row[
COL_VALUE] =
01244 g_strdup(
menu_get_prompt(def_menu));
01245 }
01246
if(sym->flags &
SYMBOL_CHOICEVAL)
01247 row[
COL_BTNRAD] = GINT_TO_POINTER(TRUE);
01248
01249 stype =
sym_get_type(sym);
01250
switch (stype) {
01251
case S_BOOLEAN:
01252
if(GPOINTER_TO_INT(row[
COL_PIXVIS]) == FALSE)
01253 row[
COL_BTNVIS] = GINT_TO_POINTER(TRUE);
01254
if (
sym_is_choice(sym))
01255
break;
01256
case S_TRISTATE:
01257 val =
sym_get_tristate_value(sym);
01258
switch (val) {
01259
case no:
01260 row[
COL_NO] = g_strdup(
"N");
01261 row[
COL_VALUE] = g_strdup(
"N");
01262 row[
COL_BTNACT] = GINT_TO_POINTER(FALSE);
01263 row[
COL_BTNINC] = GINT_TO_POINTER(FALSE);
01264
break;
01265
case mod:
01266 row[
COL_MOD] = g_strdup(
"M");
01267 row[
COL_VALUE] = g_strdup(
"M");
01268 row[
COL_BTNINC] = GINT_TO_POINTER(TRUE);
01269
break;
01270
case yes:
01271 row[
COL_YES] = g_strdup(
"Y");
01272 row[
COL_VALUE] = g_strdup(
"Y");
01273 row[
COL_BTNACT] = GINT_TO_POINTER(TRUE);
01274 row[
COL_BTNINC] = GINT_TO_POINTER(FALSE);
01275
break;
01276 }
01277
01278
if (val !=
no &&
sym_tristate_within_range(sym,
no))
01279 row[
COL_NO] = g_strdup(
"_");
01280
if (val !=
mod &&
sym_tristate_within_range(sym,
mod))
01281 row[
COL_MOD] = g_strdup(
"_");
01282
if (val !=
yes &&
sym_tristate_within_range(sym,
yes))
01283 row[
COL_YES] = g_strdup(
"_");
01284
break;
01285
case S_INT:
01286
case S_HEX:
01287
case S_STRING:
01288 def =
sym_get_string_value(sym);
01289 row[
COL_VALUE] = g_strdup(def);
01290 row[
COL_EDIT] = GINT_TO_POINTER(TRUE);
01291 row[
COL_BTNVIS] = GINT_TO_POINTER(FALSE);
01292
break;
01293 }
01294
01295
return row;
01296 }
01297
01298
01299
01300 static void set_node(GtkTreeIter * node,
struct menu *
menu, gchar ** row)
01301 {
01302 GdkColor
color;
01303 gboolean success;
01304 GdkPixbuf *pix;
01305
01306 pix = gdk_pixbuf_new_from_xpm_data((
const char **)
01307 row[
COL_PIXBUF]);
01308
01309 gdk_color_parse(row[
COL_COLOR], &
color);
01310 gdk_colormap_alloc_colors(gdk_colormap_get_system(), &
color, 1,
01311 FALSE, FALSE, &success);
01312
01313 gtk_tree_store_set(
tree, node,
01314
COL_OPTION, row[
COL_OPTION],
01315
COL_NAME, row[
COL_NAME],
01316
COL_NO, row[
COL_NO],
01317
COL_MOD, row[
COL_MOD],
01318
COL_YES, row[
COL_YES],
01319
COL_VALUE, row[
COL_VALUE],
01320
COL_MENU, (gpointer) menu,
01321
COL_COLOR, &
color,
01322
COL_EDIT, GPOINTER_TO_INT(row[
COL_EDIT]),
01323
COL_PIXBUF, pix,
01324
COL_PIXVIS, GPOINTER_TO_INT(row[
COL_PIXVIS]),
01325
COL_BTNVIS, GPOINTER_TO_INT(row[
COL_BTNVIS]),
01326
COL_BTNACT, GPOINTER_TO_INT(row[
COL_BTNACT]),
01327
COL_BTNINC, GPOINTER_TO_INT(row[
COL_BTNINC]),
01328
COL_BTNRAD, GPOINTER_TO_INT(row[
COL_BTNRAD]),
01329 -1);
01330
01331 g_object_unref(pix);
01332 }
01333
01334
01335
01336 static void place_node(
struct menu *
menu,
char **row)
01337 {
01338 GtkTreeIter *parent =
parents[
indent - 1];
01339 GtkTreeIter *node =
parents[
indent];
01340
01341 gtk_tree_store_append(
tree, node, parent);
01342
set_node(node, menu, row);
01343 }
01344
01345
01346
01347 static GtkTreeIter
found;
01348
01349
01350
01351
01352 GtkTreeIter *
gtktree_iter_find_node(GtkTreeIter * parent,
01353
struct menu *tofind)
01354 {
01355 GtkTreeIter iter;
01356 GtkTreeIter *child = &iter;
01357 gboolean valid;
01358 GtkTreeIter *ret;
01359
01360 valid = gtk_tree_model_iter_children(
model2, child, parent);
01361
while (valid) {
01362
struct menu *
menu;
01363
01364 gtk_tree_model_get(
model2, child, 6, &
menu, -1);
01365
01366
if (
menu == tofind) {
01367 memcpy(&
found, child,
sizeof(GtkTreeIter));
01368
return &
found;
01369 }
01370
01371 ret =
gtktree_iter_find_node(child, tofind);
01372
if (ret)
01373
return ret;
01374
01375 valid = gtk_tree_model_iter_next(
model2, child);
01376 }
01377
01378
return NULL;
01379 }
01380
01381
01382
01383
01384
01385
01386 static void update_tree(
struct menu *src, GtkTreeIter * dst)
01387 {
01388
struct menu *child1;
01389 GtkTreeIter iter, tmp;
01390 GtkTreeIter *child2 = &iter;
01391 gboolean valid;
01392 GtkTreeIter *sibling;
01393
struct symbol *sym;
01394
struct property *prop;
01395
struct menu *menu1, *menu2;
01396
static GtkTreePath *path = NULL;
01397
01398
if (src == &
rootmenu)
01399
indent = 1;
01400
01401 valid = gtk_tree_model_iter_children(
model2, child2, dst);
01402
for (child1 = src->
list; child1; child1 = child1->
next) {
01403
01404 prop = child1->prompt;
01405 sym = child1->sym;
01406
01407 reparse:
01408 menu1 = child1;
01409
if (valid)
01410 gtk_tree_model_get(
model2, child2,
COL_MENU,
01411 &menu2, -1);
01412
else
01413 menu2 = NULL;
01414
01415
#ifdef DEBUG
01416
printf(
"%*c%s | %s\n",
indent,
' ',
01417 menu1 ?
menu_get_prompt(menu1) :
"nil",
01418 menu2 ?
menu_get_prompt(menu2) :
"nil");
01419
#endif
01420
01421
if (!
menu_is_visible(child1) && !
show_all) {
01422
if (
gtktree_iter_find_node(dst, menu1) != NULL) {
01423 memcpy(&tmp, child2,
sizeof(GtkTreeIter));
01424 valid = gtk_tree_model_iter_next(
model2,
01425 child2);
01426 gtk_tree_store_remove(
tree2, &tmp);
01427
if (!valid)
01428
return;
01429
else
01430
goto reparse;
01431 }
else
01432
continue;
01433 }
01434
01435
if (menu1 != menu2) {
01436
if (
gtktree_iter_find_node(dst, menu1) == NULL) {
01437
if (!valid && !menu2)
01438 sibling = NULL;
01439
else
01440 sibling = child2;
01441 gtk_tree_store_insert_before(
tree2,
01442 child2,
01443 dst, sibling);
01444
set_node(child2, menu1,
fill_row(menu1));
01445
if (menu2 == NULL)
01446 valid = TRUE;
01447 }
else {
01448 memcpy(&tmp, child2,
sizeof(GtkTreeIter));
01449 valid = gtk_tree_model_iter_next(
model2,
01450 child2);
01451 gtk_tree_store_remove(
tree2, &tmp);
01452
if (!valid)
01453
return;
01454
else
01455
goto reparse;
01456 }
01457 }
else if (sym && (sym->flags &
SYMBOL_CHANGED)) {
01458
set_node(child2, menu1,
fill_row(menu1));
01459 }
01460
01461
indent++;
01462
update_tree(child1, child2);
01463
indent--;
01464
01465 valid = gtk_tree_model_iter_next(
model2, child2);
01466 }
01467 }
01468
01469
01470
01471 static void display_tree(
struct menu *
menu)
01472 {
01473
struct symbol *sym;
01474
struct property *prop;
01475
struct menu *child;
01476
enum prop_type ptype;
01477
01478
if (menu == &
rootmenu) {
01479
indent = 1;
01480
current = &
rootmenu;
01481 }
01482
01483
for (child = menu->
list; child; child = child->
next) {
01484 prop = child->
prompt;
01485 sym = child->
sym;
01486 ptype = prop ? prop->
type :
P_UNKNOWN;
01487
01488
if (sym)
01489 sym->flags &= ~
SYMBOL_CHANGED;
01490
01491
if ((
view_mode ==
SPLIT_VIEW) && !(child->flags &
MENU_ROOT) &&
01492 (
tree ==
tree1))
01493
continue;
01494
01495
if ((
view_mode ==
SPLIT_VIEW) && (child->flags &
MENU_ROOT) &&
01496 (
tree ==
tree2))
01497
continue;
01498
01499
if (
menu_is_visible(child) ||
show_all)
01500
place_node(child,
fill_row(child));
01501
#ifdef DEBUG
01502
printf(
"%*c%s: ",
indent,
' ',
menu_get_prompt(child));
01503 printf(
"%s", child->flags &
MENU_ROOT ?
"rootmenu | " :
"");
01504
dbg_print_ptype(ptype);
01505 printf(
" | ");
01506
if (sym) {
01507
dbg_print_stype(sym->type);
01508 printf(
" | ");
01509
dbg_print_flags(sym->flags);
01510 printf(
"\n");
01511 }
else
01512 printf(
"\n");
01513
#endif
01514
if ((
view_mode !=
FULL_VIEW) && (ptype ==
P_MENU)
01515 && (
tree ==
tree2))
01516
continue;
01517
01518
01519
01520
01521
if ((
view_mode ==
SINGLE_VIEW) && (menu->
flags &
MENU_ROOT)
01522 || (
view_mode ==
FULL_VIEW) || (
view_mode ==
SPLIT_VIEW)) {
01523
indent++;
01524
display_tree(child);
01525
indent--;
01526 }
01527 }
01528 }
01529
01530
01531 static void display_tree_part(
void)
01532 {
01533
if (
tree2)
01534 gtk_tree_store_clear(
tree2);
01535
if(
view_mode ==
SINGLE_VIEW)
01536
display_tree(
current);
01537
else if(
view_mode ==
SPLIT_VIEW)
01538
display_tree(
browsed);
01539 gtk_tree_view_expand_all(GTK_TREE_VIEW(
tree2_w));
01540 }
01541
01542
01543 static void display_list(
void)
01544 {
01545
if (
tree1)
01546 gtk_tree_store_clear(
tree1);
01547
01548
tree =
tree1;
01549
display_tree(&
rootmenu);
01550 gtk_tree_view_expand_all(GTK_TREE_VIEW(
tree1_w));
01551
tree =
tree2;
01552 }
01553
01554 void fixup_rootmenu(
struct menu *
menu)
01555 {
01556
struct menu *child;
01557
static int menu_cnt = 0;
01558
01559 menu->
flags |=
MENU_ROOT;
01560
for (child = menu->
list; child; child = child->
next) {
01561
if (child->prompt && child->prompt->type ==
P_MENU) {
01562 menu_cnt++;
01563
fixup_rootmenu(child);
01564 menu_cnt--;
01565 }
else if (!menu_cnt)
01566
fixup_rootmenu(child);
01567 }
01568 }
01569
01570
01571
01572
01573
01574 int main(
int ac,
char *av[])
01575 {
01576
const char *name, *srctree;
01577 gchar *cur_dir, *exe_path;
01578 gchar *glade_file;
01579
struct symbol *sym;
01580
char title[256];
01581
01582
#ifndef LKC_DIRECT_LINK
01583
kconfig_load();
01584
#endif
01585
01586
01587 gtk_set_locale();
01588 gtk_init(&ac, &av);
01589 glade_init();
01590
01591
01592
01593
01594
01595
01596 srctree = getenv(
SRCTREE);
01597 glade_file = g_strconcat(srctree ?:
".",
"/base/config/kconfig/",av[0],
".glade", NULL);
01598
01599
01600
init_main_window(glade_file);
01601 gtk_widget_show(
main_wnd);
01602
init_tree_model();
01603
init_left_tree();
01604
init_right_tree();
01605
01606
01607
if (ac > 1 && av[1][0] ==
'-') {
01608
switch (av[1][1]) {
01609
case 'a':
01610
01611
break;
01612
case 'h':
01613
case '?':
01614 printf(
"%s <config>\n", av[0]);
01615 exit(0);
01616 }
01617 name = av[2];
01618 }
else
01619 name = av[1];
01620
01621
conf_parse(name);
01622
fixup_rootmenu(&
rootmenu);
01623
conf_read(NULL);
01624
01625
switch (
view_mode) {
01626
case SINGLE_VIEW:
01627
display_tree_part();
01628
break;
01629
case SPLIT_VIEW:
01630
display_list();
01631
break;
01632
case FULL_VIEW:
01633
display_tree(&
rootmenu);
01634
break;
01635 }
01636
01637 sym =
sym_lookup(
"RTAI_VERSION",0);
01638
sym_calc_value(sym);
01639 sprintf(title,
"RTAI Configuration [ %s ]",
sym_get_string_value(sym));
01640 gtk_window_set_title(GTK_WINDOW(
main_wnd), title);
01641
01642 gtk_main();
01643
01644
return 0;
01645 }