/* If any gophers to display (screen can be blank), count the number
of pages. If there is a remainder greater than zero, add one page */
#define PAGECALC(x,y) (y) ? (x/y) + ((x%y)>0) : 1
switch(type)
{
case A_DIRECTORY:
maxlength--;
break;
case A_SOUND:
maxlength -= 3;
break;
case A_INDEX:
maxlength -=4;
break;
case A_PDF:
case A_CSO:
case A_TELNET:
case A_UNIXBIN:
case A_MACHEX:
maxlength -=6;
break;
case A_TN3270:
case A_MIME:
case A_HTML:
maxlength -= 7;
break;
case A_MOVIE:
maxlength -= 8;
break;
case A_PCBIN:
maxlength -=9;
break;
case A_GIF:
case A_IMAGE:
maxlength -= 10;
}
if (d==NULL)
d = "error";
if((m = strlen(d)) <= maxlength)
printw(" %s", d);
else {
/*** Cut out the middle bits **/
if ((c = strchr(d, '/'))!=NULL && (maxlength > (c-d))) {
n = c - d;
strncpy(temp, d, n);
strcpy(temp + n, "..");
strcat(temp, d + (m + n - maxlength));
printw(" %s", temp);
} else {
/** Trunc it.. **/
strcpy(temp, d);
temp[maxlength] ='\0';
printw(" %s..", temp);
}
}
switch(type)
{
case A_DIRECTORY:
addch('/');
break;
case A_CSO:
addstr(" <CSO>");
break;
case A_TN3270:
addstr(" <3270>");
break;
case A_TELNET:
addstr(" <TEL>");
break;
case A_INDEX:
addstr(" <?>");
break;
case A_SOUND:
addstr(" <)"); /** It's supposed to look like a speaker! **/
break;
case A_PCBIN:
addstr(" <PC Bin>");
break;
case A_UNIXBIN:
addstr(" <Bin>");
break;
case A_IMAGE:
case A_GIF:
addstr(" <Picture>");
break;
case A_MACHEX:
addstr(" <HQX>");
break;
case A_MIME:
addstr(" <MIME>");
break;
case A_HTML:
addstr(" <HTML>");
break;
case A_MOVIE:
addstr(" <Movie>");
break;
case A_PDF:
addstr(" <PDF>");
break;
}
if (GSisAsk(gs)) {
/* Add string in two parts to avoid ANSI C turning "??>" into a
trigraph for '}' */
addstr(" <?");
addstr("?>");
}
}
/*
** Man is this ugly.
*/
void
Display_Dir_Page(gopherdir, iNewLine, nNewPage, nMaxPages, iPageLen, iLastPageLen)
GopherDirObj *gopherdir;
int iNewLine;
int nNewPage, nMaxPages, iPageLen, iLastPageLen;
{
int i, iLoop, iOffset;
boolean dogplus = FALSE;
GopherObj *gs;
/*** Clear the screen and redraw the top line **/
clear();
Draw_Banner();
/** Draw the menu **/
iLoop = (nNewPage == nMaxPages) && iLastPageLen ? iLastPageLen : iPageLen;
/** Look at the first item in the directory to decide whether to
use a gopher+ display of the menu ***/
for (i= 0, iOffset = (nNewPage-1) * iPageLen; i <iLoop; i++, iOffset++) {
gs = GDgetEntry(gopherdir, iOffset);
move(MENULINE(i+1), 6);
if (GSgetType(gs) == A_INFO) {
addch(' ');
addch(' ');
if (iOffset > 9)
addch(' ');
if (iOffset >99)
addch(' ');
} else {
printw("%d.", iOffset +1);
}
if (iOffset + 1 < 10)
addch(' ');
/* scline - Screen line relocator.
* Returns the line resulting from choice */
int
scline( iOldGopher, iNewGopher, gophersdir)
int iOldGopher; /* Which gopher previously displayed */
int iNewGopher; /* New gopher to be displayed */
GopherDirObj *gophersdir;
{
int iPageLen, iLastPageLen; /* Length of normal, final pages */
int nMaxPages, nNewPage, nOldPage; /* Natural numbers */
int iOldLine, iNewLine; /* Screen locations */
char sPagenum[40];
int iMaxGophers;
GopherObj *tempGopher;
int Direction = 1;
iMaxGophers = GDgetNumitems(gophersdir);
if (iNewGopher==0)
iNewGopher = GDgetNumitems(gophersdir);
if (iNewGopher > iMaxGophers)
iNewGopher = 1;
if (iNewGopher == iOldGopher - 1)
Direction = -1;
do {
tempGopher = GDgetEntry(gophersdir, iNewGopher-1);
if (GSgetType(tempGopher) != A_INFO &&
GSgetType(tempGopher) != A_ERROR)
break;
iNewGopher += Direction;
if (iNewGopher > iMaxGophers) {
iNewGopher = 1;
if (iOldGopher < 1)
break;
}
if (iNewGopher < 1)
iNewGopher = iMaxGophers;
if (iOldGopher > iMaxGophers)
break;
} while (iNewGopher != iOldGopher);
iPageLen = LINES-6; /* Number of menu lines possible per page */
nMaxPages = PAGECALC(iMaxGophers, iPageLen); /* Total number of pages */
nOldPage = PAGECALC(iOldGopher, iPageLen);
nNewPage = PAGECALC(iNewGopher, iPageLen);
if ((nNewPage < 1) || (nNewPage > nMaxPages)) /* It won't work , make*/
return(iOldGopher); /* no changes */
iLastPageLen = iMaxGophers % iPageLen;
/* Lines on last page */
iOldLine = iOldGopher - ((nOldPage-1)*iPageLen);/* Old Screen location */
iNewLine = iNewGopher - ((nNewPage-1)*iPageLen);/* New Screen location */
if ((iNewLine < 0) || (iNewLine > iPageLen))
return(iOldGopher);
if (nOldPage != nNewPage) {
Display_Dir_Page(gophersdir,
iNewLine, nNewPage, nMaxPages, iPageLen, iLastPageLen);
/*** Draw the title ***/
CURcenterline(CursesScreen, stdscr, GDgetTitle(gophersdir), 2, COLS, FALSE);
}
/*
** This routine draws a numbered menu
** from a gopherdirobj
**
** It returns the number that the user selected, or it returns
** zero if the user decided to cancel.
**
** RETURN Code isnt used currently anywhere!
*/
int
GetMenu(gd, typedchar, redisplay)
GopherDirObj *gd; /** where the items are **/
int *typedchar;
boolean redisplay;
{
int ch; /* Input character */
int iItem; /* Display line */
static int iNewItem=1;
char sLinenum[5]; /* Used when going to a specific line */
int numitems;
/** variables for searching **/
char search1[100];
char *search2;
int sfound;
int i;
search1[0] = '\0'; /* search string will be remembered so init now */
/* Note letters not in here are picked up by default and passed back
to caller for processing */
switch(ch)
{
case '\004':
DEBUG = 1 - DEBUG;
break;
case 'j':
case '\016':
case KEY_DOWN:
iNewItem = iItem + 1; /* Advance down the page */
break;
case 'k':
case '\020': /*** For those emacs dudes **/
case KEY_UP:
iNewItem = iItem - 1; /* Back up */
break;
case '+': /** Like in elm **/
case '>': /** Like in nn **/
case ' ': /** Like in the pager ***/
case KEY_NPAGE:
/*** Go down a page ***/
iNewItem = iItem + (LINES -6);
if (iNewItem > numitems)
iNewItem = numitems;
break;
case '-':
case '<':
case KEY_PPAGE:
case 'b': /*** Like in the pager ***/
/*** Go up a page ***/
for (i=iItem; i < numitems && sfound==0; i++) {
search2 = GSgetTitle(GDgetEntry(gd, i));
if (strcasestr(search2, search1) != NULL ) {
iNewItem = i+1;
sfound = 1;
}
}
/* if it wasn't found after the current line start
from the beginning again
*/