diff --git a/src/gnome/dialog-options.c b/src/gnome/dialog-options.c index 3942360cb6..7c4c60c228 100644 --- a/src/gnome/dialog-options.c +++ b/src/gnome/dialog-options.c @@ -122,6 +122,39 @@ gnc_option_set_ui_value(GNCOption *option, gboolean use_default) g_list_free(list); } + else if (safe_strcmp(type, "list") == 0) + { + gint num_rows, row; + + gtk_clist_unselect_all(GTK_CLIST(option->widget)); + + num_rows = gnc_option_num_permissible_values(option); + for (row = 0; row < num_rows; row++) + gtk_clist_set_row_data(GTK_CLIST(option->widget), + row, GINT_TO_POINTER(FALSE)); + + while (gh_list_p(value) && !gh_null_p(value)) + { + SCM item; + + item = gh_car(value); + value = gh_cdr(value); + + row = gnc_option_permissible_value_index(option, item); + if (index < 0) + { + bad_value = TRUE; + break; + } + + gtk_clist_select_row(GTK_CLIST(option->widget), row, 0); + gtk_clist_set_row_data(GTK_CLIST(option->widget), + row, GINT_TO_POINTER(TRUE)); + } + + if (!gh_list_p(value) || !gh_null_p(value)) + bad_value = TRUE; + } else if (safe_strcmp(type, "number-range") == 0) { GtkSpinButton *spinner; @@ -233,6 +266,24 @@ gnc_option_get_ui_value(GNCOption *option) g_list_free(list); } + else if (safe_strcmp(type, "list") == 0) + { + gboolean selected; + GtkCList *clist; + gint num_rows; + gint row; + + clist = GTK_CLIST(option->widget); + num_rows = gnc_option_num_permissible_values(option); + result = gh_eval_str("()"); + + for (row = 0; row < num_rows; row++) + { + selected = GPOINTER_TO_INT(gtk_clist_get_row_data(clist, row)); + if (selected) + result = gh_cons(gnc_option_permissible_value(option, row), result); + } + } else if (safe_strcmp(type, "number-range") == 0) { GtkSpinButton *spinner; @@ -494,6 +545,151 @@ gnc_option_create_account_widget(GNCOption *option, char *name) return frame; } +static void +gnc_option_list_select_cb(GtkCList *clist, gint row, gint column, + GdkEventButton *event, gpointer data) +{ + GNCOption *option = data; + GtkWidget *pbox; + + option->changed = TRUE; + + gtk_clist_set_row_data(clist, row, GINT_TO_POINTER(TRUE)); + + pbox = gtk_widget_get_toplevel(GTK_WIDGET(clist)); + gnome_property_box_changed(GNOME_PROPERTY_BOX(pbox)); +} + +static void +gnc_option_list_unselect_cb(GtkCList *clist, gint row, gint column, + GdkEventButton *event, gpointer data) +{ + GNCOption *option = data; + GtkWidget *pbox; + + option->changed = TRUE; + + gtk_clist_set_row_data(clist, row, GINT_TO_POINTER(FALSE)); + + pbox = gtk_widget_get_toplevel(GTK_WIDGET(clist)); + gnome_property_box_changed(GNOME_PROPERTY_BOX(pbox)); +} + +static void +gnc_option_list_select_all_cb(GtkWidget *widget, gpointer data) +{ + GNCOption *option = data; + GtkWidget *pbox; + + gtk_clist_select_all(GTK_CLIST(option->widget)); + + option->changed = TRUE; + + pbox = gtk_widget_get_toplevel(GTK_WIDGET(widget)); + gnome_property_box_changed(GNOME_PROPERTY_BOX(pbox)); +} + +static void +gnc_option_list_clear_all_cb(GtkWidget *widget, gpointer data) +{ + GNCOption *option = data; + GtkWidget *pbox; + + gtk_clist_unselect_all(GTK_CLIST(option->widget)); + + option->changed = TRUE; + + pbox = gtk_widget_get_toplevel(GTK_WIDGET(widget)); + gnome_property_box_changed(GNOME_PROPERTY_BOX(pbox)); +} + +static GtkWidget * +gnc_option_create_list_widget(GNCOption *option, char *name) +{ + GtkWidget *scroll_win; + GtkWidget *top_hbox; + GtkWidget *button; + GtkWidget *frame; + GtkWidget *clist; + GtkWidget *hbox; + GtkWidget *bbox; + gint num_values; + gint width; + gint i; + + top_hbox = gtk_hbox_new(FALSE, 0); + + frame = gtk_frame_new(name); + gtk_box_pack_start(GTK_BOX(top_hbox), frame, FALSE, FALSE, 0); + + hbox = gtk_hbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(frame), hbox); + + clist = gtk_clist_new(1); + gtk_clist_column_titles_hide(GTK_CLIST(clist)); + gtk_clist_set_selection_mode(GTK_CLIST(clist), GTK_SELECTION_MULTIPLE); + + num_values = gnc_option_num_permissible_values(option); + for (i = 0; i < num_values; i++) + { + gchar *text[1]; + gchar *string; + + string = gnc_option_permissible_value_name(option, i); + if (string != NULL) + { + text[0] = _(string); + gtk_clist_append(GTK_CLIST(clist), text); + gtk_clist_set_row_data(GTK_CLIST(clist), i, GINT_TO_POINTER(FALSE)); + free(string); + } + else + { + PERR("gnc_option_create_list_widget: bad value name\n"); + } + } + + scroll_win = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + + width = gtk_clist_columns_autosize(GTK_CLIST(clist)); + gtk_widget_set_usize(scroll_win, width + 50, 0); + + gtk_box_pack_start(GTK_BOX(hbox), scroll_win, FALSE, FALSE, 0); + gtk_container_border_width(GTK_CONTAINER(scroll_win), 5); + gtk_container_add(GTK_CONTAINER(scroll_win), clist); + + bbox = gtk_vbutton_box_new(); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_SPREAD); + gtk_box_pack_start(GTK_BOX(hbox), bbox, FALSE, FALSE, 10); + + button = gtk_button_new_with_label(SELECT_ALL_STR); + gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + + gtk_signal_connect(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(gnc_option_list_select_all_cb), + option); + + button = gtk_button_new_with_label(CLEAR_ALL_STR); + gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + + gtk_signal_connect(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(gnc_option_list_clear_all_cb), + option); + + button = gtk_button_new_with_label(SELECT_DEFAULT_STR); + gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + + gtk_signal_connect(GTK_OBJECT(button), "clicked", + GTK_SIGNAL_FUNC(default_button_cb), option); + + option->widget = clist; + + return top_hbox; +} + static void gnc_option_color_changed_cb(GnomeColorPicker *picker, guint arg1, guint arg2, guint arg3, guint arg4, gpointer data) @@ -652,6 +848,33 @@ gnc_option_set_ui_widget(GNCOption *option, gtk_clist_set_row_height(GTK_CLIST(value), 0); gtk_widget_set_usize(value, 0, GTK_CLIST(value)->row_height * 10); } + else if (safe_strcmp(type, "list") == 0) + { + gint num_lines; + + enclosing = gnc_option_create_list_widget(option, name); + value = option->widget; + + gtk_tooltips_set_tip(tooltips, enclosing, documentation, NULL); + + gtk_box_pack_start(page_box, enclosing, FALSE, FALSE, 5); + packed = TRUE; + + gtk_widget_realize(value); + + gnc_option_set_ui_value(option, FALSE); + + gtk_signal_connect(GTK_OBJECT(value), "select_row", + GTK_SIGNAL_FUNC(gnc_option_list_select_cb), option); + gtk_signal_connect(GTK_OBJECT(value), "unselect_row", + GTK_SIGNAL_FUNC(gnc_option_list_unselect_cb), option); + + num_lines = gnc_option_num_permissible_values(option); + num_lines = MIN(num_lines, 9) + 1; + + gtk_clist_set_row_height(GTK_CLIST(value), 0); + gtk_widget_set_usize(value, 0, GTK_CLIST(value)->row_height * num_lines); + } else if (safe_strcmp(type, "number-range") == 0) { GtkWidget *label; diff --git a/src/gnome/global-options.c b/src/gnome/global-options.c index 61a90ade47..43bb7566e4 100644 --- a/src/gnome/global-options.c +++ b/src/gnome/global-options.c @@ -266,6 +266,25 @@ gnc_lookup_color_option_argb(const char *section, const char *name, } +/********************************************************************\ + * gnc_lookup_list_option * + * looks up a list option. If present, returns its value as a * + * list of strings representing the symbols. * + * * + * Args: section - section name of option * + * name - name of option * + * default_value - default value to return if problem * + * Return: list of values * +\********************************************************************/ +GSList * +gnc_lookup_list_option(const char *section, const char *name, + GSList *default_value) +{ + return gnc_option_db_lookup_list_option(global_options, section, name, + default_value); +} + + /********************************************************************\ * gnc_set_option_default * * set the option to its default value * diff --git a/src/gnome/global-options.h b/src/gnome/global-options.h index 14803d2df0..d83fe2f5bd 100644 --- a/src/gnome/global-options.h +++ b/src/gnome/global-options.h @@ -61,6 +61,9 @@ gboolean gnc_lookup_color_option(const char *section, const char *name, uint32 gnc_lookup_color_option_argb(const char *section, const char *name, uint32 default_value); +GSList * gnc_lookup_list_option(const char *section, const char *name, + GSList *default_value); + void gnc_set_option_default(const char *section, const char *name); gboolean gnc_set_number_range_option(const char *section, const char *name, diff --git a/src/gnome/option-util.c b/src/gnome/option-util.c index 69f470802f..160ad5d66e 100644 --- a/src/gnome/option-util.c +++ b/src/gnome/option-util.c @@ -1745,6 +1745,78 @@ uint32 gnc_option_db_lookup_color_option_argb(GNCOptionDB *odb, } +/********************************************************************\ + * gnc_option_db_lookup_list_option * + * looks up a list option. If present, returns its value as a * + * list of strings representing the symbols. * + * * + * Args: odb - option database to search in * + * section - section name of option * + * name - name of option * + * default_value - default value to return if problem * + * Return: list of values * +\********************************************************************/ +GSList * +gnc_option_db_lookup_list_option(GNCOptionDB *odb, + const char *section, + const char *name, + GSList *default_value) +{ + GNCOption *option; + GSList *list = NULL; + SCM getter; + SCM value; + SCM item; + + option = gnc_option_db_get_option_by_name(odb, section, name); + if (option == NULL) + return default_value; + + getter = gnc_option_getter(option); + if (getter == SCM_UNDEFINED) + return default_value; + + value = gh_call0(getter); + while (gh_list_p(value) && !gh_null_p(value)) + { + item = gh_car(value); + value = gh_cdr(value); + + if (!gh_symbol_p(item)) + { + gnc_free_list_option_value(list); + + return default_value; + } + + list = g_slist_prepend(list, gh_symbol2newstr(item, NULL)); + } + + if (!gh_list_p(value) || !gh_null_p(value)) + { + gnc_free_list_option_value(list); + + return default_value; + } + + return list; +} + + +static void +free_helper(gpointer string, gpointer not_used) +{ + if (string) free(string); +} + +void +gnc_free_list_option_value(GSList *list) +{ + g_slist_foreach(list, free_helper, NULL); + g_slist_free(list); +} + + /********************************************************************\ * gnc_option_db_set_option_default * * set the option to its default value * diff --git a/src/gnome/option-util.h b/src/gnome/option-util.h index b327e55c29..e791a1f811 100644 --- a/src/gnome/option-util.h +++ b/src/gnome/option-util.h @@ -164,6 +164,13 @@ uint32 gnc_option_db_lookup_color_option_argb(GNCOptionDB *odb, const char *name, uint32 default_value); +GSList * gnc_option_db_lookup_list_option(GNCOptionDB *odb, + const char *section, + const char *name, + GSList *default_value); + +void gnc_free_list_option_value(GSList *list); + void gnc_option_db_set_option_default(GNCOptionDB *odb, const char *section, const char *name); diff --git a/src/gnome/window-main.c b/src/gnome/window-main.c index 390f089beb..dfd17a4f59 100644 --- a/src/gnome/window-main.c +++ b/src/gnome/window-main.c @@ -418,9 +418,11 @@ gnc_ui_mainWindow_destroy_cb(GtkObject *object, gpointer user_data) { GNCMainInfo *main_info = user_data; - gnc_unregister_option_change_callback_id(main_info->tree_change_callback_1); - gnc_unregister_option_change_callback_id(main_info->tree_change_callback_2); - gnc_unregister_option_change_callback_id(main_info->toolbar_change_callback); + gnc_unregister_option_change_callback_id + (main_info->main_window_change_callback_id); + + gnc_unregister_option_change_callback_id + (main_info->toolbar_change_callback_id); g_slist_free(main_info->account_sensitives); main_info->account_sensitives = NULL; @@ -472,111 +474,92 @@ gnc_configure_account_tree(void *data) GNCAccountTree *tree; AccountViewInfo new_avi; AccountViewInfo old_avi; + GSList *list, *node; + + memset(&new_avi, 0, sizeof(new_avi)); app = GTK_OBJECT(gnc_get_ui_data()); - tree = gnc_get_current_account_tree(); + tree = gnc_get_current_account_tree(); if (tree == NULL) return; + list = gnc_lookup_list_option("Main Window", + "Account types to display", + NULL); + + for (node = list; node != NULL; node = node->next) + { + if (safe_strcmp(node->data, "bank") == 0) + new_avi.include_type[BANK] = TRUE; + + else if (safe_strcmp(node->data, "cash") == 0) + new_avi.include_type[CASH] = TRUE; + + else if (safe_strcmp(node->data, "credit") == 0) + new_avi.include_type[CREDIT] = TRUE; + + else if (safe_strcmp(node->data, "asset") == 0) + new_avi.include_type[ASSET] = TRUE; + + else if (safe_strcmp(node->data, "liability") == 0) + new_avi.include_type[LIABILITY] = TRUE; + + else if (safe_strcmp(node->data, "stock") == 0) + new_avi.include_type[STOCK] = TRUE; + + else if (safe_strcmp(node->data, "mutual") == 0) + new_avi.include_type[MUTUAL] = TRUE; + + else if (safe_strcmp(node->data, "currency") == 0) + new_avi.include_type[CURRENCY] = TRUE; + + else if (safe_strcmp(node->data, "income") == 0) + new_avi.include_type[INCOME] = TRUE; + + else if (safe_strcmp(node->data, "expense") == 0) + new_avi.include_type[EXPENSE] = TRUE; + + else if (safe_strcmp(node->data, "equity") == 0) + new_avi.include_type[EQUITY] = TRUE; + } + + gnc_free_list_option_value(list); + + list = gnc_lookup_list_option("Main Window", + "Account fields to display", + NULL); + + for (node = list; node != NULL; node = node->next) + { + if (safe_strcmp(node->data, "type") == 0) + new_avi.show_field[ACCOUNT_TYPE] = TRUE; + + else if (safe_strcmp(node->data, "code") == 0) + new_avi.show_field[ACCOUNT_CODE] = TRUE; + + else if (safe_strcmp(node->data, "description") == 0) + new_avi.show_field[ACCOUNT_DESCRIPTION] = TRUE; + + else if (safe_strcmp(node->data, "notes") == 0) + new_avi.show_field[ACCOUNT_NOTES] = TRUE; + + else if (safe_strcmp(node->data, "currency") == 0) + new_avi.show_field[ACCOUNT_CURRENCY] = TRUE; + + else if (safe_strcmp(node->data, "security") == 0) + new_avi.show_field[ACCOUNT_SECURITY] = TRUE; + + else if (safe_strcmp(node->data, "balance") == 0) + new_avi.show_field[ACCOUNT_BALANCE] = TRUE; + } + + gnc_free_list_option_value(list); + + new_avi.show_field[ACCOUNT_NAME] = TRUE; + gnc_account_tree_get_view_info(tree, &old_avi); - new_avi.include_type[BANK] = - gnc_lookup_boolean_option("Account Types", - "Show bank accounts", - old_avi.include_type[BANK]); - - new_avi.include_type[CASH] = - gnc_lookup_boolean_option("Account Types", - "Show cash accounts", - old_avi.include_type[CASH]); - - new_avi.include_type[CREDIT] = - gnc_lookup_boolean_option("Account Types", - "Show credit accounts", - old_avi.include_type[CREDIT]); - - new_avi.include_type[ASSET] = - gnc_lookup_boolean_option("Account Types", - "Show asset accounts", - old_avi.include_type[ASSET]); - - new_avi.include_type[LIABILITY] = - gnc_lookup_boolean_option("Account Types", - "Show liability accounts", - old_avi.include_type[LIABILITY]); - - new_avi.include_type[STOCK] = - gnc_lookup_boolean_option("Account Types", - "Show stock accounts", - old_avi.include_type[STOCK]); - - new_avi.include_type[MUTUAL] = - gnc_lookup_boolean_option("Account Types", - "Show mutual fund accounts", - old_avi.include_type[MUTUAL]); - - new_avi.include_type[CURRENCY] = - gnc_lookup_boolean_option("Account Types", - "Show currency accounts", - old_avi.include_type[CURRENCY]); - - new_avi.include_type[INCOME] = - gnc_lookup_boolean_option("Account Types", - "Show income accounts", - old_avi.include_type[INCOME]); - - new_avi.include_type[EXPENSE] = - gnc_lookup_boolean_option("Account Types", - "Show expense accounts", - old_avi.include_type[EXPENSE]); - - new_avi.include_type[EQUITY] = - gnc_lookup_boolean_option("Account Types", - "Show equity accounts", - old_avi.include_type[EQUITY]); - - - new_avi.show_field[ACCOUNT_TYPE] = - gnc_lookup_boolean_option("Account Fields", - "Show account type", - old_avi.show_field[ACCOUNT_TYPE]); - - new_avi.show_field[ACCOUNT_NAME] = - gnc_lookup_boolean_option("Account Fields", - "Show account name", - old_avi.show_field[ACCOUNT_NAME]); - - new_avi.show_field[ACCOUNT_CODE] = - gnc_lookup_boolean_option("Account Fields", - "Show account code", - old_avi.show_field[ACCOUNT_CODE]); - - new_avi.show_field[ACCOUNT_DESCRIPTION] = - gnc_lookup_boolean_option("Account Fields", - "Show account description", - old_avi.show_field[ACCOUNT_DESCRIPTION]); - - new_avi.show_field[ACCOUNT_NOTES] = - gnc_lookup_boolean_option("Account Fields", - "Show account notes", - old_avi.show_field[ACCOUNT_NOTES]); - - new_avi.show_field[ACCOUNT_CURRENCY] = - gnc_lookup_boolean_option("Account Fields", - "Show account currency", - old_avi.show_field[ACCOUNT_CURRENCY]); - - new_avi.show_field[ACCOUNT_SECURITY] = - gnc_lookup_boolean_option("Account Fields", - "Show account security", - old_avi.show_field[ACCOUNT_SECURITY]); - - new_avi.show_field[ACCOUNT_BALANCE] = - gnc_lookup_boolean_option("Account Fields", - "Show account balance", - old_avi.show_field[ACCOUNT_BALANCE]); - if (memcmp(&old_avi, &new_avi, sizeof(AccountViewInfo)) != 0) gnc_account_tree_set_view_info(tree, &new_avi); } @@ -945,13 +928,9 @@ mainWindow() main_info->account_tree = gnc_account_tree_new(); - main_info->tree_change_callback_1 = + main_info->main_window_change_callback_id = gnc_register_option_change_callback(gnc_configure_account_tree, NULL, - "Account Types", NULL); - - main_info->tree_change_callback_2 = - gnc_register_option_change_callback(gnc_configure_account_tree, NULL, - "Account Fields", NULL); + "Main Window", NULL); gtk_signal_connect(GTK_OBJECT(main_info->account_tree), "activate_account", GTK_SIGNAL_FUNC (gnc_account_tree_activate_cb), NULL); @@ -973,7 +952,7 @@ mainWindow() gnc_main_create_toolbar(GNOME_APP(app), main_info); gnc_configure_toolbar(NULL); - main_info->toolbar_change_callback = + main_info->toolbar_change_callback_id = gnc_register_option_change_callback(gnc_configure_toolbar, NULL, "General", "Toolbar Buttons"); diff --git a/src/gnome/window-mainP.h b/src/gnome/window-mainP.h index 911b3c6877..e07cdc7d24 100644 --- a/src/gnome/window-mainP.h +++ b/src/gnome/window-mainP.h @@ -33,9 +33,8 @@ struct _GNCMainInfo GtkWidget *assets_label; GtkWidget *profits_label; - SCM tree_change_callback_1; - SCM tree_change_callback_2; - SCM toolbar_change_callback; + SCM main_window_change_callback_id; + SCM toolbar_change_callback_id; GSList *account_sensitives; };