📄 dialogs.c
字号:
/* Options dialogs *//* $Id: dialogs.c,v 1.201.4.8 2005/04/06 09:11:18 jonas Exp $ */#ifndef _GNU_SOURCE#define _GNU_SOURCE /* XXX: we _WANT_ strcasestr() ! */#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#include "elinks.h"#include "bfu/dialog.h"#include "config/conf.h"#include "config/dialogs.h"#include "config/kbdbind.h"#include "config/options.h"#include "config/opttypes.h"#include "intl/gettext/libintl.h"#include "sched/session.h"#include "terminal/kbd.h"#include "terminal/terminal.h"#include "util/color.h"#include "util/error.h"#include "util/lists.h"#include "util/memory.h"#include "util/object.h"#include "util/secsave.h"static voidtoggle_success_msgbox(void *dummy){ get_opt_bool("ui.success_msgbox") = !get_opt_bool("ui.success_msgbox"); get_opt_rec(config_options, "ui.success_msgbox")->flags |= OPT_TOUCHED;}voidwrite_config_dialog(struct terminal *term, unsigned char *config_file, int secsave_error, int stdio_error){ unsigned char *errmsg = NULL; unsigned char *strerr; if (secsave_error == SS_ERR_NONE && !stdio_error) { if (!get_opt_bool("ui.success_msgbox")) return; msg_box(term, NULL, MSGBOX_FREE_TEXT, N_("Write config success"), ALIGN_CENTER, msg_text(term, N_("Options were saved successfully to config file %s."), config_file), NULL, 2, N_("~OK"), NULL, B_ENTER | B_ESC, N_("~Do not show anymore"), toggle_success_msgbox, 0); return; } switch (secsave_error) { case SS_ERR_OPEN_READ: strerr = _("Cannot read the file", term); break; case SS_ERR_STAT: strerr = _("Cannot get file status", term); break; case SS_ERR_ACCESS: strerr = _("Cannot access the file", term); break; case SS_ERR_MKSTEMP: strerr = _("Cannot create temp file", term); break; case SS_ERR_RENAME: strerr = _("Cannot rename the file", term); break; case SS_ERR_DISABLED: strerr = _("File saving disabled by option", term); break; case SS_ERR_OUT_OF_MEM: strerr = _("Out of memory", term); break; case SS_ERR_OPEN_WRITE: strerr = _("Cannot write the file", term); break; case SS_ERR_NONE: /* Impossible. */ case SS_ERR_OTHER: default: strerr = _("Secure file saving error", term); break; } if (stdio_error > 0) errmsg = straconcat(strerr, " (", strerror(stdio_error), ")", NULL); info_box(term, MSGBOX_FREE_TEXT, N_("Write config error"), ALIGN_CENTER, msg_text(term, N_("Unable to write to config file %s.\n%s"), config_file, errmsg ? errmsg : strerr)); mem_free_if(errmsg);}/**************************************************************************** Option manager stuff.****************************************************************************//* Implementation of the listbox operations */static voidlock_option(struct listbox_item *item){ object_lock((struct option *) item->udata);}static voidunlock_option(struct listbox_item *item){ object_unlock((struct option *) item->udata);}static intis_option_used(struct listbox_item *item){ return is_object_used((struct option *) item->udata);}static unsigned char *get_range_string(struct option *option){ struct string info; if (!init_string(&info)) return NULL; if (option->type == OPT_BOOL) add_to_string(&info, "[0|1]"); else if (option->type == OPT_INT || option->type == OPT_LONG) add_format_to_string(&info, "[%li..%li]", option->min, option->max); return info.source;}static unsigned char *get_option_text(struct listbox_item *item, struct terminal *term){ struct option *option = item->udata; unsigned char *desc = option->capt ? option->capt : option->name; if (option->flags & OPT_TOUCHED) return straconcat(_(desc, term), " (", _("modified", term), ")", NULL); return stracpy(_(desc, term));}static unsigned char *get_option_info(struct listbox_item *item, struct terminal *term){ struct option *option = item->udata; unsigned char *desc, *type; struct string info; if (!init_string(&info)) return NULL; type = _(option_types[option->type].name, term); if (option->type == OPT_TREE) { type = straconcat(type, " ", _("(expand by pressing space)", term), NULL); } desc = _(option->desc ? option->desc : (unsigned char *) "N/A", term); if (option_types[option->type].write) { unsigned char *range; struct string value; if (!init_string(&value)) { done_string(&info); return NULL; } option_types[option->type].write(option, &value); add_format_to_string(&info, "%s: %s", _("Name", term), option->name); add_format_to_string(&info, "\n%s: %s", _("Type", term), type); range = get_range_string(option); if (range) { if (*range) { add_to_string(&info, " "); add_to_string(&info, range); } mem_free(range); } add_format_to_string(&info, "\n%s: %s", _("Value", term), value.source); if (option->flags & OPT_TOUCHED) add_to_string(&info, _("\n\nThis value has been changed" " since you last saved your" " configuration.", term)); if (*desc) add_format_to_string(&info, "\n\n%s:\n%s", _("Description", term), desc); done_string(&value); } else { add_format_to_string(&info, "%s: %s", _("Name", term), option->name); add_format_to_string(&info, "\n%s: %s", _("Type", term), type); if (*desc) add_format_to_string(&info, "\n\n%s:\n%s", _("Description", term), desc); } if (option->type == OPT_TREE) { mem_free(type); } return info.source;}static struct listbox_item *get_option_root(struct listbox_item *item){ struct option *option = item->udata; /* The config_options root has no listbox so return that * we are at the bottom. */ if (option->root == config_options) return NULL; return option->root ? option->root->box_item : NULL;}static enum listbox_matchmatch_option(struct listbox_item *item, struct terminal *term, unsigned char *text){ struct option *option = item->udata; if (option->type == OPT_TREE) return LISTBOX_MATCH_IMPOSSIBLE; if (strcasestr(option->name, text) || (option->capt && strcasestr(_(option->capt, term), text))) return LISTBOX_MATCH_OK; return LISTBOX_MATCH_NO;}static intcan_delete_option(struct listbox_item *item){ struct option *option = item->udata; if (option->root) { struct option *parent_option = option->root; return parent_option->flags & OPT_AUTOCREATE; } return 0;}static voiddelete_option_item(struct listbox_item *item, int last){ struct option *option = item->udata; assert(!is_object_used(option)); /* Only built-in options needs to be marked as deleted, so if the * option is allocated call the cleaner. */ if (option->flags & OPT_ALLOC) delete_option(option); else mark_option_as_deleted(option);}static struct listbox_ops options_listbox_ops = { lock_option, unlock_option, is_option_used, get_option_text, get_option_info, NULL, get_option_root, match_option, can_delete_option, delete_option_item, NULL, NULL,};/* Button handlers */static t_handler_event_statuscheck_valid_option(struct dialog_data *dlg_data, struct widget_data *widget_data){ struct terminal *term = dlg_data->win->term; struct option *option = dlg_data->dlg->udata; struct session *ses = dlg_data->dlg->udata2; unsigned char *value = widget_data->cdata; unsigned char *chinon; int dummy_line = 0; commandline = 1; chinon = option_types[option->type].read(option, &value, &dummy_line); if (chinon) { if (option_types[option->type].set && option_types[option->type].set(option, chinon)) { struct option *current = option; option->flags |= OPT_TOUCHED; /* Notify everyone out there! */ /* This boolean thing can look a little weird - it * basically says that we should proceed when there's * no change_hook or there's one and its return value * was zero. */ while (current && (!current->change_hook || !current->change_hook(ses, current, option))) { if (!current->root) break; current = current->root; } commandline = 0; mem_free(chinon); return EVENT_PROCESSED; } mem_free(chinon); } commandline = 0; info_box(term, 0, N_("Error"), ALIGN_LEFT, N_("Bad option value.")); return EVENT_NOT_PROCESSED;}static voidbuild_edit_dialog(struct terminal *term, struct session *ses, struct option *option){#define EDIT_WIDGETS_COUNT 5 struct dialog *dlg; unsigned char *value, *name, *desc, *range; struct string tvalue; if (!init_string(&tvalue)) return; commandline = 1; option_types[option->type].write(option, &tvalue); commandline = 0; /* Create the dialog */ dlg = calloc_dialog(EDIT_WIDGETS_COUNT, MAX_STR_LEN); if (!dlg) { done_string(&tvalue); return; } dlg->title = _("Edit", term); dlg->layouter = generic_dialog_layouter; dlg->udata = option; dlg->udata2 = ses; value = get_dialog_offset(dlg, EDIT_WIDGETS_COUNT); safe_strncpy(value, tvalue.source, MAX_STR_LEN); done_string(&tvalue); name = straconcat(_("Name", term), ": ", option->name, "\n", _("Type", term), ": ", _(option_types[option->type].name, term), NULL); desc = straconcat(_("Description", term), ": \n", _(option->desc ? option->desc : (unsigned char *) "N/A", term), NULL); range = get_range_string(option); if (range) { if (*range) { unsigned char *tmp; tmp = straconcat(name, " ", range, NULL); if (tmp) { mem_free(name); name = tmp; } } mem_free(range); } if (!name || !desc) { mem_free_if(name); mem_free_if(desc); mem_free(dlg); return; } /* FIXME: Compute some meaningful maximal width. --pasky */ add_dlg_text(dlg, name, ALIGN_LEFT, 0); add_dlg_field_float(dlg, _("Value", term), 0, 0, check_valid_option, MAX_STR_LEN, value, NULL); add_dlg_text(dlg, desc, ALIGN_LEFT, 0); add_dlg_button(dlg, _("~OK", term), B_ENTER, ok_dialog, NULL); add_dlg_button(dlg, _("~Cancel", term), B_ESC, cancel_dialog, NULL); add_dlg_end(dlg, EDIT_WIDGETS_COUNT); do_dialog(term, dlg, getml(dlg, name, desc, NULL));#undef EDIT_WIDGETS_COUNT}static t_handler_event_statuspush_edit_button(struct dialog_data *dlg_data, struct widget_data *some_useless_info_button){ struct terminal *term = dlg_data->win->term; struct listbox_data *box = get_dlg_listbox_data(dlg_data); struct option *option; /* Show history item info */ if (!box->sel || !box->sel->udata) return EVENT_PROCESSED; option = box->sel->udata; if (!option_types[option->type].write || !option_types[option->type].read || !option_types[option->type].set) { info_box(term, 0, N_("Edit"), ALIGN_LEFT, N_("This option cannot be edited. This means that " "this is some special option like a folder - try " "to press a space in order to see its contents.")); return EVENT_PROCESSED; } build_edit_dialog(term, dlg_data->dlg->udata, option); return EVENT_PROCESSED;}static voidadd_option_to_tree(void *data, unsigned char *name){ struct option *option = data; struct option *old = get_opt_rec_real(option, name); if (old && (old->flags & OPT_DELETED)) delete_option(old); /* get_opt_rec() will do all the work for ourselves... ;-) */ get_opt_rec(option, name); /* TODO: If the return value is NULL, we should pop up a msgbox. */}static t_handler_event_statuspush_add_button(struct dialog_data *dlg_data, struct widget_data *some_useless_info_button){ struct terminal *term = dlg_data->win->term; struct listbox_data *box = get_dlg_listbox_data(dlg_data); struct listbox_item *item = box->sel; struct option *option; if (!item || !item->udata) {invalid_option: info_box(term, 0, N_("Add option"), ALIGN_CENTER, N_("Cannot add an option here.")); return EVENT_PROCESSED; } if (item->type == BI_FOLDER && !item->expanded) { item = box->ops->get_root(item); if (!item || !item->udata) goto invalid_option;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -