2001-01-04 22:57:58 +03:00
|
|
|
#include <cdk.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* $Author: garbled $
|
2001-01-04 23:15:29 +03:00
|
|
|
* $Date: 2001/01/04 20:15:30 $
|
|
|
|
* $Revision: 1.2 $
|
2001-01-04 22:57:58 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Declare file local prototypes.
|
|
|
|
*/
|
|
|
|
static void CDKEntryCallBack (CDKENTRY *entry, chtype character);
|
|
|
|
static void drawCDKEntryField (CDKENTRY *entry);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Declare file local variables.
|
|
|
|
*/
|
|
|
|
extern char *GPasteBuffer;
|
|
|
|
|
|
|
|
DeclareCDKObjects(my_funcs,Entry);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This creates a pointer to an entry widget.
|
|
|
|
*/
|
|
|
|
CDKENTRY *newCDKEntry (CDKSCREEN *cdkscreen, int xplace, int yplace, char *title, char *label, chtype fieldAttr, chtype filler, EDisplayType dispType, int fWidth, int min, int max, boolean Box, boolean shadow)
|
|
|
|
{
|
|
|
|
/* Set up some variables. */
|
|
|
|
CDKENTRY *entry = newCDKObject(CDKENTRY, &my_funcs);
|
|
|
|
chtype *holder = 0;
|
|
|
|
int parentWidth = getmaxx(cdkscreen->window);
|
|
|
|
int parentHeight = getmaxy(cdkscreen->window);
|
|
|
|
int fieldWidth = fWidth;
|
|
|
|
int boxWidth = 0;
|
|
|
|
int boxHeight = 3;
|
|
|
|
int maxWidth = INT_MIN;
|
|
|
|
int xpos = xplace;
|
|
|
|
int ypos = yplace;
|
|
|
|
int junk = 0;
|
|
|
|
int horizontalAdjust = 0;
|
|
|
|
char **temp = 0;
|
|
|
|
int x, len, junk2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the fieldWidth is a negative value, the fieldWidth will
|
|
|
|
* be COLS-fieldWidth, otherwise, the fieldWidth will be the
|
|
|
|
* given width.
|
|
|
|
*/
|
|
|
|
fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0);
|
|
|
|
boxWidth = fieldWidth + 2;
|
|
|
|
|
|
|
|
/* Set some basic values of the entry field. */
|
|
|
|
entry->label = 0;
|
|
|
|
entry->labelLen = 0;
|
|
|
|
entry->labelWin = 0;
|
|
|
|
entry->titleLines = 0;
|
|
|
|
|
|
|
|
/* Translate the label char *pointer to a chtype pointer. */
|
|
|
|
if (label != 0)
|
|
|
|
{
|
|
|
|
entry->label = char2Chtype (label, &entry->labelLen, &junk);
|
|
|
|
boxWidth += entry->labelLen;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Translate the char * items to chtype * */
|
|
|
|
if (title != 0)
|
|
|
|
{
|
|
|
|
/* We need to split the title on \n. */
|
|
|
|
temp = CDKsplitString (title, '\n');
|
|
|
|
entry->titleLines = CDKcountStrings (temp);
|
|
|
|
|
|
|
|
/* We need to determine the widest title line. */
|
|
|
|
for (x=0; x < entry->titleLines; x++)
|
|
|
|
{
|
|
|
|
holder = char2Chtype (temp[x], &len, &junk2);
|
|
|
|
maxWidth = MAXIMUM (maxWidth, len);
|
|
|
|
freeChtype (holder);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If one of the title lines is wider than the field and the label,
|
|
|
|
* the box width will expand to accomodate.
|
|
|
|
*/
|
|
|
|
if (maxWidth > boxWidth)
|
|
|
|
{
|
|
|
|
horizontalAdjust = (int)((maxWidth - boxWidth) / 2) + 1;
|
|
|
|
boxWidth = maxWidth + 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* For each line in the title, convert from char * to chtype * */
|
|
|
|
for (x=0; x < entry->titleLines; x++)
|
|
|
|
{
|
|
|
|
entry->title[x] = char2Chtype (temp[x], &entry->titleLen[x], &entry->titlePos[x]);
|
|
|
|
entry->titlePos[x] = justifyString (boxWidth - 2, entry->titleLen[x], entry->titlePos[x]);
|
|
|
|
}
|
|
|
|
CDKfreeStrings(temp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* No title? Set the required variables. */
|
|
|
|
entry->titleLines = 0;
|
|
|
|
}
|
|
|
|
boxHeight += entry->titleLines;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure we didn't extend beyond the dimensions of the window.
|
|
|
|
*/
|
|
|
|
boxWidth = MINIMUM (boxWidth, parentWidth);
|
|
|
|
boxHeight = MINIMUM (boxHeight, parentHeight);
|
|
|
|
fieldWidth = (fieldWidth > (boxWidth - entry->labelLen - 2) ? (boxWidth - entry->labelLen - 2) : fieldWidth);
|
|
|
|
|
|
|
|
/* Rejustify the x and y positions if we need to. */
|
|
|
|
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
|
|
|
|
|
|
|
|
/* Make the label window. */
|
|
|
|
entry->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
|
|
|
|
|
|
|
|
/* Is the window null? */
|
|
|
|
if (entry->win == 0)
|
|
|
|
{
|
|
|
|
/* Clean up the pointers. */
|
|
|
|
freeChtype (entry->label);
|
|
|
|
free (entry);
|
|
|
|
|
|
|
|
/* Exit with null. */
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
keypad (entry->win, TRUE);
|
|
|
|
|
|
|
|
if (entry->titleLines > 0)
|
|
|
|
{
|
|
|
|
/* Make the title window. */
|
|
|
|
entry->titleWin = subwin (entry->win,
|
|
|
|
entry->titleLines, boxWidth - 2,
|
|
|
|
ypos + 1, xpos + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make the label win, if we need to. */
|
|
|
|
if (label != 0)
|
|
|
|
{
|
|
|
|
entry->labelWin = subwin (entry->win, 1, entry->labelLen,
|
|
|
|
ypos + entry->titleLines + 1,
|
|
|
|
xpos + horizontalAdjust + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make the field window. */
|
|
|
|
entry->fieldWin = subwin (entry->win, 1, fieldWidth,
|
|
|
|
ypos + entry->titleLines + 1,
|
|
|
|
xpos + entry->labelLen + horizontalAdjust + 1);
|
|
|
|
keypad (entry->fieldWin, TRUE);
|
|
|
|
|
|
|
|
/* Make room for the info char * pointer. */
|
|
|
|
entry->infoWidth = max + 3;
|
|
|
|
entry->info = (char *)malloc (entry->infoWidth);
|
|
|
|
cleanChar (entry->info, entry->infoWidth, '\0');
|
|
|
|
|
|
|
|
/* Set up the rest of the structure. */
|
|
|
|
ScreenOf(entry) = cdkscreen;
|
|
|
|
entry->parent = cdkscreen->window;
|
|
|
|
entry->fieldAttr = fieldAttr;
|
|
|
|
entry->fieldWidth = fieldWidth;
|
|
|
|
entry->filler = filler;
|
|
|
|
entry->hidden = filler;
|
|
|
|
ObjOf(entry)->box = Box;
|
|
|
|
entry->shadow = shadow;
|
|
|
|
entry->screenCol = 0;
|
|
|
|
entry->leftChar = 0;
|
|
|
|
entry->min = min;
|
|
|
|
entry->max = max;
|
|
|
|
entry->boxWidth = boxWidth;
|
|
|
|
entry->boxHeight = boxHeight;
|
|
|
|
entry->ULChar = ACS_ULCORNER;
|
|
|
|
entry->URChar = ACS_URCORNER;
|
|
|
|
entry->LLChar = ACS_LLCORNER;
|
|
|
|
entry->LRChar = ACS_LRCORNER;
|
|
|
|
entry->HChar = ACS_HLINE;
|
|
|
|
entry->VChar = ACS_VLINE;
|
|
|
|
entry->BoxAttrib = A_NORMAL;
|
|
|
|
entry->exitType = vNEVER_ACTIVATED;
|
|
|
|
entry->dispType = dispType;
|
|
|
|
entry->callbackfn = (void *)&CDKEntryCallBack;
|
|
|
|
entry->preProcessFunction = 0;
|
|
|
|
entry->preProcessData = 0;
|
|
|
|
entry->postProcessFunction = 0;
|
|
|
|
entry->postProcessData = 0;
|
|
|
|
|
|
|
|
/* Clean the key bindings. */
|
|
|
|
cleanCDKObjectBindings (vENTRY, entry);
|
|
|
|
|
|
|
|
/* Register this baby. */
|
|
|
|
registerCDKObject (cdkscreen, vENTRY, entry);
|
|
|
|
|
|
|
|
/* Return the pointer to the structure. */
|
|
|
|
return (entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This means you want to use the given entry field. It takes input
|
|
|
|
* from the keyboard, and when its done, it fills the entry info
|
|
|
|
* element of the structure with what was typed.
|
|
|
|
*/
|
|
|
|
char *activateCDKEntry (CDKENTRY *entry, chtype *actions)
|
|
|
|
{
|
|
|
|
/* Declare local variables. */
|
|
|
|
chtype input = 0;
|
|
|
|
char *ret = 0;
|
|
|
|
|
|
|
|
/* Draw the widget. */
|
|
|
|
drawCDKEntry (entry, ObjOf(entry)->box);
|
|
|
|
|
|
|
|
/* Check if 'actions' is null. */
|
|
|
|
if (actions == 0)
|
|
|
|
{
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
/* Get the input. */
|
|
|
|
wrefresh (entry->fieldWin);
|
|
|
|
input = wgetch (entry->fieldWin);
|
|
|
|
|
|
|
|
/* Inject the character into the widget. */
|
|
|
|
ret = injectCDKEntry (entry, input);
|
|
|
|
if (entry->exitType != vEARLY_EXIT)
|
|
|
|
{
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int length = chlen (actions);
|
|
|
|
int x =0;
|
|
|
|
|
|
|
|
/* Inject each character one at a time. */
|
|
|
|
for (x=0; x < length; x++)
|
|
|
|
{
|
|
|
|
ret = injectCDKEntry (entry, actions[x]);
|
|
|
|
if (entry->exitType != vEARLY_EXIT)
|
|
|
|
{
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure we return the correct info. */
|
|
|
|
if (entry->exitType == vNORMAL)
|
|
|
|
{
|
|
|
|
return entry->info;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This injects a single character into the widget.
|
|
|
|
*/
|
|
|
|
char *injectCDKEntry (CDKENTRY *entry, chtype input)
|
|
|
|
{
|
|
|
|
/* Declare local variables. */
|
|
|
|
int ppReturn = 1;
|
|
|
|
int temp, x, charCount, stringLen;
|
|
|
|
char holder;
|
|
|
|
|
|
|
|
/* Check if there is a pre-process function to be called. */
|
|
|
|
if (entry->preProcessFunction != 0)
|
|
|
|
{
|
|
|
|
/* Call the pre-process function. */
|
|
|
|
ppReturn = ((PROCESSFN)(entry->preProcessFunction)) (vENTRY, entry, entry->preProcessData, input);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Should we continue? */
|
|
|
|
if (ppReturn != 0)
|
|
|
|
{
|
|
|
|
/* Check a predefined binding... */
|
|
|
|
if (checkCDKObjectBind (vENTRY, entry, input) != 0)
|
|
|
|
{
|
|
|
|
entry->exitType = vEARLY_EXIT;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (input)
|
|
|
|
{
|
|
|
|
case KEY_UP :
|
|
|
|
case KEY_DOWN :
|
|
|
|
Beep();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CDK_BEGOFLINE :
|
|
|
|
entry->leftChar = 0;
|
|
|
|
entry->screenCol = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CDK_TRANSPOSE :
|
|
|
|
stringLen = (int)strlen (entry->info);
|
|
|
|
temp = entry->leftChar + entry->screenCol;
|
|
|
|
if (temp >= stringLen-1)
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
holder = entry->info[temp];
|
|
|
|
entry->info[temp] = entry->info[temp + 1];
|
|
|
|
entry->info[temp + 1] = holder;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CDK_ENDOFLINE :
|
|
|
|
stringLen = (int)strlen (entry->info);
|
|
|
|
if (stringLen >= entry->fieldWidth)
|
|
|
|
{
|
|
|
|
charCount = (int)(entry->fieldWidth * .8);
|
|
|
|
entry->leftChar = stringLen - charCount;
|
|
|
|
entry->screenCol = charCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
entry->leftChar = 0;
|
|
|
|
entry->screenCol = stringLen;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_LEFT :
|
|
|
|
case CDK_BACKCHAR :
|
|
|
|
if (entry->screenCol == 0)
|
|
|
|
{
|
|
|
|
if (entry->leftChar == 0)
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Scroll left. */
|
|
|
|
entry->leftChar--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
--entry->screenCol;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_RIGHT :
|
|
|
|
case CDK_FORCHAR :
|
|
|
|
temp = (int)strlen (entry->info);
|
|
|
|
if (entry->screenCol == entry->fieldWidth-1)
|
|
|
|
{
|
|
|
|
if ((entry->leftChar + entry->screenCol + 1) == temp)
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Scroll to the right. */
|
|
|
|
entry->leftChar++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Move right. */
|
|
|
|
if ((entry->leftChar + entry->screenCol) == temp)
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
++entry->screenCol;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DELETE :
|
|
|
|
case CONTROL('H') :
|
|
|
|
case KEY_BACKSPACE :
|
|
|
|
case KEY_DC :
|
|
|
|
if (entry->dispType == vVIEWONLY)
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Get the length of the widget information. */
|
|
|
|
int infoLength = (int)strlen (entry->info);
|
|
|
|
if ((entry->leftChar + entry->screenCol) < infoLength)
|
|
|
|
{
|
|
|
|
/* We are deleteing from inside the string. */
|
|
|
|
int currPos = entry->screenCol + entry->leftChar;
|
|
|
|
for (x=currPos; x < infoLength; x++)
|
|
|
|
{
|
|
|
|
entry->info[x] = entry->info[x + 1];
|
|
|
|
}
|
|
|
|
entry->info[infoLength] = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We are deleting from the end of the string. */
|
|
|
|
if (infoLength > 0)
|
|
|
|
{
|
|
|
|
/* Update the character pointer. */
|
|
|
|
entry->info[infoLength-1] = '\0';
|
|
|
|
infoLength--;
|
|
|
|
|
|
|
|
/* Adjust the cursor. */
|
|
|
|
if (entry->screenCol > 0)
|
|
|
|
{
|
|
|
|
entry->screenCol--;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If we deleted the last character on the
|
|
|
|
* screen and the information has scrolled,
|
|
|
|
* adjust the entry field to show the info.
|
|
|
|
*/
|
|
|
|
if (entry->leftChar > 0 && entry->screenCol == 1)
|
|
|
|
{
|
|
|
|
if (infoLength < entry->fieldWidth-1)
|
|
|
|
{
|
|
|
|
entry->leftChar = 0;
|
|
|
|
entry->screenCol = infoLength;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
entry->leftChar -= (entry->fieldWidth-3);
|
|
|
|
entry->screenCol = entry->fieldWidth-2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_ESC :
|
|
|
|
entry->exitType = vESCAPE_HIT;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case CDK_ERASE :
|
|
|
|
if ((int)strlen(entry->info) != 0)
|
|
|
|
{
|
|
|
|
cleanCDKEntry (entry);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CDK_CUT:
|
|
|
|
if ((int)strlen(entry->info) != 0)
|
|
|
|
{
|
|
|
|
freeChar (GPasteBuffer);
|
|
|
|
GPasteBuffer = copyChar (entry->info);
|
|
|
|
cleanCDKEntry (entry);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CDK_COPY:
|
|
|
|
if ((int)strlen(entry->info) != 0)
|
|
|
|
{
|
|
|
|
freeChar (GPasteBuffer);
|
|
|
|
GPasteBuffer = copyChar (entry->info);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CDK_PASTE:
|
|
|
|
if (GPasteBuffer != 0)
|
|
|
|
{
|
|
|
|
setCDKEntryValue (entry, GPasteBuffer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2001-01-04 23:15:29 +03:00
|
|
|
case KEY_RETURN : case KEY_TAB : case KEY_ENTER : case KEY_CR :
|
2001-01-04 22:57:58 +03:00
|
|
|
if ((int)strlen (entry->info) >= entry->min)
|
|
|
|
{
|
|
|
|
entry->exitType = vNORMAL;
|
|
|
|
return (entry->info);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CDK_REFRESH :
|
|
|
|
eraseCDKScreen (ScreenOf(entry));
|
|
|
|
refreshCDKScreen (ScreenOf(entry));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default :
|
|
|
|
((ENTRYCB)entry->callbackfn)(entry, input);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Should we do a post-process? */
|
|
|
|
if (entry->postProcessFunction != 0)
|
|
|
|
{
|
|
|
|
((PROCESSFN)(entry->postProcessFunction)) (vENTRY, entry, entry->postProcessData, input);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Refresh the entry field. */
|
|
|
|
drawCDKEntryField (entry);
|
|
|
|
|
|
|
|
/* Return and indicate that we exited early. */
|
|
|
|
entry->exitType = vEARLY_EXIT;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This moves the entry field to the given location.
|
|
|
|
*/
|
|
|
|
static void _moveCDKEntry (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
|
|
|
|
{
|
|
|
|
CDKENTRY *entry = (CDKENTRY *)object;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If this is a relative move, then we will adjust where we want
|
|
|
|
* to move to.
|
|
|
|
*/
|
|
|
|
if (relative)
|
|
|
|
{
|
|
|
|
xplace += getbegx(entry->win);
|
|
|
|
yplace += getbegy(entry->win);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Adjust the window if we need to. */
|
|
|
|
alignxy (WindowOf(entry), &xplace, &yplace, entry->boxWidth, entry->boxHeight);
|
|
|
|
|
|
|
|
/* Move the window to the new location. */
|
|
|
|
moveCursesWindow(entry->win, xplace, yplace);
|
|
|
|
|
|
|
|
/* Redraw the window, if they asked for it. */
|
|
|
|
if (refresh_flag)
|
|
|
|
{
|
|
|
|
drawCDKEntry (entry, ObjOf(entry)->box);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This is a generic character parser for the entry field. It is used as a
|
|
|
|
* callback function, so any personal modifications can be made by creating
|
|
|
|
* a new function and calling the activation with its name.
|
|
|
|
*/
|
|
|
|
static void CDKEntryCallBack (CDKENTRY *entry, chtype character)
|
|
|
|
{
|
|
|
|
/* Declare local variables. */
|
|
|
|
char plainchar = (character & A_CHARTEXT);
|
|
|
|
int temp, x;
|
|
|
|
|
|
|
|
/* Start checking the input. */
|
|
|
|
if ((entry->dispType == vINT ||
|
|
|
|
entry->dispType == vHINT) &&
|
|
|
|
!isdigit((int)plainchar))
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else if ((entry->dispType == vCHAR ||
|
|
|
|
entry->dispType == vUCHAR ||
|
|
|
|
entry->dispType == vLCHAR ||
|
|
|
|
entry->dispType == vUHCHAR ||
|
|
|
|
entry->dispType == vLHCHAR) &&
|
|
|
|
isdigit((int)plainchar))
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else if (entry->dispType == vVIEWONLY)
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((int)strlen (entry->info) == entry->max)
|
|
|
|
{
|
|
|
|
Beep();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We will make any adjustments to the case of the character. */
|
|
|
|
if ((entry->dispType == vUCHAR ||
|
|
|
|
entry->dispType == vUHCHAR ||
|
|
|
|
entry->dispType == vUMIXED ||
|
|
|
|
entry->dispType == vUHMIXED)
|
|
|
|
&& !isdigit((int)plainchar))
|
|
|
|
{
|
|
|
|
plainchar = toupper (plainchar);
|
|
|
|
}
|
|
|
|
else if ((entry->dispType == vLCHAR ||
|
|
|
|
entry->dispType == vLHCHAR ||
|
|
|
|
entry->dispType == vLMIXED ||
|
|
|
|
entry->dispType == vLHMIXED) &&
|
|
|
|
!isdigit((int)plainchar))
|
|
|
|
{
|
|
|
|
plainchar = tolower (plainchar);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update the screen and pointer. */
|
|
|
|
if (entry->screenCol != entry->fieldWidth-1)
|
|
|
|
{
|
|
|
|
/* Update the character pointer. */
|
|
|
|
temp = (int)strlen (entry->info);
|
|
|
|
for (x=temp; x > entry->screenCol + entry->leftChar; x--)
|
|
|
|
{
|
|
|
|
entry->info[x] = entry->info[x-1];
|
|
|
|
}
|
|
|
|
entry->info[entry->screenCol + entry->leftChar] = plainchar;
|
|
|
|
entry->screenCol++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Update the character pointer. */
|
|
|
|
temp = (int)strlen (entry->info);
|
|
|
|
entry->info[temp] = plainchar;
|
|
|
|
entry->info[temp + 1] = '\0';
|
|
|
|
entry->leftChar++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This erases the information in the entry field
|
|
|
|
* and redraws a clean and empty entry field.
|
|
|
|
*/
|
|
|
|
void cleanCDKEntry (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
/* Erase the information in the character pointer. */
|
|
|
|
cleanChar (entry->info, entry->infoWidth, '\0');
|
|
|
|
|
|
|
|
/* Clean the entry screen field. */
|
|
|
|
mvwhline (entry->fieldWin, 0, 0, entry->filler, entry->fieldWidth);
|
|
|
|
|
|
|
|
/* Reset some variables. */
|
|
|
|
entry->screenCol = 0;
|
|
|
|
entry->leftChar = 0;
|
|
|
|
|
|
|
|
/* Refresh the entry field. */
|
|
|
|
wmove (entry->fieldWin, 0, entry->screenCol);
|
|
|
|
wnoutrefresh (entry->fieldWin);
|
|
|
|
wnoutrefresh (entry->win);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This draws the entry field.
|
|
|
|
*/
|
|
|
|
static void _drawCDKEntry (CDKOBJS *object, boolean Box)
|
|
|
|
{
|
|
|
|
CDKENTRY *entry = (CDKENTRY *)object;
|
|
|
|
int x;
|
|
|
|
|
|
|
|
/* Box the widget if asked. */
|
|
|
|
if (Box)
|
|
|
|
{
|
|
|
|
attrbox (entry->win,
|
|
|
|
entry->ULChar, entry->URChar,
|
|
|
|
entry->LLChar, entry->LRChar,
|
|
|
|
entry->HChar, entry->VChar,
|
|
|
|
entry->BoxAttrib,
|
|
|
|
entry->shadow);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->titleLines > 0)
|
|
|
|
{
|
|
|
|
/* Draw in the title if there is one. */
|
|
|
|
for (x=0; x < entry->titleLines; x++)
|
|
|
|
{
|
|
|
|
writeChtype (entry->titleWin,
|
|
|
|
entry->titlePos[x], x,
|
|
|
|
entry->title[x],
|
|
|
|
HORIZONTAL, 0,
|
|
|
|
entry->titleLen[x]);
|
|
|
|
}
|
|
|
|
wnoutrefresh (entry->titleWin);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw in the label to the widget. */
|
|
|
|
if (entry->label != 0)
|
|
|
|
{
|
|
|
|
writeChtype (entry->labelWin, 0, 0,
|
|
|
|
entry->label,
|
|
|
|
HORIZONTAL, 0,
|
|
|
|
entry->labelLen);
|
|
|
|
wnoutrefresh (entry->labelWin);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Redraw the entry field. */
|
|
|
|
drawCDKEntryField (entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This redraws the entry field.
|
|
|
|
*/
|
|
|
|
static void drawCDKEntryField (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
/* Declare variables. */
|
|
|
|
int infoLength;
|
|
|
|
|
|
|
|
/* Draw in the filler characters.*/
|
|
|
|
mvwhline (entry->fieldWin, 0, 0, entry->filler, entry->fieldWidth);
|
|
|
|
|
|
|
|
/* If there is information in the field. Then draw it in. */
|
|
|
|
if (entry->info != 0)
|
|
|
|
{
|
|
|
|
infoLength = (int)strlen (entry->info);
|
|
|
|
|
|
|
|
/* Redraw the field. */
|
|
|
|
if (entry->dispType == vHINT ||
|
|
|
|
entry->dispType == vHCHAR ||
|
|
|
|
entry->dispType == vHMIXED ||
|
|
|
|
entry->dispType == vUHCHAR ||
|
|
|
|
entry->dispType == vLHCHAR ||
|
|
|
|
entry->dispType == vUHMIXED ||
|
|
|
|
entry->dispType == vLHMIXED)
|
|
|
|
{
|
|
|
|
mvwhline (entry->fieldWin, 0, 0, entry->hidden,
|
|
|
|
infoLength - entry->leftChar);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
writeCharAttrib (entry->fieldWin, 0, 0, entry->info,
|
|
|
|
entry->fieldAttr, HORIZONTAL, entry->leftChar,
|
|
|
|
infoLength);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Refresh the entry field. */
|
|
|
|
wmove (entry->fieldWin, 0, entry->screenCol);
|
|
|
|
wnoutrefresh (entry->fieldWin);
|
|
|
|
wnoutrefresh (entry->win);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This erases an entry widget from the screen.
|
|
|
|
*/
|
|
|
|
static void _eraseCDKEntry (CDKOBJS *object)
|
|
|
|
{
|
|
|
|
CDKENTRY *entry = (CDKENTRY *)object;
|
|
|
|
|
|
|
|
eraseCursesWindow (entry->win);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This destroys an entry widget.
|
|
|
|
*/
|
|
|
|
void destroyCDKEntry (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
int x;
|
|
|
|
|
|
|
|
/* Erase the object. */
|
|
|
|
eraseCDKEntry (entry);
|
|
|
|
|
|
|
|
/* Clear out the character pointers. */
|
|
|
|
for (x=0; x < entry->titleLines; x++)
|
|
|
|
{
|
|
|
|
freeChtype (entry->title[x]);
|
|
|
|
}
|
|
|
|
freeChtype (entry->label);
|
|
|
|
freeChar (entry->info);
|
|
|
|
|
|
|
|
/* Delete the windows. */
|
|
|
|
deleteCursesWindow (entry->win);
|
|
|
|
|
|
|
|
/* Unregister this object. */
|
|
|
|
unregisterCDKObject (vENTRY, entry);
|
|
|
|
|
|
|
|
/* Finish cleaning up. */
|
|
|
|
free (entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets specific attributes of the entry field.
|
|
|
|
*/
|
|
|
|
void setCDKEntry (CDKENTRY *entry, char *value, int min, int max, boolean Box)
|
|
|
|
{
|
|
|
|
setCDKEntryValue (entry, value);
|
|
|
|
setCDKEntryMin (entry, min);
|
|
|
|
setCDKEntryMax (entry, max);
|
|
|
|
setCDKEntryBox (entry, Box);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This removes the old information in the entry field and keeps the
|
|
|
|
* new information given.
|
|
|
|
*/
|
|
|
|
void setCDKEntryValue (CDKENTRY *entry, char *newValue)
|
|
|
|
{
|
|
|
|
/* Declare local variables. */
|
|
|
|
int copychars = 0;
|
|
|
|
int stringLen = 0;
|
|
|
|
int charCount = 0;
|
|
|
|
|
|
|
|
/* If the pointer sent in is the same pointer as before, do nothing. */
|
|
|
|
if (entry->info == newValue)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Just to be sure, if lets make sure the new value isn't null. */
|
|
|
|
if (newValue == 0)
|
|
|
|
{
|
|
|
|
/* Then we want to just erase the old value. */
|
|
|
|
cleanChar (entry->info, entry->infoWidth, '\0');
|
|
|
|
|
|
|
|
/* Set the pointers back to zero. */
|
|
|
|
entry->leftChar = 0;
|
|
|
|
entry->screenCol = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Determine how many characters we need to copy. */
|
|
|
|
copychars = MINIMUM ((int)strlen(newValue), entry->max);
|
|
|
|
|
|
|
|
/* OK, erase the old value, and copy in the new value. */
|
|
|
|
cleanChar (entry->info, entry->max, '\0');
|
|
|
|
strncpy (entry->info, newValue, copychars);
|
|
|
|
stringLen = (int)strlen (entry->info);
|
|
|
|
|
|
|
|
/* Now determine the values of leftChar and screenCol. */
|
|
|
|
if (stringLen >= entry->fieldWidth)
|
|
|
|
{
|
|
|
|
charCount = (int)(entry->fieldWidth * .8);
|
|
|
|
entry->leftChar = stringLen - charCount;
|
|
|
|
entry->screenCol = charCount;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
entry->leftChar = 0;
|
|
|
|
entry->screenCol = stringLen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
char *getCDKEntryValue (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
return entry->info;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets the maximum length of the string that will be accepted.
|
|
|
|
*/
|
|
|
|
void setCDKEntryMax (CDKENTRY *entry, int max)
|
|
|
|
{
|
|
|
|
entry->max = max;
|
|
|
|
}
|
|
|
|
int getCDKEntryMax (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
return entry->max;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets the minimum length of the string that will
|
|
|
|
* be accepted.
|
|
|
|
*/
|
|
|
|
void setCDKEntryMin (CDKENTRY *entry, int min)
|
|
|
|
{
|
|
|
|
entry->min = min;
|
|
|
|
}
|
|
|
|
int getCDKEntryMin (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
return entry->min;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets the filler character to be used in the entry field.
|
|
|
|
*/
|
|
|
|
void setCDKEntryFillerChar (CDKENTRY *entry, chtype fillerCharacter)
|
|
|
|
{
|
|
|
|
entry->filler = fillerCharacter;
|
|
|
|
}
|
|
|
|
chtype getCDKEntryFillerChar (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
return entry->filler;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets the character to use when a hidden type is used.
|
|
|
|
*/
|
|
|
|
void setCDKEntryHiddenChar (CDKENTRY *entry, chtype hiddenCharacter)
|
|
|
|
{
|
|
|
|
entry->hidden = hiddenCharacter;
|
|
|
|
}
|
|
|
|
chtype getCDKEntryHiddenChar (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
return entry->hidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets whether or not the entry field will be boxed.
|
|
|
|
*/
|
|
|
|
void setCDKEntryBox (CDKENTRY *entry, boolean Box)
|
|
|
|
{
|
|
|
|
ObjOf(entry)->box = Box;
|
|
|
|
}
|
|
|
|
boolean getCDKEntryBox (CDKENTRY *entry)
|
|
|
|
{
|
|
|
|
return ObjOf(entry)->box;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These functions set the drawing characters of the widget.
|
|
|
|
*/
|
|
|
|
void setCDKEntryULChar (CDKENTRY *entry, chtype character)
|
|
|
|
{
|
|
|
|
entry->ULChar = character;
|
|
|
|
}
|
|
|
|
void setCDKEntryURChar (CDKENTRY *entry, chtype character)
|
|
|
|
{
|
|
|
|
entry->URChar = character;
|
|
|
|
}
|
|
|
|
void setCDKEntryLLChar (CDKENTRY *entry, chtype character)
|
|
|
|
{
|
|
|
|
entry->LLChar = character;
|
|
|
|
}
|
|
|
|
void setCDKEntryLRChar (CDKENTRY *entry, chtype character)
|
|
|
|
{
|
|
|
|
entry->LRChar = character;
|
|
|
|
}
|
|
|
|
void setCDKEntryVerticalChar (CDKENTRY *entry, chtype character)
|
|
|
|
{
|
|
|
|
entry->VChar = character;
|
|
|
|
}
|
|
|
|
void setCDKEntryHorizontalChar (CDKENTRY *entry, chtype character)
|
|
|
|
{
|
|
|
|
entry->HChar = character;
|
|
|
|
}
|
|
|
|
void setCDKEntryBoxAttribute (CDKENTRY *entry, chtype character)
|
|
|
|
{
|
|
|
|
entry->BoxAttrib = character;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets the background color of the widget.
|
|
|
|
*/
|
|
|
|
void setCDKEntryBackgroundColor (CDKENTRY *entry, char *color)
|
|
|
|
{
|
|
|
|
chtype *holder = 0;
|
|
|
|
int junk1, junk2;
|
|
|
|
|
|
|
|
/* Make sure the color isn't null. */
|
|
|
|
if (color == 0)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert the value of the environment variable to a chtype. */
|
|
|
|
holder = char2Chtype (color, &junk1, &junk2);
|
|
|
|
|
|
|
|
/* Set the widgets background color. */
|
|
|
|
wbkgd (entry->win, holder[0]);
|
|
|
|
wbkgd (entry->fieldWin, holder[0]);
|
|
|
|
if (entry->label != 0)
|
|
|
|
{
|
|
|
|
wbkgd (entry->labelWin, holder[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clean up. */
|
|
|
|
freeChtype (holder);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This sets the entry field callback function.
|
|
|
|
*/
|
|
|
|
void setCDKEntryCB (CDKENTRY *entry, ENTRYCB callback)
|
|
|
|
{
|
|
|
|
entry->callbackfn = (void *)callback;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function sets the pre-process function.
|
|
|
|
*/
|
|
|
|
void setCDKEntryPreProcess (CDKENTRY *entry, PROCESSFN callback, void *data)
|
|
|
|
{
|
|
|
|
entry->preProcessFunction = callback;
|
|
|
|
entry->preProcessData = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function sets the post-process function.
|
|
|
|
*/
|
|
|
|
void setCDKEntryPostProcess (CDKENTRY *entry, PROCESSFN callback, void *data)
|
|
|
|
{
|
|
|
|
entry->postProcessFunction = callback;
|
|
|
|
entry->postProcessData = data;
|
|
|
|
}
|