diff options
author | ache <ache@FreeBSD.org> | 1995-02-15 19:44:08 +0000 |
---|---|---|
committer | ache <ache@FreeBSD.org> | 1995-02-15 19:44:08 +0000 |
commit | 8606846519fea95655a87c1758e86ea3e8bffc34 (patch) | |
tree | a7743d34a6549d3bf5ac9aa482d97aaadd19fe2a | |
parent | c89046c5551c9d22af39898dd39354fd4f5cae44 (diff) | |
download | FreeBSD-src-8606846519fea95655a87c1758e86ea3e8bffc34.zip FreeBSD-src-8606846519fea95655a87c1758e86ea3e8bffc34.tar.gz |
file selector, helpline, helpfile and more, with my fixes
Submitted by: wmbfmk@urc.tue.nl
-rw-r--r-- | gnu/lib/libdialog/CHANGES | 9 | ||||
-rw-r--r-- | gnu/lib/libdialog/Makefile | 6 | ||||
-rw-r--r-- | gnu/lib/libdialog/TODO | 36 | ||||
-rw-r--r-- | gnu/lib/libdialog/checklist.c | 6 | ||||
-rw-r--r-- | gnu/lib/libdialog/dialog.h | 17 | ||||
-rw-r--r-- | gnu/lib/libdialog/dialog.priv.h | 11 | ||||
-rw-r--r-- | gnu/lib/libdialog/dir.c | 549 | ||||
-rw-r--r-- | gnu/lib/libdialog/dir.h | 36 | ||||
-rw-r--r-- | gnu/lib/libdialog/fselect.c | 242 | ||||
-rw-r--r-- | gnu/lib/libdialog/help.c | 155 | ||||
-rw-r--r-- | gnu/lib/libdialog/inputbox.c | 6 | ||||
-rw-r--r-- | gnu/lib/libdialog/kernel.c | 1 | ||||
-rw-r--r-- | gnu/lib/libdialog/lineedit.c | 12 | ||||
-rw-r--r-- | gnu/lib/libdialog/menubox.c | 86 | ||||
-rw-r--r-- | gnu/lib/libdialog/msgbox.c | 235 | ||||
-rw-r--r-- | gnu/lib/libdialog/notify.c | 64 | ||||
-rw-r--r-- | gnu/lib/libdialog/prgbox.c | 1 | ||||
-rw-r--r-- | gnu/lib/libdialog/radiolist.c | 6 | ||||
-rw-r--r-- | gnu/lib/libdialog/textbox.c | 7 | ||||
-rw-r--r-- | gnu/lib/libdialog/ui_objects.c | 735 | ||||
-rw-r--r-- | gnu/lib/libdialog/ui_objects.h | 109 | ||||
-rw-r--r-- | gnu/lib/libdialog/yesno.c | 6 |
22 files changed, 2313 insertions, 22 deletions
diff --git a/gnu/lib/libdialog/CHANGES b/gnu/lib/libdialog/CHANGES new file mode 100644 index 0000000..1467a0e --- /dev/null +++ b/gnu/lib/libdialog/CHANGES @@ -0,0 +1,9 @@ +- Added two variables to call to dialog_menu() to save the position + in the menu when choosing a menu-option. + +- Added dialog_fselect(), implements a fileselector dialog +- Added ui-interface objects: Stringobject, Listobject and Buttonobject. + The fileselector dialog was built using these objects. +- changed dialog_menu to use PGUP and PGDN +- Added dialog_mesgbox, which display text given in a char buffer. +- diff --git a/gnu/lib/libdialog/Makefile b/gnu/lib/libdialog/Makefile index 5562415..236b71c 100644 --- a/gnu/lib/libdialog/Makefile +++ b/gnu/lib/libdialog/Makefile @@ -1,13 +1,15 @@ # Makefile for libdialog -# $Id: Makefile,v 1.5 1994/10/28 03:08:14 ache Exp $ +# $Id: Makefile,v 1.6 1994/10/28 05:36:38 jkh Exp $ LIB= dialog SRCS= kernel.c rc.c checklist.c inputbox.c menubox.c msgbox.c \ - lineedit.c radiolist.c textbox.c yesno.c prgbox.c raw_popen.c + lineedit.c radiolist.c textbox.c yesno.c prgbox.c raw_popen.c \ + fselect.c ui_objects.c dir.c notify.c help.c CFLAGS+= -I${.CURDIR} -Wall -Wstrict-prototypes -DLOCALE LDADD+= -lncurses -lmytinfo +DPADD+= ${LIBNCURSES} ${LIBMYTINFO} beforeinstall: -cd ${.CURDIR}; cmp -s dialog.h ${DESTDIR}/usr/include/dialog.h || \ diff --git a/gnu/lib/libdialog/TODO b/gnu/lib/libdialog/TODO new file mode 100644 index 0000000..132a4a4 --- /dev/null +++ b/gnu/lib/libdialog/TODO @@ -0,0 +1,36 @@ +- cut off names in the listbox that are to long +done 27Jan95 + The current behaviour may not be desirable. When browsing through + long names these, when highlighted, will be shown with the first + characters cut off, when not highlighted the last characters will + be cut off. + +- look at behaviour of TAB key when browsing through directories. +done 28Jan95 + +- make sure the full name of the directory is written to the + "Directory:"-box +done 28Jan95 + +- mark current selections in listbox when initializing the listobject +Idontknow +- test and use Notify() when checking for error conditions +ok +- test overall +- adapt color of buttons when changing focus to the button. +done 28Jan95 +- add shade to dialog_fselect()-window +done 29Jan95 +- add (nn%) indication to lists. +done 30Jan95 +- add use_helpfile() +done 13Feb95 +- add use_helpline() + +NOTE: apparently there is a bug (or a strange interaction between pkg_manage +and dialog_textbox) in dialog_textbox. When I use this routine to display +the helpfile in display_helpfile() the program gets mysterious segmentation +faults and bus errors. +I now use dialog_mesgbox, after I have read the file into a buffer. + + diff --git a/gnu/lib/libdialog/checklist.c b/gnu/lib/libdialog/checklist.c index 964a1b6..c19f7c2 100644 --- a/gnu/lib/libdialog/checklist.c +++ b/gnu/lib/libdialog/checklist.c @@ -147,6 +147,8 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in waddstr(dialog, "(+)"); } + display_helpline(dialog, height-1, width); + x = width/2-11; y = height-2; print_button(dialog, "Cancel", y, x+14, FALSE); @@ -349,6 +351,10 @@ int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, in return button; case ESC: break; + case KEY_F(1): + case '?': + display_helpfile(); + break; } } diff --git a/gnu/lib/libdialog/dialog.h b/gnu/lib/libdialog/dialog.h index 35f6f35..82d0100 100644 --- a/gnu/lib/libdialog/dialog.h +++ b/gnu/lib/libdialog/dialog.h @@ -36,6 +36,14 @@ #define VERSION "0.4" #define MAX_LEN 2048 +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef FALSE +#define FALSE (0) +#endif + + /* * Attribute names */ @@ -88,7 +96,7 @@ int dialog_yesno(unsigned char *title, unsigned char *prompt, int height, int wi int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, int width, int pause, int use_shell); int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause); int dialog_textbox(unsigned char *title, unsigned char *file, int height, int width); -int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result); +int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result, int *ch, int *sc); int dialog_checklist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result); int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, int width, int list_height, int item_no, unsigned char **items, unsigned char *result); int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int width, unsigned char *result); @@ -97,3 +105,10 @@ void dialog_clear(void); void dialog_update(void); void init_dialog(void); void end_dialog(void); + +/* Additions to libdialog */ +char *dialog_fselect(char *dir, char *fmask); +void dialog_notify(char *msg); +int dialog_mesgbox(unsigned char *title, unsigned char *prompt, int height, int width); +void use_helpfile(char *helpfile); +void use_helpline(char *helpline); diff --git a/gnu/lib/libdialog/dialog.priv.h b/gnu/lib/libdialog/dialog.priv.h index f21a4e8..e09bd45 100644 --- a/gnu/lib/libdialog/dialog.priv.h +++ b/gnu/lib/libdialog/dialog.priv.h @@ -39,8 +39,17 @@ #define ESC 27 #define TAB 9 #define BUF_SIZE (10*1024) + +#ifndef MIN #define MIN(x,y) (x < y ? x : y) +#endif +#ifndef MAX #define MAX(x,y) (x > y ? x : y) +#endif + +#ifndef ctrl +#define ctrl(a) ((a) - 'a' + 1) +#endif #ifndef HAVE_NCURSES #ifndef ACS_ULCORNER @@ -159,3 +168,5 @@ void print_autowrap(WINDOW *win, unsigned char *prompt, int height, int width, i void print_button(WINDOW *win, unsigned char *label, int y, int x, int selected); FILE *raw_popen(const char *program, char * const *argv, const char *type); int raw_pclose(FILE *iop); +void display_helpfile(void); +void display_helpline(WINDOW *w, int y, int width); diff --git a/gnu/lib/libdialog/dir.c b/gnu/lib/libdialog/dir.c new file mode 100644 index 0000000..2fa5835 --- /dev/null +++ b/gnu/lib/libdialog/dir.c @@ -0,0 +1,549 @@ + +/**************************************************************************** + * + * Program: dir.c + * Author: Marc van Kempen + * desc: Directory routines, sorting and reading + * + * Copyright (c) 1995, Marc van Kempen + * + * All rights reserved. + * + * This software may be used, modified, copied, distributed, and + * sold, in both source and binary form provided that the above + * copyright and these terms are retained, verbatim, as the first + * lines of this file. Under no circumstances is the author + * responsible for the proper functioning of this software, nor does + * the author assume any responsibility for damages incurred with + * its use. + * + ****************************************************************************/ + +#include <sys/types.h> +#include <sys/stat.h> + +#if !defined sgi +#include <sys/dir.h> +#endif +#if defined __sun__ +#include <sys/dirent.h> +#endif +#if defined sgi +#include <dirent.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <fnmatch.h> +#include <sys/param.h> +#include "dir.h" + +/**************************************************************************** + * + * local prototypes + * + ****************************************************************************/ + +void toggle_dotfiles(void); +int show_dotfiles(void); +int dir_alphasort(const void *d1, const void *d2); +int dir_sizesort(const void *d1, const void *d2); +int dir_datesort(const void *d1, const void *d2); +int dir_extsort(const void *d1, const void *d2); + +/**************************************************************************** + * + * global variables + * + ****************************************************************************/ + + +/* This is user-selectable, I've set them fixed for now however */ + +void *_sort_func = dir_alphasort; +static int _showdotfiles = TRUE; + +/**************************************************************************** + * + * Functions + * + ****************************************************************************/ + +int +dir_select_nd( +#if defined __linux__ + const struct dirent *d +#else + struct dirent *d +#endif +) +/* + * desc: allways include a directory entry <d>, except + * for the current directory and other dot-files + * keep '..' however. + * pre: <d> points to a dirent + * post: returns TRUE if d->d_name != "." else FALSE + */ +{ + if (strcmp(d->d_name, ".")==0 || + (d->d_name[0] == '.' && strlen(d->d_name) > 1 && d->d_name[1] != '.')) { + return(FALSE); + } else { + return(TRUE); + } +}/* dir_select_nd() */ + + +int +dir_select( +#ifdef __linux__ + const struct dirent *d +#else + struct dirent *d +#endif +) +/* + * desc: allways include a directory entry <d>, except + * for the current directory + * pre: <d> points to a dirent + * post: returns TRUE if d->d_name != "." else FALSE + */ +{ + if (strcmp(d->d_name, ".")==0) { /* don't include the current directory */ + return(FALSE); + } else { + return(TRUE); + } +} /* dir_select() */ + +int +dir_select_root_nd( +#ifdef __linux__ + const struct dirent *d +#else + struct dirent *d +#endif +) +/* + * desc: allways include a directory entry <d>, except + * for the current directory and the parent directory. + * Also skip any other dot-files. + * pre: <d> points to a dirent + * post: returns TRUE if d->d_name[0] != "." else FALSE + */ +{ + if (d->d_name[0] == '.') { /* don't include the current directory */ + return(FALSE); /* nor the parent directory */ + } else { + return(TRUE); + } +} /* dir_select_root_nd() */ + + +int +dir_select_root( +#ifdef __linux__ + const struct dirent *d +#else + struct dirent *d +#endif +) +/* + * desc: allways include a directory entry <d>, except + * for the current directory and the parent directory + * pre: <d> points to a dirent + * post: returns TRUE if d->d_name[0] != "." else FALSE + */ +{ + if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) { + return(FALSE); + } else { + return(TRUE); + } +}/* dir_select_root() */ + + +#ifdef NO_ALPHA_SORT +int +alphasort(const void *d1, const void *d2) +/* + * desc: a replacement for what should be in the library + */ +{ + return(strcmp(((struct dirent *) d1)->d_name, + ((struct dirent *) d2)->d_name)); +} /* alphasort() */ +#endif + +int +dir_alphasort(const void *d1, const void *d2) +/* + * desc: compare d1 and d2, but put directories always first + * put '..' always on top + * + */ +{ + DirList *f1 = ((DirList *) d1), + *f2 = ((DirList *) d2); + struct stat *s1 = &(f1->filestatus); + struct stat *s2 = &(f2->filestatus); + + /* check for '..' */ + if (strcmp(((DirList *) d1)->filename, "..") == 0) { + return(-1); + } + if (strcmp(((DirList *) d2)->filename, "..") == 0) { + return(1); + } + + /* put directories first */ + if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) { + return(strcmp(f1->filename, f2->filename)); + }; + if (s1->st_mode & S_IFDIR) { + return(-1); + } + if (s2->st_mode & S_IFDIR) { + return(1); + } + return(strcmp(f1->filename, f2->filename)); + +} /* dir_alphasort() */ + + +int +dir_sizesort(const void *d1, const void *d2) +/* + * desc: compare d1 and d2, but put directories always first + * + */ +{ + DirList *f1 = ((DirList *) d1), + *f2 = ((DirList *) d2); + struct stat *s1 = &(f1->filestatus); + struct stat *s2 = &(f2->filestatus); + + /* check for '..' */ + if (strcmp(((DirList *) d1)->filename, "..") == 0) { + return(-1); + } + if (strcmp(((DirList *) d2)->filename, "..") == 0) { + return(1); + } + + /* put directories first */ + if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) { + return(s1->st_size < s2->st_size ? + -1 + : + s1->st_size >= s2->st_size); + }; + if (s1->st_mode & S_IFDIR) { + return(-1); + } + if (s2->st_mode & S_IFDIR) { + return(1); + } + return(s1->st_size < s2->st_size ? + -1 + : + s1->st_size >= s2->st_size); + +} /* dir_sizesort() */ + +int +dir_datesort(const void *d1, const void *d2) +/* + * desc: compare d1 and d2 on date, but put directories always first + */ +{ + DirList *f1 = ((DirList *) d1), + *f2 = ((DirList *) d2); + struct stat *s1 = &(f1->filestatus); + struct stat *s2 = &(f2->filestatus); + + + /* check for '..' */ + if (strcmp(((DirList *) d1)->filename, "..") == 0) { + return(-1); + } + if (strcmp(((DirList *) d2)->filename, "..") == 0) { + return(1); + } + + /* put directories first */ + if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) { + return(s1->st_mtime < s2->st_mtime ? + -1 + : + s1->st_mtime >= s2->st_mtime); + }; + if (s1->st_mode & S_IFDIR) { + return(-1); + } + if (s2->st_mode & S_IFDIR) { + return(1); + } + return(s1->st_mtime < s2->st_mtime ? + -1 + : + s1->st_mtime >= s2->st_mtime); + +} /* dir_datesort() */ + + +int +null_strcmp(char *s1, char *s2) +/* + * desc: compare strings allowing NULL pointers + */ +{ + if ((s1 == NULL) && (s2 == NULL)) { + return(0); + } + if (s1 == NULL) { + return(-1); + } + if (s2 == NULL) { + return(1); + } + return(strcmp(s1, s2)); +} /* null_strcmp() */ + + +int +dir_extsort(const void *d1, const void *d2) +/* + * desc: compare d1 and d2 on extension, but put directories always first + * extension = "the characters after the last dot in the filename" + * pre: d1 and d2 are pointers to DirList type records + * post: see code + */ +{ + DirList *f1 = ((DirList *) d1), + *f2 = ((DirList *) d2); + struct stat *s1 = &(f1->filestatus); + struct stat *s2 = &(f2->filestatus); + char *ext1, *ext2; + int extf, ret; + + + /* check for '..' */ + if (strcmp(((DirList *) d1)->filename, "..") == 0) { + return(-1); + } + if (strcmp(((DirList *) d2)->filename, "..") == 0) { + return(1); + } + + + /* find the first extension */ + + ext1 = f1->filename + strlen(f1->filename); + extf = FALSE; + while (!extf && (ext1 > f1->filename)) { + extf = (*--ext1 == '.'); + } + if (!extf) { + ext1 = NULL; + } else { + ext1++; + } + /* ext1 == NULL if there's no "extension" else ext1 points */ + /* to the first character of the extension string */ + + /* find the second extension */ + + ext2 = f2->filename + strlen(f2->filename); + extf = FALSE; + while (!extf && (ext2 > f2->filename)) { + extf = (*--ext2 == '.'); + } + if (!extf) { + ext2 = NULL; + } else { + ext2++; + } + /* idem as for ext1 */ + + if ((s1->st_mode & S_IFDIR) && (s2->st_mode & S_IFDIR)) { + ret = null_strcmp(ext1, ext2); + if (ret == 0) { + return(strcmp(f1->filename, f2->filename)); + } else { + return(ret); + } + }; + if (s1->st_mode & S_IFDIR) { + return(-1); + } + if (s2->st_mode & S_IFDIR) { + return(1); + } + ret = null_strcmp(ext1, ext2); + if (ret == 0) { + return(strcmp(f1->filename, f2->filename)); + } else { + return(ret); + } + +} /* dir_extsort() */ + + +void +get_dir(char *dirname, char *fmask, DirList **dir, int *n) +/* + * desc: get the files in the current directory + * pre: <dir> == NULL + * post: <dir> contains <n> dir-entries + */ +{ + char cwd[MAXPATHLEN]; + char buf[256]; + struct dirent **dire; + struct stat status; + int i, j, nb; + long d; + + + getcwd(cwd, MAXPATHLEN); + if (strcmp(cwd, "/") == 0) { /* we are in the root directory */ + if (show_dotfiles()) { + *n = scandir(dirname, &dire, dir_select_root, alphasort); + } else { + *n = scandir(dirname, &dire, dir_select_root_nd, alphasort); + } + } else { + if (show_dotfiles()) { + *n = scandir(dirname, &dire, dir_select, alphasort); + } else { + *n = scandir(dirname, &dire, dir_select_nd, alphasort); + } + } + + /* There is the possibility that we have entered a directory */ + /* which we are not allowed to read, scandir thus returning */ + /* -1 for *n. */ + /* Actually I should also check for lack of memory, but I'll */ + /* let my application happily crash if this is the case */ + /* Solution: */ + /* manually insert the parent directory as the only */ + /* directory entry, and return. */ + + if (*n == -1) { + *n = 1; + *dir = (DirList *) malloc(sizeof(DirList)); + strcpy((*dir)[0].filename, ".."); + lstat("..", &status); + (*dir)[0].filestatus = status; + (*dir)[0].link = FALSE; + return; + } + + *dir = (DirList *) malloc( *n * sizeof(DirList) ); + d = 0; + i = 0; + j = 0; + while (j<*n) { + lstat(dire[j]->d_name, &status); + /* check if this file is to be included */ + /* always include directories, the rest is subject to fmask */ + if (S_ISDIR(status.st_mode) + || fnmatch(fmask, dire[j]->d_name, FNM_NOESCAPE) != FNM_NOMATCH) { + strcpy((*dir)[i].filename, dire[j]->d_name); + (*dir)[i].filestatus = status; + if ((S_IFMT & status.st_mode) == S_IFLNK) { /* handle links */ + (*dir)[i].link = TRUE; + stat(dire[j]->d_name, &status); + nb = readlink(dire[j]->d_name, buf, 256); + if (nb == -1) { + printf("get_dir(): Error reading link: %s\n", dire[j]->d_name); + exit(-1); + } else { + (*dir)[i].linkname = malloc(sizeof(char) * nb + 1); + strncpy((*dir)[i].linkname, buf, nb); + (*dir)[i].linkname[nb] = 0; + } + (*dir)[i].filestatus = status; + } else { + (*dir)[i].link = FALSE; + (*dir)[i].linkname = NULL; + } + i++; + } else { + /* skip this entry */ + } + j++; + } + *n = i; + + /* sort the directory with the directory names on top */ + qsort((*dir), *n, sizeof(DirList), _sort_func); + + /* Free the allocated memory */ + for (i=0; i<*n; i++) { + free(dire[i]); + } + free(dire); + + return; +}/* get_dir() */ + + +void +FreeDir(DirList *d, int n) +/* + * desc: free the dirlist d + * pre: d != NULL + * post: memory allocated to d has been released + */ +{ + int i; + + if (d) { + for (i=0; i<n; i++) { + if (d[i].linkname) { + free(d[i].linkname); + } + } + free(d); + } else { + printf("dir.c:FreeDir(): d == NULL\n"); + exit(-1); + } + + return; +} /* FreeDir() */ + +void +toggle_dotfiles(void) +/* + * desc: toggle visibility of dot-files + */ +{ + _showdotfiles = !_showdotfiles; + + return; +} /* toggle_dotfiles() */ + +int +show_dotfiles(void) +/* + * desc: return the value of _showdotfiles + */ +{ + return(_showdotfiles); +} /* show_dotfiles() */ + +void +set_dotfiles(int b) +/* + * desc: set the value of _showdotfiles + */ +{ + _showdotfiles = b; + + return; +} /* set_dotfiles() */ diff --git a/gnu/lib/libdialog/dir.h b/gnu/lib/libdialog/dir.h new file mode 100644 index 0000000..3a28f12 --- /dev/null +++ b/gnu/lib/libdialog/dir.h @@ -0,0 +1,36 @@ +/* + * include file for dir.c + * + * Copyright (c) 1995, Marc van Kempen + * + * All rights reserved. + * + * This software may be used, modified, copied, distributed, and + * sold, in both source and binary form provided that the above + * copyright and these terms are retained, verbatim, as the first + * lines of this file. Under no circumstances is the author + * responsible for the proper functioning of this software, nor does + * the author assume any responsibility for damages incurred with + * its use. + * + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/dirent.h> + +typedef struct DirList { /* structure to hold the directory entries */ + char filename[MAXNAMLEN]; /* together with the stat-info per file */ + struct stat filestatus; /* filename, or the name to which it points */ + int link; /* is it a link ? */ + char *linkname; /* the name of the file the link points to */ +} DirList; + +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef FALSE +#define FALSE (0) +#endif + +void get_dir(char *dirname, char *fmask, DirList **dir, int *n); diff --git a/gnu/lib/libdialog/fselect.c b/gnu/lib/libdialog/fselect.c new file mode 100644 index 0000000..bf73b29 --- /dev/null +++ b/gnu/lib/libdialog/fselect.c @@ -0,0 +1,242 @@ +/* + * program: fselect.c + * author: Marc van Kempen (wmbfmk@urc.tue.nl) + * Desc: File selection routine + * + * Copyright (c) 1995, Marc van Kempen + * + * All rights reserved. + * + * This software may be used, modified, copied, distributed, and + * sold, in both source and binary form provided that the above + * copyright and these terms are retained, verbatim, as the first + * lines of this file. Under no circumstances is the author + * responsible for the proper functioning of this software, nor does + * the author assume any responsibility for damages incurred with + * its use. + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include <sys/param.h> +#include <dialog.h> +#include "ui_objects.h" +#include "dir.h" +#include "dialog.priv.h" + +void +get_directories(DirList *d, int n, char ***names, int *nd) +/* + * Desc: return the directorienames in <dir> as an array in + * <names>, the # of entries in <nd>, memory allocated + * to *names should be freed when done with it. + */ +{ + int i; + + /* count the directories, which are in front */ + *nd = 0; + while ((*nd < n) && (S_ISDIR(d[*nd].filestatus.st_mode))) (*nd)++; + *names = (char **) malloc( *nd * sizeof(char *) ); + for (i=0; i<*nd; i++) { + (*names)[i] = (char *) malloc( strlen(d[i].filename) + 1); + strcpy((*names)[i], d[i].filename); + } + + return; +} /* get_directories() */ + +void +get_filenames(DirList *d, int n, char ***names, int *nf) +/* + * Desc: return the filenames in <dir> as an arry in + * <names>, the # of entries in <nf>, memory allocated + * to *names should be freed when done. + */ +{ + int nd, i; + + /* the # of regular files is the total # of files - # of directories */ + /* count the # of directories */ + nd = 0; + while ((nd < n) && (S_ISDIR(d[nd].filestatus.st_mode))) nd++; + + *names = (char **) malloc( (n-nd) * sizeof(char *) ); + *nf = n - nd; + for (i=0; i<*nf; i++) { + (*names)[i] = (char *) malloc( strlen(d[i+nd].filename) + 1); + strcpy((*names)[i], d[i+nd].filename); + } + + return; +} /* get_filenames() */ + +void +FreeNames(char **names, int n) +/* + * Desc: free the space occupied by names + */ +{ + int i; + + /* free the space occupied by names */ + for (i=0; i<n; i++) { + free(names[i]); + } + free(names); + + return; +} /* FreeNames() */ + +char * +dialog_fselect(char *dir, char *fmask) +/* + * Desc: choose a file from the directory <dir>, which + * initially display files with the mask <filemask> + * pre: <dir> is the initial directory + * only files corresponding to the mask <fmask> are displayed + * post: returns NULL if no file was selected + * else returns pointer to filename, space is allocated, should + * be freed after use. + */ +{ + DirList *d = NULL; + char msg[512]; + char **names, *ret_name; + WINDOW *fs_win; + int n, nd, nf, ret; + StringObj *fm_obj, *dir_obj, *sel_obj; + char o_fm[255], o_dir[MAXPATHLEN], o_sel[MAXPATHLEN]; + char old_fmask[255], old_dir[MAXPATHLEN]; + ListObj *dirs_obj, *files_obj; + struct ComposeObj *obj = NULL, *o; + int quit, cancel; + ButtonObj *okbut_obj, *canbut_obj; + int ok_button, cancel_button; + + if (chdir(dir)) { + sprintf(msg, "Could not move into specified directory: %s", dir); + dialog_notify(msg); + return(NULL); + } + getcwd(o_dir, MAXPATHLEN); + + /* setup the fileselect-window and initialize its components */ + fs_win = newwin(LINES-2, COLS-20, 1, 10); + if (fs_win == NULL) { + endwin(); + fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", + LINES-2, COLS-20, 2, 10); + exit(1); + } + draw_box(fs_win, 0, 0, LINES-2, COLS-20, dialog_attr, border_attr); + wattrset(fs_win, dialog_attr); + mvwaddstr(fs_win, 0, (COLS-20)/2 - 7, " File Select "); + draw_shadow(stdscr, 1, 10, LINES-2, COLS-20); + + /* Filemask entry */ + strcpy(o_fm, fmask); + fm_obj = NewStringObj(fs_win, "Filemask:", o_fm, 1, 2, 19, 255); + AddObj(&obj, STRINGOBJ, (void *) fm_obj); + + /* Directory entry */ + dir_obj = NewStringObj(fs_win, "Directory:", o_dir, 1, 22, COLS-44, 255); + AddObj(&obj, STRINGOBJ, (void *) dir_obj); + + /* Directory list */ + get_dir(".", fmask, &d, &n); /* read the entire directory */ + get_directories(d, n, &names, &nd); /* extract the dir-entries */ + dirs_obj = NewListObj(fs_win, "Directories:", names, o_dir, 5, 2, + LINES-16, (COLS-20)/2-2, nd); + AddObj(&obj, LISTOBJ, (void *) dirs_obj); + + /* Filenames list */ + get_filenames(d, n, &names, &nf); /* extract the filenames */ + files_obj = NewListObj(fs_win, "Files:", names, o_sel, 5, (COLS-20)/2+1, + LINES-16, (COLS-20)/2-3, nf); + AddObj(&obj, LISTOBJ, (void *) files_obj); + + /* Selection entry */ + o_sel[0] = '\0'; + sel_obj = NewStringObj(fs_win, "Selection:", o_sel, LINES-10, 2, COLS-24, 255); + AddObj(&obj, STRINGOBJ, (void *) sel_obj); + + /* Ok button */ + ok_button = FALSE; + okbut_obj = NewButtonObj(fs_win, "Ok", &ok_button, LINES-6, 20); + AddObj(&obj, BUTTONOBJ, (void *) okbut_obj); + + /* Cancel button */ + cancel_button = FALSE; + canbut_obj = NewButtonObj(fs_win, "Cancel", &cancel_button, LINES-6, 30); + AddObj(&obj, BUTTONOBJ, (void *) canbut_obj); + + /* Make sure all objects on the window are drawn */ + wrefresh(fs_win); + keypad(fs_win, TRUE); + + /* Start the reading */ + o = obj; + strcpy(old_fmask, o_fm); + strcpy(old_dir, o_dir); + quit = FALSE; + cancel = FALSE; + while (!quit) { + ret = PollObj(&o); + switch(ret) { + case SEL_CR: + if (strcmp(old_fmask, o_fm) || strcmp(old_dir, o_dir)) { + /* reread directory and update the listobjects */ + if (strcmp(old_dir, o_dir)) { /* dir entry was changed */ + if (chdir(o_dir)) { + dialog_notify("Could not change into directory"); + } else { + getcwd(o_dir, MAXPATHLEN); + strcpy(old_dir, o_dir); + RefreshStringObj(dir_obj); + } + } else { /* fmask entry was changed */ + strcpy(old_fmask, o_fm); + } + get_dir(".", o_fm, &d, &n); + get_directories(d, n, &names, &nd); + UpdateListObj(dirs_obj, names, nd); + get_filenames(d, n, &names, &nf); + UpdateListObj(files_obj, names, nf); + if (((o->prev)->obj == (void *) dirs_obj)) { + o=o->prev; + } + } + break; + case SEL_BUTTON: + /* check which button was pressed */ + if (ok_button) { + quit = TRUE; + } + if (cancel_button) { + quit = TRUE; + cancel = TRUE; + } + break; + case SEL_ESC: + quit = TRUE; + cancel = TRUE; + break; + case KEY_F(1): + case '?': + display_helpfile(); + break; + } + } + DelObj(obj); + + if (cancel || (strlen(o_sel) == 0)) { + return(NULL); + } else { + ret_name = (char *) malloc( strlen(o_sel) + 1 ); + strcpy(ret_name, o_sel); + return(ret_name); + } +} /* dialog_fselect() */ + diff --git a/gnu/lib/libdialog/help.c b/gnu/lib/libdialog/help.c new file mode 100644 index 0000000..eee04ca --- /dev/null +++ b/gnu/lib/libdialog/help.c @@ -0,0 +1,155 @@ +/*************************************************************** + * + * Program: help.c + * Author: Marc van Kempen + * Desc: get help + * + * + * Copyright (c) 1995, Marc van Kempen + * + * All rights reserved. + * + * This software may be used, modified, copied, distributed, and + * sold, in both source and binary form provided that the above + * copyright and these terms are retained, verbatim, as the first + * lines of this file. Under no circumstances is the author + * responsible for the proper functioning of this software, nor does + * the author assume any responsibility for damages incurred with + * its use. + * + ***************************************************************/ + +#include <stdlib.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <dialog.h> + +static char _helpfilebuf[MAXPATHLEN]; +static char _helplinebuf[77]; /* limit the helpline to 76 characters */ +static char *_helpfile = NULL; +static char *_helpline = NULL; + +/****************************************************************** + * + * helpfile routines + * + ******************************************************************/ + +void +use_helpfile(char *hfile) +/* + * desc: set the helpfile to be opened on pressing F1 to <helpfile> + */ +{ + if (hfile != NULL) { + _helpfile = _helpfilebuf; + strcpy(_helpfile, hfile); + } else { + _helpfile = NULL; + } + + return; +} /* use_helpfile() */ + +void +display_helpfile(void) +/* + * desc: display the current helpfile in a window + */ +{ + WINDOW *w; + FILE *f; + struct stat sb; + char msg[80], *buf; + static int in_help = FALSE; + + if (in_help) return; /* dont call help when you're in help */ + + if (_helpfile != NULL) { + w = dupwin(curscr); + if ((f = fopen(_helpfile, "r")) == NULL) { + sprintf(msg, "Can't open helpfile : %s\n", _helpfile); + dialog_notify(msg); + return; + } + if (fstat(fileno(f), &sb)) { + sprintf(msg, "Can't stat helpfile : %s\n", _helpfile); + dialog_notify(msg); + return; + } + if ((buf = (char *) malloc( sb.st_size )) == NULL) { + sprintf(msg, "Could not malloc space for helpfile : %s\n", _helpfile); + dialog_notify(msg); + return; + } + if (fread(buf, 1, sb.st_size, f) != sb.st_size) { + sprintf(msg, "Could not read entire help file : %s", _helpfile); + dialog_notify(msg); + return; + } + buf[sb.st_size] = 0; + in_help = TRUE; + dialog_mesgbox("Online help", buf, LINES-4, COLS-4); + in_help = FALSE; + wrefresh(w); + delwin(w); + free(buf); + } else { + /* do nothing */ + } + + return; +} /* display_helpfile() */ + + +/****************************************************************** + * + * helpline routines + * + ******************************************************************/ + +void +use_helpline(char *hline) +/* + * desc: set the helpline to printed in dialogs + */ +{ + if (hline) { + _helpline = _helplinebuf; + if (strlen(hline) > 76) { + /* only display the first 76 characters in the helpline */ + strncpy(_helpline, hline, 76); + _helpline[76] = 0; + } else { + strcpy(_helpline, hline); + } + } else { + _helpline = NULL; + } + + return; +} /* use_helpline() */ + +void +display_helpline(WINDOW *w, int y, int width) +/* + * desc: display the helpline at the given coordinates <y, x> in the window <w> + */ +{ + if (_helpline != NULL) { + if (strlen(_helpline) > width - 6) { + _helpline[width - 6] = 0; + } + wmove(w, y, (int) (width - strlen(_helpline)- 4) / 2); + wattrset(w, title_attr); + waddstr(w, "[ "); + waddstr(w, _helpline); + waddstr(w, " ]"); + } else { + /* do nothing */ + } + + return; +} diff --git a/gnu/lib/libdialog/inputbox.c b/gnu/lib/libdialog/inputbox.c index b69267f..b552a9a 100644 --- a/gnu/lib/libdialog/inputbox.c +++ b/gnu/lib/libdialog/inputbox.c @@ -92,6 +92,8 @@ int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int box_x = (width - box_width)/2; draw_box(dialog, y+1, box_x-1, 3, box_width+2, border_attr, dialog_attr); + display_helpline(dialog, height-1, width); + x = width/2-11; y = height-2; print_button(dialog, "Cancel", y, x+14, FALSE); @@ -175,6 +177,10 @@ int dialog_inputbox(unsigned char *title, unsigned char *prompt, int height, int return (button == -1 ? 0 : button); case ESC: break; + case KEY_F(1): + case '?': + display_helpfile(); + break; } } diff --git a/gnu/lib/libdialog/kernel.c b/gnu/lib/libdialog/kernel.c index fad8c65..75c6370 100644 --- a/gnu/lib/libdialog/kernel.c +++ b/gnu/lib/libdialog/kernel.c @@ -375,6 +375,7 @@ void draw_box(WINDOW *win, int y, int x, int height, int width, chtype box, chty void draw_shadow(WINDOW *win, int y, int x, int height, int width) { int i,sx,sy; + WINDOW *newscr=win; if (has_colors()) { /* Whether terminal supports color? */ getbegyx(win,sy,sx); diff --git a/gnu/lib/libdialog/lineedit.c b/gnu/lib/libdialog/lineedit.c index afcf0f5..f643bf4 100644 --- a/gnu/lib/libdialog/lineedit.c +++ b/gnu/lib/libdialog/lineedit.c @@ -45,8 +45,10 @@ int line_edit(WINDOW* dialog, int box_y, int box_x, int flen, int box_width, cht memset(instr, 0, sizeof(instr)); strcpy(instr, result); i = strlen(instr); - input_x = i % box_width; - scroll = i - input_x; +/* input_x = i % box_width;*/ + input_x = (i > box_width) ? box_width - 1 : i; +/* scroll = i - input_x;*/ + scroll = (i > box_width) ? i - box_width + 1: 0; } wmove(dialog, box_y, box_x); wattrset(dialog, attr); @@ -65,6 +67,12 @@ int line_edit(WINDOW* dialog, int box_y, int box_x, int flen, int box_width, cht wrefresh(dialog); key = wgetch(dialog); switch (key) { + case ctrl('q'): + goto ret; + break; + case KEY_F(1): + display_helpfile(); + break; case TAB: case KEY_BTAB: case KEY_UP: diff --git a/gnu/lib/libdialog/menubox.c b/gnu/lib/libdialog/menubox.c index 22c7bc0..f15ed00 100644 --- a/gnu/lib/libdialog/menubox.c +++ b/gnu/lib/libdialog/menubox.c @@ -21,23 +21,27 @@ #include <dialog.h> #include "dialog.priv.h" - +#include <ncurses.h> static void print_item(WINDOW *win, unsigned char *tag, unsigned char *item, int choice, int selected); static int menu_width, tag_x, item_x; - /* * Display a menu for choosing among a number of options */ -int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result) +int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int width, int menu_height, int item_no, unsigned char **items, unsigned char *result, int *ch, int *sc) { int i, j, x, y, cur_x, cur_y, box_x, box_y, key = 0, button = 0, choice = 0, - l, k, scroll = 0, max_choice; + l, k, scroll = 0, max_choice, redraw_menu = FALSE; WINDOW *dialog, *menu; + if (ch) /* restore menu item info */ + choice = *ch; + if (sc) + scroll = *sc; + max_choice = MIN(menu_height, item_no); tag_x = 0; @@ -137,10 +141,13 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid waddstr(dialog,"(+)"); } + display_helpline(dialog, height-1, width); + x = width/2-11; y = height-2; print_button(dialog, "Cancel", y, x+14, FALSE); print_button(dialog, " OK ", y, x, TRUE); + wrefresh(dialog); while (key != ESC) { @@ -273,20 +280,54 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid continue; /* wait for another key press */ } + /* save info about menu item position */ + if (ch) + *ch = choice; + if (sc) + *sc = scroll; + switch (key) { - case 'O': - case 'o': + case KEY_PPAGE: + if (scroll > height-4) { /* can we go up? */ + scroll -= (height-4); + } else { + scroll = 0; + } + redraw_menu = TRUE; + break; + case KEY_NPAGE: + if (scroll + menu_height >= item_no-1 - menu_height) { /* can we go down a full page? */ + scroll = item_no - menu_height; + if (scroll < 0) scroll = 0; + } else { + scroll += menu_height; + } + redraw_menu = TRUE; + break; + case KEY_HOME: + scroll = 0; + choice = 0; + redraw_menu = TRUE; + break; + case KEY_END: + scroll = item_no - menu_height; + if (scroll < 0) scroll = 0; + choice = max_choice - 1; + redraw_menu = TRUE; + break; + case 'O': + case 'o': delwin(dialog); strcpy(result, items[(scroll+choice)*2]); return 0; - case 'C': - case 'c': + case 'C': + case 'c': delwin(dialog); return 1; - case KEY_BTAB: - case TAB: - case KEY_LEFT: - case KEY_RIGHT: + case KEY_BTAB: + case TAB: + case KEY_LEFT: + case KEY_RIGHT: if (!button) { button = 1; /* Indicates "Cancel" button is selected */ print_button(dialog, " OK ", y, x, FALSE); @@ -299,15 +340,28 @@ int dialog_menu(unsigned char *title, unsigned char *prompt, int height, int wid } wrefresh(dialog); break; - case ' ': - case '\r': - case '\n': + case ' ': + case '\r': + case '\n': delwin(dialog); if (!button) strcpy(result, items[(scroll+choice)*2]); return button; - case ESC: + case ESC: break; + case KEY_F(1): + case '?': + display_helpfile(); + break; + } + if (redraw_menu) { + for (i = 0; i < max_choice; i++) { + print_item(menu, items[(scroll+i)*2], + items[(scroll+i)*2 + 1], i, i == choice); + } + wnoutrefresh(menu); + wrefresh(dialog); + redraw_menu = FALSE; } } diff --git a/gnu/lib/libdialog/msgbox.c b/gnu/lib/libdialog/msgbox.c index f8ca26f..d5966c4 100644 --- a/gnu/lib/libdialog/msgbox.c +++ b/gnu/lib/libdialog/msgbox.c @@ -23,6 +23,12 @@ #include "dialog.priv.h" +/* local prototypes */ +static int getnlines(unsigned char *buf); +static void print_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll); +static void print_perc(WINDOW *win, int y, int x, float p); + + /* * Display a message box. Program will pause and display an "OK" button * if the parameter 'pause' is non-zero. @@ -86,6 +92,7 @@ int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int w wmove(dialog, height-2, 1); for (i = 0; i < width-2; i++) waddch(dialog, ' '); + display_helpline(dialog, height-1, width); print_button(dialog, " OK ", height-2, width/2-4, TRUE); wrefresh(dialog); while (key != ESC && key != '\n' && key != ' ' && key != '\r') @@ -102,3 +109,231 @@ int dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int w return (key == ESC ? -1 : 0); } /* End of dialog_msgbox() */ + +int +dialog_mesgbox(unsigned char *title, unsigned char *prompt, int height, int width) +/* + * Desc: basically the same as dialog_msgbox, but ... can use PGUP, PGDN and + * arrowkeys to move around the text and pause is always enabled + */ +{ + int i, j, x, y, key=0; + int theight, startline, hscroll, max_lines; + WINDOW *dialog; + + if (height < 0) + height = strheight(prompt)+2+2*(!!pause); + if (width < 0) { + i = strwidth(prompt); + j = strwidth(title); + width = MAX(i,j)+4; + } + + 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); + exit(1); + } + keypad(dialog, TRUE); + + draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); + + 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, 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, ' '); + display_helpline(dialog, height-1, width); + print_button(dialog, " EXIT ", height-2, width/2-4, TRUE); + wattrset(dialog, dialog_attr); + + theight = height - 4; + startline = 0; + hscroll = 0; + max_lines = getnlines(prompt); + print_page(dialog, theight, width, prompt, startline, hscroll); + print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines); + wmove(dialog, height-2, width/2-2); + wrefresh(dialog); + while ((key != ESC) && (key != '\n') && (key != '\r')) { + key = wgetch(dialog); + switch(key) { + case KEY_HOME: + startline=0; + hscroll=0; + break; + case KEY_END: + startline = max_lines - theight; + if (startline < 0) startline = 0; + break; + case KEY_UP: + if (startline > 0) startline--; + break; + case KEY_DOWN: + if (startline < max_lines - theight) startline++; + break; + case KEY_RIGHT: + hscroll++; + break; + case KEY_LEFT: + if (hscroll > 0) hscroll--; + break; + case KEY_PPAGE: + if (startline - height > 0) { + startline -= theight; + } else { + startline = 0; + } + break; + case KEY_NPAGE: + if (startline + theight < max_lines - theight) { + startline += theight; + } else { + startline = max_lines - theight; + if (startline < 0) startline = 0; + } + break; + case KEY_F(1): + case '?': + display_helpfile(); + break; + } + print_page(dialog, theight, width, prompt, startline, hscroll); + print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines); + wmove(dialog, height-2, width/2-2); + wrefresh(dialog); + } + + delwin(dialog); + return (key == ESC ? -1 : 0); + +} /* dialog_mesgbox() */ + +static void +print_perc(WINDOW *win, int y, int x, float p) +/* + * Desc: print p as a percentage at the coordinates (y,x) + */ +{ + char ps[10]; + + if (p>1.0) p=1.0; + sprintf(ps, "(%3d%%)", (int) (p*100)); + wmove(win, y, x); + waddstr(win, ps); + + return; +} /* print_perc() */ + +static int +getnlines(unsigned char *buf) +/* + * Desc: count the # of lines in <buf> + */ +{ + int i = 0; + + while (*buf) { + if (*buf == '\n' || *buf == '\r') { + i++; + } + buf++; + } + return(i); +} /* getlines() */ + + +unsigned char * +getline(unsigned char *buf, int n) +/* + * Desc: return a pointer to the n'th line in <buf> or NULL if its + * not there + */ +{ + int i; + + if (n<0) { + return(NULL); + } + + i=0; + while (*buf && i<n) { + if (*buf == '\n' || *buf == '\r') { + i++; + } + buf++; + } + if (i<n) { + return(NULL); + } else { + return(buf); + } +} /* getline() */ + +static void +print_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll) +/* + * Desc: Print a page of text in the current window, starting at line <startline> + * with a <horizontal> scroll of hscroll from buffer <buf> + */ +{ + int i, j; + unsigned char *b; + + b = getline(buf, startline); + for (i=0; i<height; i++) { + /* clear line */ + wmove(win, 1+i, 1); + for (j=0; j<width-2; j++) waddnstr(win, " ", 1); + wmove(win, 1+i, 1); + j = 0; + /* scroll to the right */ + while (*b && (*b != '\n') && (*b != '\r') && (j<hscroll)) { + b++; + j++; + } + /* print new line */ + j = 0; + while (*b && (*b != '\n') && (*b != '\r') && (j<width-2)) { + waddnstr(win, b, 1); + if (*b != '\t') { /* check for tabs */ + j++; + } else { + j = ((int) (j+1)/8 + 1) * 8 - 1; + } + b++; + } + while (*b && (*b != '\n') && (*b != '\r')) b++; + if (*b) b++; /* skip over '\n', if it exists */ + } +} /* print_page() */ + + + + diff --git a/gnu/lib/libdialog/notify.c b/gnu/lib/libdialog/notify.c new file mode 100644 index 0000000..27d1cc0 --- /dev/null +++ b/gnu/lib/libdialog/notify.c @@ -0,0 +1,64 @@ +/* + * File: notify.c + * Author: Marc van Kempen + * Desc: display a notify box with a message + * + * Copyright (c) 1995, Marc van Kempen + * + * All rights reserved. + * + * This software may be used, modified, copied, distributed, and + * sold, in both source and binary form provided that the above + * copyright and these terms are retained, verbatim, as the first + * lines of this file. Under no circumstances is the author + * responsible for the proper functioning of this software, nor does + * the author assume any responsibility for damages incurred with + * its use. + * + */ + + +#include <dialog.h> +#include <stdio.h> + +void +dialog_notify(char *msg) +/* + * Desc: display an error message + */ +{ + int li, co, mco; + char *p; + WINDOW *w; + + /* determine # of lines in msg and max colwidth */ + li = 0; + co = 0; + mco = 0; + p = msg; + while (*p) { + if (*p == '\n') { + li++; + if (co > mco) mco = co; + co = 0; + } + p++; + co++; + } + if (co < mco) co = mco; + + li += 5; + if (li > LINES) li = LINES; + co += 4; + if (co < 20) co = 20; + if (co > COLS) co = COLS; + + w = dupwin(curscr); + dialog_msgbox("Message", msg, li, co, TRUE); + wrefresh(w); + delwin(w); + + return; + +} /* dialog_notify() */ + diff --git a/gnu/lib/libdialog/prgbox.c b/gnu/lib/libdialog/prgbox.c index 0177edb..7082b67 100644 --- a/gnu/lib/libdialog/prgbox.c +++ b/gnu/lib/libdialog/prgbox.c @@ -129,6 +129,7 @@ int dialog_prgbox(unsigned char *title, const unsigned char *line, int height, i wmove(dialog, height-2, 1); for (i = 0; i < width-2; i++) waddch(dialog, ' '); + display_helpline(dialog, height-1, width); print_button(dialog, " OK ", height-2, width/2-4, TRUE); wrefresh(dialog); while (key != ESC && key != '\n' && key != ' ' && key != '\r') diff --git a/gnu/lib/libdialog/radiolist.c b/gnu/lib/libdialog/radiolist.c index 417f2ab..060390e 100644 --- a/gnu/lib/libdialog/radiolist.c +++ b/gnu/lib/libdialog/radiolist.c @@ -155,6 +155,8 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in waddstr(dialog, "(+)"); } + display_helpline(dialog, height-1, width); + x = width/2-11; y = height-2; print_button(dialog, "Cancel", y, x+14, FALSE); @@ -360,6 +362,10 @@ int dialog_radiolist(unsigned char *title, unsigned char *prompt, int height, in return button; case ESC: break; + case KEY_F(1): + case '?': + display_helpfile(); + break; } } diff --git a/gnu/lib/libdialog/textbox.c b/gnu/lib/libdialog/textbox.c index 0479723..a9a3a28 100644 --- a/gnu/lib/libdialog/textbox.c +++ b/gnu/lib/libdialog/textbox.c @@ -59,7 +59,7 @@ int dialog_textbox(unsigned char *title, unsigned char *file, int height, int wi /* Open input file for reading */ if ((fd = open(file, O_RDONLY)) == -1) { endwin(); - fprintf(stderr, "\nCan't open input file in dialog_textbox().\n"); + fprintf(stderr, "\nCan't open input file <%s>in dialog_textbox().\n", file); exit(-1); } /* Get file size. Actually, 'file_size' is the real file size - 1, @@ -139,6 +139,8 @@ int dialog_textbox(unsigned char *title, unsigned char *file, int height, int wi waddstr(dialog, title); waddch(dialog, ' '); } + display_helpline(dialog, height-1, width); + print_button(dialog, " EXIT ", height-2, width/2-4, TRUE); wnoutrefresh(dialog); getyx(dialog, cur_y, cur_x); /* Save cursor position */ @@ -411,6 +413,9 @@ int dialog_textbox(unsigned char *title, unsigned char *file, int height, int wi break; case ESC: break; + case KEY_F(1): + display_helpfile(); + break; } } diff --git a/gnu/lib/libdialog/ui_objects.c b/gnu/lib/libdialog/ui_objects.c new file mode 100644 index 0000000..132fe1e --- /dev/null +++ b/gnu/lib/libdialog/ui_objects.c @@ -0,0 +1,735 @@ +/* + * Program: objects.c + * Author: Marc van Kempen + * Desc: Implementation of UI-objects: + * - String input fields + * - List selection + * - Buttons + * + * Copyright (c) 1995, Marc van Kempen + * + * All rights reserved. + * + * This software may be used, modified, copied, distributed, and + * sold, in both source and binary form provided that the above + * copyright and these terms are retained, verbatim, as the first + * lines of this file. Under no circumstances is the author + * responsible for the proper functioning of this software, nor does + * the author assume any responsibility for damages incurred with + * its use. + * + */ + +#include <stdlib.h> +#include <sys/param.h> +#include <ncurses.h> +#include <dialog.h> +#include "dialog.priv.h" +#include "ui_objects.h" + +#define ESC 27 + + +/*********************************************************************** + * + * Obj routines + * + ***********************************************************************/ + +void +AddObj(ComposeObj **Obj, int objtype, void *obj) +/* + * Desc: Add the object <obj> to the list of objects <Obj> + */ +{ + if (*Obj == NULL) { + /* Create the root object */ + *Obj = (ComposeObj *) malloc( sizeof(ComposeObj) ); + if (!Obj) { + printf("AddObj: Error malloc'ing ComposeObj\n"); + exit(-1); + } + (*Obj)->objtype = objtype; + (*Obj)->obj = obj; + (*Obj)->next = NULL; + (*Obj)->prev = NULL; + } else { + ComposeObj *o = *Obj; + + /* create the next object */ + while (o->next) o = (ComposeObj *) o->next; + o->next = (struct ComposeObj *) malloc( sizeof(ComposeObj) ); + if (!o->next) { + printf("AddObj: Error malloc'ing o->next\n"); + exit(-1); + } + o->next->objtype = objtype; + o->next->obj = obj; + o->next->next = NULL; + o->next->prev = o; + } + + return; +} /* AddObj() */ + +void +FreeObj(ComposeObj *Obj) +/* + * Desc: free the memory occupied by *Obj + */ +{ + ComposeObj *o = Obj; + + o = Obj; + while (o) { + o = Obj->next; + free(Obj); + Obj = o; + } + + return; +} /* FreeObj() */ + + +int +ReadObj(ComposeObj *Obj) +/* + * Desc: navigate through the different objects calling their + * respective navigation routines as necessary + * Pre: Obj != NULL + */ +{ + ComposeObj *o; + ComposeObj *last; /* the last object in the list */ + int ret; /* the return value from the selection routine */ + + /* find the last object in the list */ + last = Obj; + while (last->next) last = last->next; + + ret = 0; + o = Obj; + while ((ret != SEL_BUTTON) && (ret != SEL_ESC)) { + switch(o->objtype) { + case STRINGOBJ: + ret = SelectStringObj((StringObj *) o->obj); + break; + case LISTOBJ: + ret = SelectListObj((ListObj *) o->obj); + break; + case BUTTONOBJ: + ret = SelectButtonObj((ButtonObj *) o->obj); + break; + } + switch(ret) { + case SEL_CR: + case SEL_TAB: /* move to the next object in the list */ + if (o->next != NULL) { + o = o->next; /* next object */ + } else { + o = Obj; /* beginning of the list */ + } + break; + case SEL_BACKTAB: /* move to the previous object in the list */ + if (o->prev != NULL) { + o = o->prev; /* previous object */ + } else { + o = last; /* end of the list */ + } + break; + case KEY_F(1): /* display help_file */ + case '?': + display_helpfile(); + break; + } + } + + return(ret); + +} /* ReadObj() */ + + +int +PollObj(ComposeObj **Obj) +{ + ComposeObj *last; /* the last object in the list */ + ComposeObj *first; /* the first object in the list */ + int ret; /* the return value from the selection routine */ + + /* find the last object in the list */ + last = *Obj; + while (last->next) last = last->next; + + /* find the first object in the list */ + first = *Obj; + while (first->prev) first = first->prev; + + ret = 0; + switch((*Obj)->objtype) { + case STRINGOBJ: + ret = SelectStringObj((StringObj *) (*Obj)->obj); + break; + case LISTOBJ: + ret = SelectListObj((ListObj *) (*Obj)->obj); + break; + case BUTTONOBJ: + ret = SelectButtonObj((ButtonObj *) (*Obj)->obj); + break; + } + switch(ret) { + case SEL_CR: + case SEL_TAB: /* move to the next object in the list */ + if ((*Obj)->next != NULL) { + *Obj = (*Obj)->next; /* next object */ + } else { + *Obj = first; /* beginning of the list */ + } + break; + case SEL_BACKTAB: /* move to the previous object in the list */ + if ((*Obj)->prev != NULL) { + *Obj = (*Obj)->prev; /* previous object */ + } else { + *Obj = last; /* end of the list */ + } + break; + } + + return(ret); + +} /* PollObj() */ + + +void +DelObj(ComposeObj *Obj) +/* + * Desc: Free all objects + */ +{ + ComposeObj *o; + + o = Obj; + while (Obj != NULL) { + switch(Obj->objtype) { + case STRINGOBJ: + DelStringObj((StringObj *) Obj->obj); + break; + case LISTOBJ: + DelListObj((ListObj *) Obj->obj); + break; + case BUTTONOBJ: + DelButtonObj((ButtonObj *) Obj->obj); + break; + } + Obj = Obj->next; + } + + FreeObj(o); +} /* DelObj() */ + +/*********************************************************************** + * + * StringObj routines + * + ***********************************************************************/ + +void +RefreshStringObj(StringObj *so) +/* + * Desc: redraw the object + */ +{ + char tmp[512]; + + wmove(so->win, so->y, so->x+1); + wattrset(so->win, dialog_attr); + waddstr(so->win, so->title); + + draw_box(so->win, so->y+1, so->x, 3, so->w, dialog_attr, border_attr); + wattrset(so->win, item_attr); + wmove(so->win, so->y+2, so->x+1); + if (strlen(so->s) > so->w-2) { + strncpy(tmp, (char *) so->s + strlen(so->s) - so->w + 2, so->w - 1); + waddstr(so->win, tmp); + } else { + waddstr(so->win, so->s); + } + + return; +} /* RefreshStringObj() */ + +StringObj * +NewStringObj(WINDOW *win, char *title, char *s, int y, int x, int w, int len) +/* + * Desc: Initialize a new stringobj and return a pointer to it. + * Draw the object on the screen at the specified coordinates + */ +{ + StringObj *so; + + /* Initialize a new object */ + so = (StringObj *) malloc( sizeof(StringObj) ); + if (!so) { + printf("NewStringObj: Error malloc'ing StringObj\n"); + exit(-1); + } + so->title = (char *) malloc( strlen(title) + 1); + if (!so->title) { + printf("NewStringObj: Error malloc'ing so->title\n"); + exit(-1); + } + strcpy(so->title, title); + so->s = s; + strcpy(so->s, s); + so->x = x; + so->y = y; + so->w = w; + so->len = len; + so->win = win; + + /* Draw it on the screen */ + RefreshStringObj(so); + + return(so); +} /* NewStringObj() */ + +int +SelectStringObj(StringObj *so) +/* + * Desc: get input using the info in <so> + */ +{ + int key; + char tmp[so->len+1]; + + strcpy(tmp, so->s); + key = line_edit(so->win, so->y+2, so->x+1, + so->len, so->w-2, inputbox_attr, TRUE, tmp); + if ((key == '\n') || (key == '\r')) { + strcpy(so->s, tmp); + } + RefreshStringObj(so); + if (key == ESC) { + return(SEL_ESC); + } + if (key == '\t') { + return(SEL_TAB); + } + if ( (key == KEY_BTAB) || (key == KEY_F(2)) ) { + return(SEL_BACKTAB); + } + if ((key == '\n') || (key == '\r')) { + strcpy(so->s, tmp); + return(SEL_CR); + } + return(key); +} /* SelectStringObj() */ + + +void +DelStringObj(StringObj *so) +/* + * Desc: Free the space occupied by <so> + */ +{ + free(so->title); + free(so); + + return; +} + +/*********************************************************************** + * + * ListObj routines + * + ***********************************************************************/ + +void +DrawNames(ListObj *lo) +/* + * Desc: Just refresh the names, not the surrounding box and title + */ +{ + int i, j, h, x, y; + char tmp[MAXPATHLEN]; + + x = lo->x + 1; + y = lo->y + 2; + h = lo->h - 2; + wattrset(lo->win, item_attr); + for (i=lo->scroll; i<lo->n && i<lo->scroll+h; i++) { + wmove(lo->win, y+i-lo->scroll, x); + if (strlen(lo->name[i]) > lo->w-2) { + strncpy(tmp, lo->name[i], lo->w-2); + tmp[lo->w - 2] = 0; + waddstr(lo->win, tmp); + } else { + waddstr(lo->win, lo->name[i]); + for (j=strlen(lo->name[i]); j<lo->w-2; j++) waddstr(lo->win, " "); + } + } + while (i<lo->scroll+h) { + wmove(lo->win, y+i-lo->scroll, x); + for (j=0; j<lo->w-2; j++) waddstr(lo->win, " "); + i++; + } + + return; +} /* DrawNames() */ + +void +RefreshListObj(ListObj *lo) +/* + * Desc: redraw the list object + */ +{ + char perc[7]; + + /* setup the box */ + wmove(lo->win, lo->y, lo->x+1); + wattrset(lo->win, dialog_attr); + waddstr(lo->win, lo->title); + draw_box(lo->win, lo->y+1, lo->x, lo->h, lo->w, dialog_attr, border_attr); + + /* draw the names */ + DrawNames(lo); + + /* Draw % indication */ + sprintf(perc, "(%3d%%)", MIN(100, (int) (100 * (lo->sel+lo->h-2) / MAX(1, lo->n)))); + wmove(lo->win, lo->y + lo->h, lo->x + lo->w - 8); + wattrset(lo->win, dialog_attr); + waddstr(lo->win, perc); + + + return; +} /* RefreshListObj() */ + +ListObj * +NewListObj(WINDOW *win, char *title, char **list, char *listelt, int y, int x, + int h, int w, int n) +/* + * Desc: create a listobj, draw it on the screen and return a pointer to it. + */ +{ + ListObj *lo; + + /* Initialize a new object */ + lo = (ListObj *) malloc( sizeof(ListObj) ); + if (!lo) { + printf("NewListObj: Error malloc'ing ListObj\n"); + exit(-1); + } + lo->title = (char *) malloc( strlen(title) + 1); + if (!lo->title) { + printf("NewListObj: Error malloc'ing lo->title\n"); + exit(-1); + } + strcpy(lo->title, title); + lo->name = list; + lo->y = y; + lo->x = x; + lo->w = w; + lo->h = h; + lo->n = n; + lo->scroll = 0; + lo->sel = 0; + lo->elt = listelt; + lo->win = win; + + /* Draw the object on the screen */ + RefreshListObj(lo); + + return(lo); +} /* NewListObj() */ + +void +UpdateListObj(ListObj *lo, char **list, int n) +/* + * Desc: Update the list in the listobject with the provided list + * Pre: lo->name "has been allocated" + * (A i: 0<=i<lo->n: "lo->name[i] has been allocated") + */ +{ + int i; + + /* Free the current names */ + if (lo->name != NULL) { + for (i=0; i<lo->n; i++) { + free(lo->name[i]); + } + free(lo->name); + } + + /* Rewrite the list in the object */ + lo->name = list; + lo->n = n; + lo->scroll = 0; + lo->sel = 0; + + /* Draw the object on the screen */ + RefreshListObj(lo); + + return; +} /* UpdateListObj() */ + +int +SelectListObj(ListObj *lo) +/* + * Desc: get a listname (or listnames), TAB to move on, or ESC ESC to exit + * Pre: lo->n >= 1 + */ +{ + int key, sel_x, sel_y; + char tmp[MAXPATHLEN]; + char perc[4]; + + sel_x = lo->x+1; + sel_y = lo->y + 2 + lo->sel - lo->scroll; + + if (lo->n == 0) return(SEL_TAB); + + keypad(lo->win, TRUE); + + /* Draw current selection in inverse video */ + wmove(lo->win, sel_y, sel_x); + wattrset(lo->win, item_selected_attr); + waddstr(lo->win, lo->name[lo->sel]); + + key = wgetch(lo->win); + while ((key != '\t') && (key != '\n') && (key != '\r') + && (key != ESC) && (key != KEY_F(1)) && (key != '?')) { + /* first draw current item in normal video */ + wmove(lo->win, sel_y, sel_x); + wattrset(lo->win, item_attr); + if (strlen(lo->name[lo->sel]) > lo->w - 2) { + strncpy(tmp, lo->name[lo->sel], lo->w - 2); + tmp[lo->w - 2] = 0; + waddstr(lo->win, tmp); + } else { + waddstr(lo->win, lo->name[lo->sel]); + } + + switch (key) { + case KEY_DOWN: + case ctrl('n'): + if (sel_y < lo->y + lo->h-1) { + if (lo->sel < lo->n-1) { + sel_y++; + lo->sel++; + } + } else { + if (lo->sel < lo->n-1) { + lo->sel++; + lo->scroll++; + DrawNames(lo); + wrefresh(lo->win); + } + } + break; + case KEY_UP: + case ctrl('p'): + if (sel_y > lo->y+2) { + if (lo->sel > 0) { + sel_y--; + lo->sel--; + } + } else { + if (lo->sel > 0) { + lo->sel--; + lo->scroll--; + DrawNames(lo); + wrefresh(lo->win); + } + } + break; + case KEY_HOME: + case ctrl('a'): + lo->sel = 0; + lo->scroll = 0; + sel_y = lo->y + 2; + DrawNames(lo); + wrefresh(lo->win); + break; + case KEY_END: + case ctrl('e'): + if (lo->n < lo->h - 3) { + lo->sel = lo->n-1; + lo->scroll = 0; + sel_y = lo->y + 2 + lo->sel - lo->scroll; + } else { + /* more than one page of list */ + lo->sel = lo->n-1; + lo->scroll = lo->n-1 - (lo->h-3); + sel_y = lo->y + 2 + lo->sel - lo->scroll; + DrawNames(lo); + wrefresh(lo->win); + } + break; + case KEY_NPAGE: + case ctrl('f'): + lo->sel += lo->h - 2; + if (lo->sel >= lo->n) lo->sel = lo->n - 1; + lo->scroll += lo->h - 2; + if (lo->scroll >= lo->n - 1) lo->scroll = lo->n - 1; + if (lo->scroll < 0) lo->scroll = 0; + sel_y = lo->y + 2 + lo->sel - lo->scroll; + DrawNames(lo); + wrefresh(lo->win); + break; + case KEY_PPAGE: + case ctrl('b'): + lo->sel -= lo->h - 2; + if (lo->sel < 0) lo->sel = 0; + lo->scroll -= lo->h - 2; + if (lo->scroll < 0) lo->scroll = 0; + sel_y = lo->y + 2 + lo->sel - lo->scroll; + DrawNames(lo); + wrefresh(lo->win); + break; + } + /* Draw % indication */ + sprintf(perc, "(%3d%%)", MIN(100, (int) + (100 * (lo->sel+lo->h - 2) / MAX(1, lo->n)))); + wmove(lo->win, lo->y + lo->h, lo->x + lo->w - 8); + wattrset(lo->win, dialog_attr); + waddstr(lo->win, perc); + + /* draw current item in inverse */ + wmove(lo->win, sel_y, sel_x); + wattrset(lo->win, item_selected_attr); + if (strlen(lo->name[lo->sel]) > lo->w - 2) { + /* when printing in inverse video show the last characters in the */ + /* name that will fit in the window */ + strncpy(tmp, + lo->name[lo->sel] + strlen(lo->name[lo->sel]) - (lo->w - 2), + lo->w - 2); + tmp[lo->w - 2] = 0; + waddstr(lo->win, tmp); + } else { + waddstr(lo->win, lo->name[lo->sel]); + } + key = wgetch(lo->win); + } + + if (key == ESC) { + return(SEL_ESC); + } + if (key == '\t') { + return(SEL_TAB); + } + if ((key == KEY_BTAB) || (key == ctrl('b'))) { + return(SEL_BACKTAB); + } + if ((key == '\n') || (key == '\r')) { + strcpy(lo->elt, lo->name[lo->sel]); + return(SEL_CR); + } + return(key); +} /* SelectListObj() */ + +void +DelListObj(ListObj *lo) +/* + * Desc: Free the space occupied by the listobject + */ +{ + int i; + + free(lo->title); + if (lo->name != NULL) { + for (i=0; i<lo->n; i++) { + free(lo->name[i]); + } + free(lo->name); + } + + free(lo); + +} /* DelListObj() */ + + +/*********************************************************************** + * + * ButtonObj routines + * + ***********************************************************************/ + + +void +RefreshButtonObj(ButtonObj *bo) +/* + * Desc: redraw the button + */ +{ + draw_box(bo->win, bo->y, bo->x, 3, bo->w, dialog_attr, border_attr); + print_button(bo->win, bo->title, bo->y+1, bo->x+2, FALSE); + + return; +} /* RefreshButtonObj() */ + +ButtonObj * +NewButtonObj(WINDOW *win, char *title, int *pushed, int y, int x) +/* + * Desc: Create a new button object + */ +{ + ButtonObj *bo; + + bo = (ButtonObj *) malloc( sizeof(ButtonObj) ); + + bo->win = win; + bo->title = (char *) malloc( strlen(title) + 1); + strcpy(bo->title, title); + bo->x = x; + bo->y = y; + bo->w = strlen(title) + 6; + bo->h = 3; + bo->pushed = pushed; + + RefreshButtonObj(bo); + + return(bo); +} /* NewButtonObj() */ + +int +SelectButtonObj(ButtonObj *bo) +/* + * Desc: Wait for buttonpresses or TAB's to move on, or ESC ESC + */ +{ + int key; + + print_button(bo->win, bo->title, bo->y+1, bo->x+2, TRUE); + wmove(bo->win, bo->y+1, bo->x+(bo->w/2)-1); + key = wgetch(bo->win); + print_button(bo->win, bo->title, bo->y+1, bo->x+2, FALSE); + switch(key) { + case '\t': + return(SEL_TAB); + break; + case KEY_BTAB: + case ctrl('b'): + return(SEL_BACKTAB); + case '\n': + *(bo->pushed) = TRUE; + return(SEL_BUTTON); + break; + case ESC: + return(SEL_ESC); + break; + default: + return(key); + break; + } +} /* SelectButtonObj() */ + +void +DelButtonObj(ButtonObj *bo) +/* + * Desc: Free the space occupied by <bo> + */ +{ + free(bo->title); + free(bo); + + return; +} /* DelButtonObj() */ diff --git a/gnu/lib/libdialog/ui_objects.h b/gnu/lib/libdialog/ui_objects.h new file mode 100644 index 0000000..59f4ae9 --- /dev/null +++ b/gnu/lib/libdialog/ui_objects.h @@ -0,0 +1,109 @@ +/* + * Author: Marc van Kempen + * Desc: include file for UI-objects + * + * Copyright (c) 1995, Marc van Kempen + * + * All rights reserved. + * + * This software may be used, modified, copied, distributed, and + * sold, in both source and binary form provided that the above + * copyright and these terms are retained, verbatim, as the first + * lines of this file. Under no circumstances is the author + * responsible for the proper functioning of this software, nor does + * the author assume any responsibility for damages incurred with + * its use. + * + */ + +#include "dialog.h" +#include <ncurses.h> + +/*********************************************************************** + * + * Defines + * + ***********************************************************************/ + +#define ctrl(a) ((a) - 'a' + 1) + +/* the Object types */ +#define STRINGOBJ 1 +#define LISTOBJ 2 +#define BUTTONOBJ 3 + +/* the return signals from the selection routines */ +/* 1000 and higher should avoid conflicts with keys pressed */ +#define SEL_CR 1001 /* return was pressed */ +#define SEL_ESC 1002 /* ESC pressed */ +#define SEL_TAB 1003 /* TAB pressed */ +#define SEL_BACKTAB 1004 /* SHIFT-TAB pressed */ +#define SEL_BUTTON 1005 /* a button was pressed */ + +/*********************************************************************** + * + * Typedefs + * + ***********************************************************************/ + +typedef struct { + WINDOW *win; /* the window it's contained in */ + char *title; /* the prompt for the input field */ + char *s; /* initial value of the input field */ + int x, y, w, len; /* the (y, x) position of the upperleft */ + /* corner and the width <w> of the display */ + /* and length <len> of the field */ +} StringObj; + +typedef struct { + WINDOW *win; /* the windows it's contained in */ + char *title; /* the title of the list */ + char **name; /* the names of the list */ + char *elt; /* the current element in the list list[sel] */ + int x, y, w, h, n; /* dimensions of list and # of elements (n) */ + int scroll, sel; /* current position in the list */ +} ListObj; + +typedef struct { + WINDOW *win; /* the window it's contained in */ + char *title; /* title for the button */ + int x, y, w, h; /* its dimensions */ + int *pushed; /* boolean that determines wether button was pushed */ +} ButtonObj; + +typedef struct ComposeObj { + int objtype; + void *obj; + struct ComposeObj *next, *prev; +} ComposeObj; + +/********************************************************************** + * + * Prototypes + * + **********************************************************************/ + +void RefreshStringObj(StringObj *so); +StringObj *NewStringObj(WINDOW *win, char *title, char *s, + int y, int x, int w, int len); +int SelectStringObj(StringObj *so); +void DelStringObj(StringObj *so); + +void RefreshListObj(ListObj *lo); +ListObj *NewListObj(WINDOW *win, char *title, char **list, + char *listelt, int y, int x, int h, int w, int n); +void UpdateListObj(ListObj *lo, char **list, int n); +int SelectListObj(ListObj *lo); +void DelListObj(ListObj *obj); + +void RefreshButtonObj(ButtonObj *bo); +ButtonObj *NewButtonObj(WINDOW *win, char *title, int *pushed, + int y, int x); +int SelectButtonObj(ButtonObj *bo); +void DelButtonObj(ButtonObj *bo); +void AddObj(ComposeObj **Obj, int objtype, void *obj); +void FreeObj(ComposeObj *Obj); +int ReadObj(ComposeObj *Obj); +int PollObj(ComposeObj **Obj); +void DelObj(ComposeObj *Obj); + diff --git a/gnu/lib/libdialog/yesno.c b/gnu/lib/libdialog/yesno.c index 20799b6..45ff649 100644 --- a/gnu/lib/libdialog/yesno.c +++ b/gnu/lib/libdialog/yesno.c @@ -83,6 +83,8 @@ int dialog_yesno(unsigned char *title, unsigned char * prompt, int height, int w wmove(dialog, 1, 2); print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE); + display_helpline(dialog, height-1, width); + x = width/2-10; y = height-2; print_button(dialog, " No ", y, x+13, FALSE); @@ -125,6 +127,10 @@ int dialog_yesno(unsigned char *title, unsigned char * prompt, int height, int w return button; case ESC: break; + case KEY_F(1): + case '?': + display_helpfile(); + break; } } |