Пример #1
0
enum plugin_status plugin_start(const void* nothing) 
{
    (void)nothing;
    rb->lcd_clear_display();
    rb->lcd_update();
    int main_menu_selection = 0;
    bool menuquit = false;

    display = rb->screens[0];
    rb->viewport_set_defaults(&screen_vp,0);
    rb->viewport_set_defaults(&text_vp,0);
    rb->viewport_set_defaults(&bitmap_vp,0);
#ifndef USE_TEXT_ONLY
    bitmap_vp.y = RESISTOR_BMP_Y + screen_vp.y;
    bitmap_vp.height = BMPHEIGHT_resistor;
    text_vp.y = bitmap_vp.y + bitmap_vp.height;
    text_vp.height = screen_vp.height - text_vp.y;
#endif

    MENUITEM_STRINGLIST(main_menu, "Resistor Code Calculator:", NULL, 
                        "Colours -> Resistance", "Resistance -> Colours", 
                        "LED resistor calculator", "Help", "Exit");
    while (!menuquit) {
        display->set_viewport(&screen_vp);
        main_menu_selection = rb->do_menu(&main_menu, &main_menu_selection, 
                                          NULL, false);
        switch(main_menu_selection) {
            case 0:
                color_to_resistance();
                break;
            case 1:
                resistance_to_color();
                break;
            case 2:
                led_resistance_calc();
                break;
            case 3:
                display_helpfile();
                break;
            case 4:
                menuquit = true;
                break;
            case MENU_ATTACHED_USB:
                return PLUGIN_USB_CONNECTED;
        }
    }
    return PLUGIN_OK;
}
Пример #2
0
/*
 * Display a dialog box with a list of options that can be turned on or off
 */
int
dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width,
		 int list_height, int cnt, void *it, unsigned char *result)
{
    int i, j, x, y, cur_x, cur_y, old_x, old_y, box_x, box_y, key = 0, button,
	choice, l, k, scroll, max_choice, item_no = 0, *status;
    int redraw_menu = FALSE, cursor_reset = FALSE;
    int rval = 0, onlist = 1, ok_space, cancel_space;
    char okButton, cancelButton;
    WINDOW *dialog, *list;
    unsigned char **items = NULL;
    dialogMenuItem *ditems;
    int list_width, check_x, item_x;

    /* Allocate space for storing item on/off status */
    if ((status = alloca(sizeof(int) * abs(cnt))) == NULL) {
	endwin();
	fprintf(stderr, "\nCan't allocate memory in dialog_checklist().\n");
	exit(-1);
    }
    
draw:
    choice = scroll = button = 0;
    /* Previous calling syntax, e.g. just a list of strings? */
    if (cnt >= 0) {
	items = it;
	ditems = NULL;
	item_no = cnt;
	/* Initializes status */
	for (i = 0; i < item_no; i++)
	    status[i] = !strcasecmp(items[i*3 + 2], "on");
    }
    /* It's the new specification format - fake the rest of the code out */
    else {
	item_no = abs(cnt);
	ditems = it;
	if (!items)
	    items = (unsigned char **)alloca((item_no * 3) * sizeof(unsigned char *));
	
	/* Initializes status */
	for (i = 0; i < item_no; i++) {
	    status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
	    items[i*3] = ditems[i].prompt;
	    items[i*3 + 1] = ditems[i].title;
	    items[i*3 + 2] = status[i] ? "on" : "off";
	}
    }
    max_choice = MIN(list_height, item_no);
    
    check_x = 0;
    item_x = 0;
    /* Find length of longest item in order to center checklist */
    for (i = 0; i < item_no; i++) {
	l = strlen(items[i*3]);
	for (j = 0; j < item_no; j++) {
	    k = strlen(items[j*3 + 1]);
	    check_x = MAX(check_x, l + k + 6);
	}
	item_x = MAX(item_x, l);
    }
    if (height < 0)
	height = strheight(prompt)+list_height+4+2;
    if (width < 0) {
	i = strwidth(prompt);
	j = ((title != NULL) ? strwidth(title) : 0);
	width = MAX(i,j);
	width = MAX(width,check_x+4)+4;
    }
    width = MAX(width,24);
    
    if (width > COLS)
	width = COLS;
    if (height > LINES)
	height = LINES;
    /* center dialog box on screen */
    x = (COLS - width)/2;
    y = (LINES - height)/2;

#ifdef HAVE_NCURSES
    if (use_shadow)
	draw_shadow(stdscr, y, x, height, width);
#endif
    dialog = newwin(height, width, y, x);
    if (dialog == NULL) {
	endwin();
	fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width, y, x);
	return -1;
    }
    keypad(dialog, TRUE);
    
    draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
    wattrset(dialog, border_attr);
    wmove(dialog, height-3, 0);
    waddch(dialog, ACS_LTEE);
    for (i = 0; i < width-2; i++)
	waddch(dialog, ACS_HLINE);
    wattrset(dialog, dialog_attr);
    waddch(dialog, ACS_RTEE);
    wmove(dialog, height-2, 1);
    for (i = 0; i < width-2; i++)
	waddch(dialog, ' ');
    
    if (title != NULL) {
	wattrset(dialog, title_attr);
	wmove(dialog, 0, (width - strlen(title))/2 - 1);
	waddch(dialog, ' ');
	waddstr(dialog, title);
	waddch(dialog, ' ');
    }
    wattrset(dialog, dialog_attr);
    wmove(dialog, 1, 2);
    print_autowrap(dialog, prompt, height - 1, width - 2, width, 1, 2, TRUE, FALSE);
    
    list_width = width - 6;
    getyx(dialog, cur_y, cur_x);
    box_y = cur_y + 1;
    box_x = (width - list_width) / 2 - 1;
    
    /* create new window for the list */
    list = subwin(dialog, list_height, list_width, y + box_y + 1, x + box_x + 1);
    if (list == NULL) {
	delwin(dialog);
	endwin();
	fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", list_height, list_width,
		y + box_y + 1, x + box_x + 1);
	return -1;
    }
    keypad(list, TRUE);
    
    /* draw a box around the list items */
    draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);
    
    check_x = (list_width - check_x) / 2;
    item_x = check_x + item_x + 6;
    
    /* Print the list */
    for (i = 0; i < max_choice; i++)
	print_item(list, items[i * 3], items[i * 3 + 1], status[i], i, i == choice, DREF(ditems, i), list_width, item_x, check_x);
    wnoutrefresh(list);
    print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
    
    display_helpline(dialog, height - 1, width);
    
    x = width / 2 - 11;
    y = height - 2;
    /* Is this a fancy new style argument string where we get to override
     * the buttons, or an old style one where they're fixed?
     */
    if (ditems && result) {
	cancelButton = toupper(ditems[CANCEL_BUTTON].prompt[0]);
	print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : FALSE);
	okButton = toupper(ditems[OK_BUTTON].prompt[0]);
	print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : TRUE);
    }
    else {
	cancelButton = 'C';
	print_button(dialog, "Cancel", y, x + 14, FALSE);
	okButton = 'O';
	print_button(dialog, "  OK  ", y, x, TRUE);
    }
    wnoutrefresh(dialog);
    wmove(list, choice, check_x+1);
    wrefresh(list);

    /*
     *	XXX Black magic voodoo that allows printing to the checklist
     *	window. For some reason, if this "refresh" code is not in
     *	place, printing to the window from the selected callback
     *	prints "behind" the checklist window. There is probably a
     *	better way to do this.
     */
    draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);

    for (i = 0; i < max_choice; i++)
	print_item(list, items[i * 3], items[i * 3 + 1], status[i], i, i == choice, DREF(ditems, i), list_width, item_x, check_x);
    print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);

    wmove(list, choice, check_x+1);
    wnoutrefresh(dialog);
    wrefresh(list);
    /* XXX Black magic XXX */
    
    while (key != ESC) {
	key = wgetch(dialog);
	
	/* Shortcut to OK? */
	if (toupper(key) == okButton) {
	    if (ditems) {
		if (result && ditems[OK_BUTTON].fire) {
		    int st;
		    WINDOW *save;

		    save = dupwin(newscr);
		    st = ditems[OK_BUTTON].fire(&ditems[OK_BUTTON]);
		    if (st & DITEM_RESTORE) {
			touchwin(save);
			wrefresh(save);
		    }
		    delwin(save);
		}
	    }
	    else if (result) {
		*result = '\0';
		for (i = 0; i < item_no; i++) {
		    if (status[i]) {
			strcat(result, items[i*3]);
			strcat(result, "\n");
		    }
		}
	    }
	    rval = 0;
	    key = ESC;	/* Lemme out! */
	    break;
	}

	/* Shortcut to cancel? */
	if (toupper(key) == cancelButton) {
	    if (ditems && result && ditems[CANCEL_BUTTON].fire) {
		int st;
		WINDOW *save;

		save = dupwin(newscr);
		st = ditems[CANCEL_BUTTON].fire(&ditems[CANCEL_BUTTON]);
		if (st & DITEM_RESTORE) {
		    touchwin(save);
		    wrefresh(save);
		    wmove(dialog, cur_y, cur_x);
		}
		delwin(save);
	    }
	    rval = 1;
	    key = ESC;	/* I gotta go! */
	    break;
	}
	
	/* Check if key pressed matches first character of any item tag in list */
	for (i = 0; i < max_choice; i++)
	    if (key != ' ' && key < 0x100 && toupper(key) == toupper(items[(scroll+i)*3][0]))
		break;

	if (i < max_choice || (key >= '1' && key <= MIN('9', '0'+max_choice)) ||
	    KEY_IS_UP(key) || KEY_IS_DOWN(key) || ((key == ' ' || key == '\n' ||
	    key == '\r') && onlist)) {

	    /* if moving from buttons to the list, reset and redraw buttons */
	    if (!onlist) {
		onlist = 1;
		button = 0;

	        if (ditems && result) {
		    print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
		    print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
		}
		else {
		    print_button(dialog, "Cancel", y, x + 14, button);
		    print_button(dialog, "  OK  ", y, x, !button);
		}
		wmove(list, choice, check_x+1);
		wnoutrefresh(dialog);
		wrefresh(list);
	    }

	    if (key >= '1' && key <= MIN('9', '0'+max_choice))
		i = key - '1';
	    
	    else if (KEY_IS_UP(key)) {
		if (!choice) {
		    if (scroll) {
			/* Scroll list down */
			getyx(dialog, cur_y, cur_x);    /* Save cursor position */
			if (list_height > 1) {
			    /* De-highlight current first item before scrolling down */
			    print_item(list, items[scroll * 3], items[scroll * 3 + 1], status[scroll], 0,
				       FALSE, DREF(ditems, scroll), list_width, item_x, check_x);
			    scrollok(list, TRUE);
			    wscrl(list, -1);
			    scrollok(list, FALSE);
			}
			scroll--;
			print_item(list, items[scroll*3], items[scroll*3 + 1], status[scroll], 0,
				   TRUE, DREF(ditems, scroll), list_width, item_x, check_x);
			print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
			wmove(list, choice, check_x+1);
			wnoutrefresh(dialog);
			wrefresh(list);
		    }
		    continue;    /* wait for another key press */
		}
		else
		    i = choice - 1;
	    }
	    else if (KEY_IS_DOWN(key)) {
		if (choice == max_choice - 1) {
		    if (scroll + choice < item_no - 1) {
			/* Scroll list up */
			getyx(dialog, cur_y, cur_x);    /* Save cursor position */
			if (list_height > 1) {
			    /* De-highlight current last item before scrolling up */
			    print_item(list, items[(scroll + max_choice - 1) * 3],
				       items[(scroll + max_choice - 1) * 3 + 1],
				       status[scroll + max_choice - 1], max_choice - 1,
				       FALSE, DREF(ditems, scroll + max_choice - 1), list_width, item_x, check_x);
			    scrollok(list, TRUE);
			    scroll(list);
			    scrollok(list, FALSE);
			}
			scroll++;
			print_item(list, items[(scroll + max_choice - 1) * 3],
				   items[(scroll + max_choice - 1) * 3 + 1],
				   status[scroll + max_choice - 1], max_choice - 1, TRUE,
				   DREF(ditems, scroll + max_choice - 1), list_width, item_x, check_x);
			print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);
			wmove(list, choice, check_x+1);
			wnoutrefresh(dialog);
			wrefresh(list);
		    }
		    continue;    /* wait for another key press */
		}
		else
		    i = choice + 1;
	    }
	    else if ((key == ' ' || key == '\n' || key == '\r') && onlist) {    /* Toggle item status */
		char lbra = 0, rbra = 0, mark = 0;

		getyx(list, old_y, old_x);    /* Save cursor position */
		
		if (ditems) {
		    if (ditems[scroll + choice].fire) {
			int st;
			WINDOW *save;

			save = dupwin(newscr);
			st = ditems[scroll + choice].fire(&ditems[scroll + choice]);	/* Call "fire" action */
			if (st & DITEM_RESTORE) {
			    touchwin(save);
			    wrefresh(save);
			}
			delwin(save);
			if (st & DITEM_REDRAW) {
			    wclear(list);
			    for (i = 0; i < item_no; i++)
				status[i] = ditems[i].checked ? ditems[i].checked(&ditems[i]) : FALSE;
			    for (i = 0; i < max_choice; i++) {
				print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1],
					   status[scroll + i], i, i == choice, DREF(ditems, scroll + i), list_width, item_x, check_x);
			    }
			    wnoutrefresh(list);
			    print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4,
					 cur_x, cur_y);
			    wrefresh(dialog);
			}
			if (st & DITEM_LEAVE_MENU) {
			    /* Allow a fire action to take us out of the menu */
			    key = ESC;
			    rval = 0;
			    break;
			}
			else if (st & DITEM_RECREATE) {
			    delwin(list);
			    delwin(dialog);
			    dialog_clear();
			    goto draw;
			}
		    }
		    status[scroll + choice] = ditems[scroll + choice].checked ?
			ditems[scroll + choice].checked(&ditems[scroll + choice]) : FALSE;
		    lbra = ditems[scroll + choice].lbra;
		    rbra = ditems[scroll + choice].rbra;
		    mark = ditems[scroll + choice].mark;
		}
		else
		    status[scroll + choice] = !status[scroll + choice];
		wmove(list, choice, check_x);
		wattrset(list, check_selected_attr);
		if (!lbra)
		    lbra = '[';
		if (!rbra)
		    rbra = ']';
		if (!mark)
		    mark = 'X';
		wprintw(list, "%c%c%c", lbra, status[scroll + choice] ? mark : ' ', rbra);
		wmove(list, old_y, old_x);  /* Restore cursor to previous position */
		wrefresh(list);
		continue;    /* wait for another key press */
	    }
	    
	    if (i != choice) {
		/* De-highlight current item */
		getyx(dialog, cur_y, cur_x);    /* Save cursor position */
		print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1],
			   status[scroll + choice], choice, FALSE, DREF(ditems, scroll + choice), list_width, item_x, check_x);
		
		/* Highlight new item */
		choice = i;
		print_item(list, items[(scroll + choice) * 3], items[(scroll + choice) * 3 + 1], status[scroll + choice], choice, TRUE, DREF(ditems, scroll + choice), list_width, item_x, check_x);
		wmove(list, choice, check_x+1);	  /* Restore cursor to previous position */
		wrefresh(list);
	    }
	    continue;    /* wait for another key press */
	}
	
	switch (key) {
	case KEY_PPAGE:	/* can we go up? */
	    if (scroll > height - 4)
		scroll -= (height-4);
	    else
		scroll = 0;
	    redraw_menu = TRUE;
	    if (!onlist) {
		onlist = 1;
		button = 0;
	    }
	    break;
	    
	case KEY_NPAGE:      /* can we go down a full page? */
	    if (scroll + list_height >= item_no-1 - list_height) {
		scroll = item_no - list_height;
		if (scroll < 0)
		    scroll = 0;
	    }
	    else
		scroll += list_height;
	    redraw_menu = TRUE;
	    if (!onlist) {
 		onlist = 1;
		button = 0;
	    }
	    break;
	    
	case KEY_HOME:      /* go to the top */
	    scroll = 0;
	    choice = 0;
	    redraw_menu = TRUE;
	    cursor_reset = TRUE;
	    onlist = 1;
	    break;
	    
	case KEY_END:      /* Go to the bottom */
	    scroll = item_no - list_height;
	    if (scroll < 0)
		scroll = 0;
	    choice = max_choice - 1;
	    redraw_menu = TRUE;
	    cursor_reset = TRUE;
	    onlist = 1;
	    break;
	    
	case TAB:
	case KEY_BTAB:
	    /* move to next component */
	    if (onlist) {       /* on list, next is ok button */
		onlist = 0;
		if (ditems && result) {
		    print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
		    print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
		    ok_space = 1;
		    cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6;
		}
		else {
		    print_button(dialog, "Cancel", y, x + 14, button);
		    print_button(dialog, "  OK  ", y, x, !button);
		    ok_space = 3;
		    cancel_space = 15;
		}
		if (button)
		    wmove(dialog, y, x + cancel_space);
		else
		    wmove(dialog, y, x + ok_space);
		wrefresh(dialog);
		break;
	    }
	    else if (button) {     /* on cancel button, next is list */
		button = 0;
		onlist = 1;
		redraw_menu = TRUE;
		break; 
	    }
	    /* on ok button, next is cancel button, same as left/right case */

	case KEY_LEFT:
	case KEY_RIGHT:
	    onlist = 0;
	    button = !button;
	    if (ditems && result) {
		print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
		print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ?  ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
		ok_space = 1;
		cancel_space = strlen(ditems[OK_BUTTON].prompt) + 6;
	    }
	    else {
		print_button(dialog, "Cancel", y, x + 14, button);
		print_button(dialog, "  OK  ", y, x, !button);
		ok_space = 3;
		cancel_space = 15;
	    }
	    if (button)
		wmove(dialog, y, x + cancel_space);
	    else
		wmove(dialog, y, x + ok_space);
	    wrefresh(dialog);
	    break;

	case ' ':
	case '\n':
	case '\r':
	    if (!onlist) {
		if (ditems) {
		    if (result && ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire) {
			int st;
			WINDOW *save = dupwin(newscr);

			st = ditems[button ? CANCEL_BUTTON : OK_BUTTON].fire(&ditems[button ? CANCEL_BUTTON : OK_BUTTON]);
			if (st & DITEM_RESTORE) {
			    touchwin(save);
			    wrefresh(save);
			}
			delwin(save);
			if (st == DITEM_FAILURE)
			continue;
		    }
		}
		else if (result) {
		    *result = '\0';
		    for (i = 0; i < item_no; i++) {
			if (status[i]) {
			    strcat(result, items[i*3]);
			    strcat(result, "\n");
			}
		    }
		}
		rval = button;
		key = ESC;	/* Bail out! */
		break;
	    }
	    
	    /* Let me outta here! */
	case ESC:
	    rval = -1;
	    break;
	    
	    /* Help! */
	case KEY_F(1):
	case '?':
	    display_helpfile();
	    break;
	}
	
	if (redraw_menu) {
	    getyx(list, old_y, old_x);
	    wclear(list);

    	    /*
	     * Re-draw a box around the list items.  It is required
	     * if amount of list items is smaller than height of listbox.
	     * Otherwise un-redrawn field will be filled with default
	     * screen attributes instead of dialog attributes.
	     */
	    draw_box(dialog, box_y, box_x, list_height + 2, list_width + 2, menubox_border_attr, menubox_attr);

	    for (i = 0; i < max_choice; i++)
		print_item(list, items[(scroll + i) * 3], items[(scroll + i) * 3 + 1], status[scroll + i], i, i == choice, DREF(ditems, scroll + i), list_width, item_x, check_x);
	    print_arrows(dialog, scroll, list_height, item_no, box_x, box_y, check_x + 4, cur_x, cur_y);

	    /* redraw buttons to fix highlighting */
	    if (ditems && result) {
		print_button(dialog, ditems[CANCEL_BUTTON].prompt, y, x + strlen(ditems[OK_BUTTON].prompt) + 5, ditems[CANCEL_BUTTON].checked ? ditems[CANCEL_BUTTON].checked(&ditems[CANCEL_BUTTON]) : button);
		print_button(dialog, ditems[OK_BUTTON].prompt, y, x, ditems[OK_BUTTON].checked ? ditems[OK_BUTTON].checked(&ditems[OK_BUTTON]) : !button);
	    }
	    else {
		print_button(dialog, "Cancel", y, x + 14, button);
		print_button(dialog, "  OK  ", y, x, !button);
	    }
	    wnoutrefresh(dialog);
	    if (cursor_reset) {
		wmove(list, choice, check_x+1);
		cursor_reset = FALSE;
	    }
	    else {
		wmove(list, old_y, old_x);
	    }
	    wrefresh(list);
	    redraw_menu = FALSE;
	}
    }
    delwin(list);
    delwin(dialog);
    return rval;
}
Пример #3
0
Файл: alias.c Проект: wfp5p/elm
static int alias_help(void)
{
/*
 *	Help section for the alias menu...
 *
 *	Return non-0 if main part of screen overwritten, else 0
 */

	int  ch;
	int  redraw=0;
	char *alias_prompt;


	if (mini_menu)
		alias_prompt = catgets(elm_msg_cat, AliasesSet, AliasesShortKey,
			"Key: ");
	else
		alias_prompt = catgets(elm_msg_cat, AliasesSet, AliasesLongKey,
			"Key you want help for: ");

	MoveCursor(LINES-3, 0);
	CleartoEOS();
	if (mini_menu) {
	  CenterLine(LINES-3, catgets(elm_msg_cat, AliasesSet, AliasesKeyMenu,
 "Press the key you want help for, '?' for a key list, or '.' to exit help"));
	}

	lower_prompt(alias_prompt);

	while ((ch = ReadCh()) != '.') {
	  switch(ch) {
	    case '?' : display_helpfile("alias");
		       redraw++;
		       return(redraw);

	    case '$': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpDollar,
"$ = Force resynchronization of aliases, processing additions and deletions."));
		      break;

	    case '/': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpSlash,
			"/ = Search for specified name or alias in list."));
		      break;

	    case RETURN:
	    case LINE_FEED:
	    case ' ':
	    case 'v': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpv,
	    "v = View the address for the currently selected alias."));
		      break;

	    case 'a': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpa,
	    "a = Add (return) address of current message to alias database."));
		      break;

	    case 'c': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpc,
"c = Change current user alias, modifying alias database at next resync."));
		      break;

	    case 'd': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpd,
	    "d = Mark the current alias for deletion from alias database."));
		      break;

	    case ctrl('D'): show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpCtrlD,
	    "^D = Mark for deletion user aliases matching specified pattern."));
		      break;

	    case 'e': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpe,
	    "e = Edit the alias text file directly (will run newalias)."));
		      break;

	    case 'f': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpf,
		"f = Display fully expanded address of current alias."));
		      break;

	    case 'l': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpl,
	    "l = Limit displayed aliases on the specified criteria."));
		      break;

	    case ctrl('L'): show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpCtrlL,
		      "^L = Rewrite the screen."));
	    	      break;

	    case 'm': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpm,
	    "m = Send mail to the current or tagged aliases."));
		      break;

	    case 'n': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpn,
"n = Add a new user alias, adding to alias database at next resync."));
		      break;

	    case 'r':
	    case 'q':
	    case 'i': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpi,
		      "r,q,i = Return from alias menu (with prompting)."));
	   	      break;

	    case 'R':
	    case 'Q':
	    case 'I': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpQ,
		      "R,Q,I = Return from alias menu (no prompting)."));
	   	      break;

	    case 't': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpt,
		      "t = Tag current alias for further operations."));
		      break;

	    case 'T': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpT,
		      "T = Tag current alias and go to next alias."));
		      break;

	    case ctrl('T'): show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpCtrlT,
	    "^T = Tag aliases matching specified pattern."));
		      break;

	    case 'u': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpu,
	    "u = Unmark the current alias for deletion from alias database."));
		      break;

	    case ctrl('U'): show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpCtrlU,
"^U = Mark for undeletion user aliases matching specified pattern."));
		      break;

	    case 'x':
	    case 'X': show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpX,
	    "x = Exit from alias menu, abandoning any pending deletions."));
	   	      break;

	    default : show_error(catgets(elm_msg_cat, AliasesSet, AliasesHelpNoHelp,
			"That key isn't used in this section."));
	   	      break;
	  }
	  lower_prompt(alias_prompt);
	}

	/* Remove help lines */
	MoveCursor(LINES-3, 0);	CleartoEOS();
	return(redraw);
}
Пример #4
0
/*
 * Display text from a file in a dialog box.
 */
int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width)
{
  int i, x, y, cur_x, cur_y, fpos, key = 0, dir, temp, temp1;
#ifdef HAVE_NCURSES
  int passed_end;
#endif
  unsigned char search_term[MAX_LEN+1], *tempptr, *found;
  WINDOW *dialog, *text;

  if (height < 0 || width < 0) {
    fprintf(stderr, "\nAutosizing is impossible in dialog_textbox().\n");
    return(-1);
  }

  search_term[0] = '\0';    /* no search term entered yet */

  /* Open input file for reading */
  if ((fd = open(file, O_RDONLY)) == -1) {
    fprintf(stderr, "\nCan't open input file <%s>in dialog_textbox().\n", file);
    return(-1);
  }
  /* Get file size. Actually, 'file_size' is the real file size - 1,
     since it's only the last byte offset from the beginning */
  if ((file_size = lseek(fd, 0, SEEK_END)) == -1) {
    fprintf(stderr, "\nError getting file size in dialog_textbox().\n");
    return(-1);
  }
  /* Restore file pointer to beginning of file after getting file size */
  if (lseek(fd, 0, SEEK_SET) == -1) {
    fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
    return(-1);
  }
  /* Allocate space for read buffer */
  if ((buf = malloc(BUF_SIZE+1)) == NULL) {
    endwin();
    fprintf(stderr, "\nCan't allocate memory in dialog_textbox().\n");
    exit(-1);
  }
  if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
    fprintf(stderr, "\nError reading file in dialog_textbox().\n");
    return(-1);
  }
  buf[bytes_read] = '\0';    /* mark end of valid data */
  page = buf;    /* page is pointer to start of page to be displayed */

  if (width > COLS)
	width = COLS;
  if (height > LINES)
	height = LINES;
  /* center dialog box on screen */
  x = DialogX ? DialogX : (COLS - width)/2;
  y = DialogY ? DialogY : (LINES - height)/2;

#ifdef HAVE_NCURSES
  if (use_shadow)
    draw_shadow(stdscr, y, x, height, width);
#endif
  dialog = newwin(height, width, y, x);
  if (dialog == NULL) {
    endwin();
    fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
    exit(1);
  }
  keypad(dialog, TRUE);

  /* Create window for text region, used for scrolling text */
/*  text = newwin(height-4, width-2, y+1, x+1); */
  text = subwin(dialog, height-4, width-2, y+1, x+1);
  if (text == NULL) {
    endwin();
    fprintf(stderr, "\nsubwin(dialog,%d,%d,%d,%d) failed, maybe wrong dims\n", height-4,width-2,y+1,x+1);
    exit(1);
  }
  keypad(text, TRUE);

  draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);

  wattrset(dialog, border_attr);
  wmove(dialog, height-3, 0);
  waddch(dialog, ACS_LTEE);
  for (i = 0; i < width-2; i++)
    waddch(dialog, ACS_HLINE);
  wattrset(dialog, dialog_attr);
  waddch(dialog, ACS_RTEE);
  wmove(dialog, height-2, 1);
  for (i = 0; i < width-2; i++)
    waddch(dialog, ' ');

  if (title != NULL) {
    wattrset(dialog, title_attr);
    wmove(dialog, 0, (width - strlen(title))/2 - 1);
    waddch(dialog, ' ');
    waddstr(dialog, title);
    waddch(dialog, ' ');
  }
  display_helpline(dialog, height-1, width);

  print_button(dialog, "  OK  ", height-2, width/2-6, TRUE);
  wnoutrefresh(dialog);
  getyx(dialog, cur_y, cur_x);    /* Save cursor position */

  /* Print first page of text */
  attr_clear(text, height-4, width-2, dialog_attr);
  print_page(text, height-4, width-2);
  print_position(dialog, height, width);
  wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
  wrefresh(dialog);

  while ((key != ESC) && (key != '\n') && (key != '\r') && (key != ' ')) {
    key = wgetch(dialog);
    switch (key) {
      case 'E':    /* Exit */
      case 'e':
        delwin(dialog);
        free(buf);
        close(fd);
        return 0;
      case 'g':    /* First page */
      case KEY_HOME:
        if (!begin_reached) {
          begin_reached = 1;
          /* First page not in buffer? */
          if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
            endwin();
            fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
            exit(-1);
          }
          if (fpos > bytes_read) {    /* Yes, we have to read it in */
            if (lseek(fd, 0, SEEK_SET) == -1) {
              endwin();
              fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
              exit(-1);
            }
            if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
              endwin();
              fprintf(stderr, "\nError reading file in dialog_textbox().\n");
              exit(-1);
            }
            buf[bytes_read] = '\0';
          }
          page = buf;
          print_page(text, height-4, width-2);
          print_position(dialog, height, width);
          wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
          wrefresh(dialog);
        }
        break;
      case 'G':    /* Last page */
#ifdef HAVE_NCURSES
      case KEY_END:
#endif
        end_reached = 1;
        /* Last page not in buffer? */
        if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
          endwin();
          fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
          exit(-1);
        }
        if (fpos < file_size) {    /* Yes, we have to read it in */
          if (lseek(fd, -BUF_SIZE, SEEK_END) == -1) {
            endwin();
            fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
            exit(-1);
          }
          if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
            endwin();
            fprintf(stderr, "\nError reading file in dialog_textbox().\n");
            exit(-1);
          }
          buf[bytes_read] = '\0';
        }
        page = buf + bytes_read;
        back_lines(height-4);
        print_page(text, height-4, width-2);
        print_position(dialog, height, width);
        wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
        wrefresh(dialog);
        break;
      case 'K':    /* Previous line */
      case 'k':
      case '\020':	/* ^P */
      case KEY_UP:
        if (!begin_reached) {
          back_lines(page_length+1);
#ifdef HAVE_NCURSES
          /* We don't call print_page() here but use scrolling to ensure
             faster screen update. However, 'end_reached' and 'page_length'
             should still be updated, and 'page' should point to start of
             next page. This is done by calling get_line() in the following
             'for' loop. */
          scrollok(text, TRUE);
          wscrl(text, -1);    /* Scroll text region down one line */
          scrollok(text, FALSE);
          page_length = 0;
          passed_end = 0;
          for (i = 0; i < height-4; i++) {
            if (!i) {
              print_line(text, 0, width-2);    /* print first line of page */
              wnoutrefresh(text);
            }
            else
              get_line();    /* Called to update 'end_reached' and 'page' */
            if (!passed_end)
              page_length++;
            if (end_reached && !passed_end)
              passed_end = 1;
          }
#else
          print_page(text, height-4, width-2);
#endif
          print_position(dialog, height, width);
          wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
          wrefresh(dialog);
        }
        break;
      case 'B':    /* Previous page */
      case 'b':
      case KEY_PPAGE:
        if (!begin_reached) {
          back_lines(page_length + height-4);
          print_page(text, height-4, width-2);
          print_position(dialog, height, width);
          wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
          wrefresh(dialog);
        }
        break;
      case 'J':    /* Next line */
      case 'j':
      case '\016':	/* ^N */
      case KEY_DOWN:
        if (!end_reached) {
          begin_reached = 0;
          scrollok(text, TRUE);
          scroll(text);    /* Scroll text region up one line */
          scrollok(text, FALSE);
          print_line(text, height-5, width-2);
#ifndef HAVE_NCURSES
          wmove(text, height-5, 0);
          waddch(text, ' ');
          wmove(text, height-5, width-3);
          waddch(text, ' ');
#endif
          wnoutrefresh(text);
          print_position(dialog, height, width);
          wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
          wrefresh(dialog);
        }
        break;
      case 'F':    /* Next page */
      case 'f':
      case KEY_NPAGE:
        if (!end_reached) {
          begin_reached = 0;
          print_page(text, height-4, width-2);
          print_position(dialog, height, width);
          wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
          wrefresh(dialog);
        }
        break;
      case '0':    /* Beginning of line */
      case 'H':    /* Scroll left */
      case 'h':
      case KEY_LEFT:
        if (hscroll > 0) {
          if (key == '0')
            hscroll = 0;
          else
            hscroll--;
          /* Reprint current page to scroll horizontally */
          back_lines(page_length);
          print_page(text, height-4, width-2);
          wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
          wrefresh(dialog);
        }
        break;
      case 'L':    /* Scroll right */
      case 'l':
      case KEY_RIGHT:
        if (hscroll < MAX_LEN) {
          hscroll++;
          /* Reprint current page to scroll horizontally */
          back_lines(page_length);
          print_page(text, height-4, width-2);
          wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
          wrefresh(dialog);
        }
        break;
      case '/':    /* Forward search */
      case 'n':    /* Repeat forward search */
      case '?':    /* Backward search */
      case 'N':    /* Repeat backward search */
        /* set search direction */
        dir = (key == '/' || key == 'n') ? 1 : 0;
        if (dir ? !end_reached : !begin_reached) {
          if (key == 'n' || key == 'N') {
            if (search_term[0] == '\0') {    /* No search term yet */
              fprintf(stderr, "\a");    /* beep */
              break;
            }
	  }
          else    /* Get search term from user */
            if (get_search_term(text, search_term, height-4, width-2) == -1) {
              /* ESC pressed in get_search_term(). Reprint page to clear box */
              wattrset(text, dialog_attr);
              back_lines(page_length);
              print_page(text, height-4, width-2);
              wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
              wrefresh(dialog);
              break;
            }
          /* Save variables for restoring in case search term can't be found */
          tempptr = page;
          temp = begin_reached;
          temp1 = end_reached;
          if ((fpos = lseek(fd, 0, SEEK_CUR)) == -1) {
            endwin();
            fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
            exit(-1);
          }
          fpos -= bytes_read;
          /* update 'page' to point to next (previous) line before
             forward (backward) searching */
          back_lines(dir ? page_length-1 : page_length+1);
          found = NULL;
          if (dir)    /* Forward search */
            while((found = strstr(get_line(), search_term)) == NULL) {
              if (end_reached)
                break;
	    }
          else    /* Backward search */
            while((found = strstr(get_line(), search_term)) == NULL) {
              if (begin_reached)
                break;
              back_lines(2);
            }
          if (found == NULL) {    /* not found */
            fprintf(stderr, "\a");    /* beep */
            /* Restore program state to that before searching */
            if (lseek(fd, fpos, SEEK_SET) == -1) {
              endwin();
              fprintf(stderr, "\nError moving file pointer in dialog_textbox().\n");
              exit(-1);
            }
            if ((bytes_read = read(fd, buf, BUF_SIZE)) == -1) {
              endwin();
              fprintf(stderr, "\nError reading file in dialog_textbox().\n");
              exit(-1);
            }
            buf[bytes_read] = '\0';
            page = tempptr;
            begin_reached = temp;
            end_reached = temp1;
            /* move 'page' to point to start of current page in order to
               re-print current page. Note that 'page' always points to
               start of next page, so this is necessary */
            back_lines(page_length);
          }
          else    /* Search term found */
            back_lines(1);
          /* Reprint page */
          wattrset(text, dialog_attr);
          print_page(text, height-4, width-2);
          if (found != NULL)
            print_position(dialog, height, width);
          wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
          wrefresh(dialog);
        }
        else    /* no need to find */
          fprintf(stderr, "\a");    /* beep */
        break;
      case ESC:
        break;
    case KEY_F(1):
	display_helpfile();
	break;
    }
  }

  delwin(dialog);
  free(buf);
  close(fd);
  return (key == ESC ? -1 : 0);
}