dialogs.c

来自「elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, el」· C语言 代码 · 共 826 行 · 第 1/2 页

C
826
字号
			n_("%u remaining", "%u remaining", value, term), value);	}	/* Statistics: */	add_format_to_string(&string, "\n%s: ", _("Statistics", term));	value = list_size(&bittorrent->cache->queue);	add_format_to_string(&string,		n_("%u in memory", "%u in memory", value, term), value);	value = bittorrent->cache->locked_pieces;	if (value) {		add_to_string(&string, ", ");		add_format_to_string(&string,			n_("%u locked", "%u locked", value, term), value);	}	value = bittorrent->cache->rejected_pieces;	if (value) {		add_to_string(&string, ", ");		add_format_to_string(&string,			n_("%u rejected", "%u rejected", value, term), value);	}	value = bittorrent->cache->unavailable_pieces;	if (value) {		add_to_string(&string, ", ");		add_format_to_string(&string,			n_("%u unavailable", "%u unavailable", value, term), value);	}	return string.source;}voiddraw_bittorrent_piece_progress(struct download *download, struct terminal *term,			       int x, int y, int width, unsigned char *text,			       struct color_pair *color){	struct bittorrent_connection *bittorrent;	uint32_t piece;	int x_start;	if (!download->conn || !download->conn->info)		return;	bittorrent = download->conn->info;	/* Draw the progress meter part "[###    ]" */	if (!text && width > 2) {		width -= 2;		draw_text(term, x++, y, "[", 1, 0, NULL);		draw_text(term, x + width, y, "]", 1, 0, NULL);	}	x_start = x;	if (width <= 0 || !bittorrent->cache)		return;	if (!color) color = get_bfu_color(term, "dialog.meter");	if (bittorrent->meta.pieces <= width) {		int chars_per_piece = width / bittorrent->meta.pieces;		int remainder	    = width % bittorrent->meta.pieces;		for (piece = 0; piece < bittorrent->meta.pieces; piece++) {			struct box piecebox;			set_box(&piecebox, x, y, chars_per_piece + !!remainder, 1);			if (bittorrent->cache->entries[piece].completed)				draw_box(term, &piecebox, ' ', 0, color);			x += chars_per_piece + !!remainder;			if (remainder > 0) remainder--;		}	} else {		int pieces_per_char = bittorrent->meta.pieces / width;		int remainder 	    = bittorrent->meta.pieces % width;		struct color_pair inverted;		uint32_t completed = 0, remaining = 0;		int steps = pieces_per_char + !!remainder;		inverted.background = color->foreground;		inverted.foreground = color->background;		for (piece = 0; piece < bittorrent->meta.pieces; piece++) {			if (bittorrent->cache->entries[piece].completed)				completed++;			else				remaining++;			if (--steps > 0)				continue;			assert(completed <= pieces_per_char + !!remainder);			assert(remaining <= pieces_per_char + !!remainder);			if (!remaining)				/*  100% */				draw_char_color(term, x, y, color);			else if (completed > remaining)		/* > 50% */				draw_char(term, x, y, BORDER_SVLINE,					  SCREEN_ATTR_FRAME, color);			else if (completed)			/* >  0% */				draw_char(term, x, y, BORDER_SVLINE,					  SCREEN_ATTR_FRAME, &inverted);			x++;			if (remainder > 0) remainder--;			remaining = completed = 0;			steps = pieces_per_char + !!remainder;		}	}	if (download->state == S_RESUME) {		static unsigned char s[] = "????"; /* Reduce or enlarge at will. */		unsigned int slen = 0;		int max = int_min(sizeof(s), width) - 1;		int percent = 0;		percent = (int) ((longlong) 100 * bittorrent->cache->resume_pos						/ bittorrent->meta.pieces);		if (ulongcat(s, &slen, percent, max, 0)) {			s[0] = '?';			slen = 1;		}		s[slen++] = '%';		/* Draw the percentage centered in the progress meter */		x_start += (1 + width - slen) / 2;		assert(slen <= width);		draw_text(term, x_start, y, s, slen, 0, NULL);	}}/* ************************************************************************** *//* Display Failure Reason from the tracker: *//* ************************************************************************** */voidbittorrent_message_dialog(struct session *ses, void *data){	struct bittorrent_message *message = data;	struct string string;	unsigned char *uristring;	/* Don't show error dialogs for missing CSS stylesheets */	if (!init_string(&string))		return;	uristring = get_uri_string(message->uri, URI_PUBLIC);	if (uristring) {		decode_uri_for_display(uristring);		add_format_to_string(&string,			_("Unable to retrieve %s", ses->tab->term),			uristring);		mem_free(uristring);		add_to_string(&string, ":\n\n");	}	if (message->state != S_OK) {		add_format_to_string(&string, "%s: %s",			get_state_message(S_BITTORRENT_TRACKER, ses->tab->term),			get_state_message(message->state, ses->tab->term));	} else {		add_to_string(&string, message->string);	}	info_box(ses->tab->term, MSGBOX_FREE_TEXT,		 N_("Error"), ALIGN_CENTER,		 string.source);	done_bittorrent_message(message);}/* ************************************************************************** *//* BitTorrent download querying: *//* ************************************************************************** */static voidabort_bittorrent_download_query(struct dialog_data *dlg_data){	struct bittorrent_download_info *info = dlg_data->dlg->udata;	done_bittorrent_download_info(info);}/* The download button handler. Basicly it redirects <uri> to bittorrent:<uri> * and starts displaying the download. */static widget_handler_status_Tbittorrent_download(struct dialog_data *dlg_data, struct widget_data *widget_data){	struct type_query *type_query = dlg_data->dlg->udata2;	struct bittorrent_download_info *info = dlg_data->dlg->udata;	struct file_download *file_download;	struct session *ses = type_query->ses;	struct string redirect;	struct uri *uri;	struct connection conn;	if (!init_string(&redirect))		return cancel_dialog(dlg_data, widget_data);	add_to_string(&redirect, "bittorrent:");	add_uri_to_string(&redirect, type_query->uri, URI_ORIGINAL);	uri = get_uri(redirect.source, 0);	done_string(&redirect);	tp_cancel(type_query);	if (!uri)		return cancel_dialog(dlg_data, widget_data);	file_download = init_file_download(uri, ses, info->name, -1);	done_uri(uri);	if (!file_download)		return cancel_dialog(dlg_data, widget_data);	update_dialog_data(dlg_data);	/* Put the meta info in the store. */	add_bittorrent_selection(file_download->uri, info->selection, info->size);	info->selection = NULL;	info->name = NULL;	/* XXX: Hackery to get the Info button installed */	conn.uri = file_download->uri;	file_download->download.conn = &conn;	/* Done here and not in init_file_download() so that the external	 * handler can become initialized. */	display_download(ses->tab->term, file_download, ses);	file_download->download.conn = NULL;	load_uri(file_download->uri, ses->referrer, &file_download->download,		 PRI_DOWNLOAD, CACHE_MODE_NORMAL, file_download->seek);	return cancel_dialog(dlg_data, widget_data);}/* Show the protocol header. *//* XXX: Code duplication with session/download.h */widget_handler_status_Ttp_show_header(struct dialog_data *dlg_data, struct widget_data *widget_data){	struct type_query *type_query = widget_data->widget->data;	cached_header_dialog(type_query->ses, type_query->cached);	return EVENT_PROCESSED;}/* Build a dialog querying the user on how to handle a .torrent file. */static voidbittorrent_query_callback(void *data, enum connection_state state,			    struct string *response){	struct type_query *type_query = data;	struct string filename;	unsigned char *text;	struct dialog *dlg;#define BITTORRENT_QUERY_WIDGETS_COUNT	6	int widgets = BITTORRENT_QUERY_WIDGETS_COUNT;	struct terminal *term = type_query->ses->tab->term;	struct bittorrent_download_info *info;	struct bittorrent_meta meta;	struct dialog_data *dlg_data;	int selected_widget;	struct memory_list *ml;	struct string msg;	int files;	if (state != S_OK)		return;	/* This should never happen, since setup_download_handler() should make	 * sure to handle application/x-bittorrent document types in the default	 * type query handler. */	if (get_cmd_opt_bool("anonymous")) {		INTERNAL("BitTorrent downloads not allowed in anonymous mode.");		return;	}	if (!init_string(&msg))		return;	if (init_string(&filename)) {		add_mime_filename_to_string(&filename, type_query->uri);		/* Let's make the filename pretty for display & save */		/* TODO: The filename can be the empty string here. See bug 396. */		decode_uri_string_for_display(&filename);	}	add_format_to_string(&msg,		_("What would you like to do with the file '%s'?", term),		filename.source);	done_string(&filename);	if (parse_bittorrent_metafile(&meta, response) != BITTORRENT_STATE_OK) {		print_error_dialog(type_query->ses, S_BITTORRENT_METAINFO,				   type_query->uri, PRI_CANCEL);		tp_cancel(type_query);		done_string(&msg);		return;	}	files = list_size(&meta.files);	add_format_to_string(&msg, "\n%s:",		_("Information about the torrent", term));	add_bittorrent_meta_to_string(&msg, &meta, term, files == 1);	info = init_bittorrent_download_info(&meta);	done_bittorrent_meta(&meta);	if (!info) {		done_string(&msg);		return;	}	dlg = calloc_dialog(widgets + files, msg.length + 1);	if (!dlg) {		done_bittorrent_download_info(info);		done_string(&msg);		return;	}	text = get_dialog_offset(dlg, widgets + files);	memcpy(text, msg.source, msg.length + 1);	done_string(&msg);	dlg->title = _("What to do?", term);	dlg->abort = abort_bittorrent_download_query;	dlg->layouter = generic_dialog_layouter;	dlg->layout.padding_top = 1;	dlg->layout.fit_datalen = 1;	dlg->udata2 = type_query;	dlg->udata = info;	add_dlg_text(dlg, text, ALIGN_LEFT, 0);	dlg->widgets->info.text.is_scrollable = 1;	if (files > 1) {		struct string_list_item *item;		size_t index = 0;		foreach (item, info->labels) {			add_dlg_checkbox(dlg, item->string.source, &info->selection[index++]);			widgets++;		}	}	selected_widget = dlg->number_of_widgets;	add_dlg_button(dlg, _("Down~load", term), B_ENTER,			bittorrent_download, type_query);	add_dlg_ok_button(dlg, _("Sa~ve", term), B_ENTER,			  (done_handler_T *) tp_save, type_query);	add_dlg_ok_button(dlg, _("~Display", term), B_ENTER,			  (done_handler_T *) tp_display, type_query);	if (type_query->cached && type_query->cached->head && *type_query->cached->head) {		add_dlg_button(dlg, _("Show ~header", term), B_ENTER,			       tp_show_header, type_query);	} else {		widgets--;	}	add_dlg_ok_button(dlg, _("~Cancel", term), B_ESC,			  (done_handler_T *) tp_cancel, type_query);	add_dlg_end(dlg, widgets);	ml = getml(dlg, NULL);	if (!ml) {		/* XXX: Assume that the allocated @external_handler will be		 * freed when releasing the @type_query. */		done_bittorrent_download_info(info);		mem_free(dlg);		return;	}	dlg_data = do_dialog(term, dlg, ml);	if (dlg_data)		select_widget_by_id(dlg_data, selected_widget);}voidquery_bittorrent_dialog(struct type_query *type_query){	init_bittorrent_fetch(NULL, type_query->uri,			      bittorrent_query_callback, type_query, 0);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?