home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
CSAPE32.ARJ
/
SOURCE
/
CSSRC
/
HELPXREF.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-30
|
7KB
|
350 lines
/*
helpxref.c 5/5/87
% help_Xref
C-scape 3.2
Copyright (c) 1986, 1987, by Oakland Group, Inc.
ALL RIGHTS RESERVED.
Revision History:
-----------------
7/09/87 jmd fixed no fields bug.
7/16/87 jmd added first letter search.
7/25/87 jmd added data structure and colors.
8/06/87 jmd fixed "empty screen" problem
8/08/88 jmd removed vid_ calls
8/14/88 jmd now passes xref by reference
adjusted for windows, sed is no longer static
10/20/88 jmd now passes xref by value again
removed @c[] statement
11/05/88 jmd removed menu_Close
4/22/89 jmd changed border to bord
8/02/89 jmd Added mouse support
8/24/89 jmd removed dependence on bd_xref
3/28/90 jmd ansi-fied
4/03/90 jmd added additional cast to xref
8/27/90 jmd added use of ocountry struct
10/04/90 pmcm removed isprint from search
10/19/90 jmd added iarray to hold xref values
10/30/90 jmd made iarray "external" to fix realloc trouble
*/
#include <stdio.h>
#include <ctype.h>
#include "cscape.h"
#include "ostdlib.h" /* for atoi() */
#include "scancode.h"
#include "helpdecl.h"
#define RING_LEN 22 /* must be greater than 1 */
static int ringbuf[RING_LEN]; /* used to remember previous help screens */
static int top, bot;
OSTATIC void help_fkey(sed_type sed);
static field_funcs_struct help_funcs = {
FNULL,
FNULL,
help_fkey,
FNULL,
FNULL,
0
};
int help_Xref(help_type h)
/*
Cross referenced help display routine.
Looks for special cross referenced help symbols in the help text.
The syntax is "@3[word]". This means that "word" will highlighted and
will be a cross reference to message number 3. Any number of cross
references can appear in the help text. The regular C-scape commands
(@[] @p[] @c) can also be imbedded in the help text if you feel like it.
The backspace key is used to cycle back through previous screens.
A ring buffer is used to remember the previous screens.
The cross-reference values for the fields are stored in an external
iarray. This is connected to the sed data pointer.
*/
{
menu_type menu;
sed_type sed;
sed_type prevsed = NULL;
iarray ia;
int key;
char *p, *q, hold;
int mode, xref, x, fldno;
int msg = -1;
char bk_clr, reg_clr, sel_clr, bd_clr;
bd_fptr bord;
struct hx_struct *hx;
hx = (struct hx_struct *) help_GetData(h);
if (hx == NULL) {
bk_clr = ATTR_NORMAL;
reg_clr = ATTR_BOLD;
sel_clr = ATTR_REVERSE;
bd_clr = ATTR_NORMAL;
bord = FNULL;
}
else {
bk_clr = hx->bk_clr;
reg_clr = hx->reg_clr;
sel_clr = hx->sel_clr;
bd_clr = hx->bd_clr;
bord = hx->bord;
}
/* initialize ring buffer */
top = bot = 0;
while (msg != 0) {
/* create an array to hold cross reference values */
if ((ia = ia_Open(10)) == NULL) {
break;
}
if ((menu = menu_Open()) == NULL) {
ia_Close(ia);
break;
}
/* search for cross-references */
for (mode = 0, q = p = help_GetText(h); *p != '\0'; p++) {
switch (mode) {
case 0:
if (*p == '@') {
mode = 1;
}
break;
case 1:
if (*p == '@' || *p == '[' || *p == 'c' || *p == 'p') {
mode = 0;
}
else {
hold = *(p-1);
*(p-1) = '\0';
menu_Printf(menu, q);
*(p-1) = hold;
mode = 2;
q = p;
}
break;
case 2:
if (*p == '[') {
xref = atoi(q);
q = p + 1;
mode = 3;
}
break;
case 3:
if (*p == ']') {
hold = *p;
*p = '\0';
/* store xref value into iarray */
fldno = menu_GetFieldCount(menu);
ia_Put(ia, fldno, xref);
menu_Printf(menu, "@f[%s]", NULL, &help_funcs, q);
*p = hold;
q = p+1;
mode = 0;
}
break;
default:
break;
}
}
menu_Printf(menu, q);
menu_Flush(menu);
if ((sed = sed_Open(menu)) == NULL) {
ia_Close(ia);
menu_Destroy(menu);
break;
}
/* place the iarray into the sed's generic data pointer */
sed_SetData(sed, (VOID *) ia);
sed_SetMouse(sed, sedmou_GreedyTrack);
sed_SetColors(sed, reg_clr, bk_clr, sel_clr);
if (bord != FNULL) {
sed_SetBorder(sed, bord);
sed_SetBorderColor(sed, bd_clr);
sed_SetBorderTitle(sed, help_GetTitle(h));
}
/* adjust height and width to fill the display */
x = sed_GetBorderHeight(sed) - sed_GetHeight(sed);
sed_SetHeight(sed, disp_GetHeight() - x);
x = sed_GetBorderWidth(sed) - sed_GetWidth(sed);
sed_SetWidth(sed, disp_GetWidth() - x);
sed_SetPosition(sed, 0, 0);
sed_Repaint(sed);
/* remove previous sed */
if (prevsed != NULL) {
if (sed_GetData(prevsed) != NULL) {
ia_Close((iarray) sed_GetData(prevsed));
}
sed_Close(prevsed);
prevsed = NULL;
}
sed_BorderPrompt(sed, ocountry.helpxrefmsg);
if (sed_GetFieldCount(sed) > 0) {
msg = sed_Go(sed);
}
else {
/* no fields... wait for ESC to be pressed */
while(TRUE){
key = kb_Read();
if (key == ESC) {
msg = 0;
break;
}
if (key == BACKSPACE) {
msg = -1;
break;
}
}
}
/* save old sed until new one is created to avoid unecessary painting */
prevsed = sed;
if (msg == -1) {
/* look up previous screen */
if (top != bot) {
top = (top == 0) ? RING_LEN - 1 : top - 1;
if (!help_LookUp(ringbuf[top])) {
break;
}
}
}
else if (msg > 0) {
/* adjust ring buffer */
ringbuf[top++] = help_GetMessage(h);
top %= RING_LEN;
if (top == bot) {
bot++;
bot %= RING_LEN;
}
if (!help_LookUp(msg)) {
break;
}
}
}
/* close the sed */
if (prevsed != NULL) {
if (sed_GetData(prevsed) != NULL) {
ia_Close((iarray) sed_GetData(prevsed));
}
sed_Close(prevsed);
}
return(0);
}
static void help_fkey(sed_type sed)
/*
fkey function for x-referenced help screen.
return the following in the baton:
-1) put up previous help screen
0) exit help system
n) put up help message n
*/
{
int scancode, letter, choice, x;
iarray ia;
switch(scancode = kb_Read()) {
case MOU_HERE:
break;
case MOU_THERE:
case ESC:
sed_SetBaton(sed, 0);
sed_ToggleExit(sed);
break;
case BACKSPACE:
/* look up the previous message, if there is one */
if (top != bot) {
sed_SetBaton(sed, -1);
sed_ToggleExit(sed);
}
break;
case MOU_CLICK:
case ENTER:
/* get the xref value from external iarray */
ia = (iarray) sed_GetData(sed);
x = ia_Get(ia, sed_GetFieldNo(sed));
if (x == -1 && top == bot) {
/* ignore request for previous screen */
break;
}
sed_SetBaton(sed, x);
sed_ToggleExit(sed);
break;
case HOME:
sed_GotoFirstField(sed);
break;
case END:
sed_GotoLastField(sed);
break;
case UP:
if (sed_UpField(sed) == SED_STUCK) {
sed_GotoLastField(sed);
}
break;
case DOWN:
if (sed_DownField(sed) == SED_STUCK) {
sed_GotoFirstField(sed);
}
break;
case LEFT:
if (sed_DecField(sed) == SED_STUCK) {
sed_GotoLastField(sed);
}
break;
case RIGHT:
if (sed_IncField(sed) == SED_STUCK) {
sed_GotoFirstField(sed);
}
break;
default:
/* do letter search */
letter = ascii(scancode);
if ((choice = sed_SearchMerge(sed, (char)letter)) != -1) {
sed_GotoField(sed, choice);
}
break;
}
}