Annotation of othersrc/dist/cdk/mentry.c, revision 1.1.1.1

1.1       garbled     1: #include <cdk.h>
                      2: 
                      3: /*
                      4:  * $Author: tom $
                      5:  * $Date: 2000/02/18 23:20:55 $
                      6:  * $Revision: 1.112 $
                      7:  */
                      8: 
                      9: /*
                     10:  * Declare file local prototypes.
                     11:  */
                     12: static void CDKMentryCallBack (CDKMENTRY *mentry, chtype character);
                     13: 
                     14: /*
                     15:  * Declare file local variables.
                     16:  */
                     17: extern char *GPasteBuffer;
                     18: 
                     19: DeclareCDKObjects(my_funcs,Mentry);
                     20: 
                     21: /*
                     22:  * This creates a pointer to a muliple line entry widget.
                     23:  */
                     24: CDKMENTRY *newCDKMentry (CDKSCREEN *cdkscreen, int xplace, int yplace, char *title, char *label, chtype fieldAttr, chtype filler, EDisplayType dispType, int fWidth, int fRows, int logicalRows, int min, boolean Box, boolean shadow)
                     25: {
                     26:    /* Set up some variables */
                     27:    CDKMENTRY *mentry   = newCDKObject(CDKMENTRY, &my_funcs);
                     28:    chtype *holder      = 0;
                     29:    int parentWidth     = getmaxx(cdkscreen->window);
                     30:    int parentHeight    = getmaxy(cdkscreen->window);
                     31:    int fieldWidth      = fWidth;
                     32:    int fieldRows       = fRows;
                     33:    int boxWidth                = 0;
                     34:    int boxHeight       = 0;
                     35:    int maxWidth                = INT_MIN;
                     36:    int horizontalAdjust = 0;
                     37:    int xpos            = xplace;
                     38:    int ypos            = yplace;
                     39:    char **temp         = 0;
                     40:    int x, len, junk, junk2;
                     41: 
                     42:   /*
                     43:    * If the fieldWidth is a negative value, the fieldWidth will
                     44:    * be COLS-fieldWidth, otherwise, the fieldWidth will be the
                     45:    * given width.
                     46:    */
                     47:    fieldWidth = setWidgetDimension (parentWidth, fieldWidth, 0);
                     48: 
                     49:   /*
                     50:    * If the fieldRows is a negative value, the fieldRows will
                     51:    * be ROWS-fieldRows, otherwise, the fieldRows will be the
                     52:    * given height.
                     53:    */
                     54:    fieldRows = setWidgetDimension (parentWidth, fieldRows, 0);
                     55:    boxHeight = fieldRows + 2;
                     56: 
                     57:    /* Set some basic values of the mentry field. */
                     58:    mentry->label       = 0;
                     59:    mentry->labelLen    = 0;
                     60:    mentry->labelWin    = 0;
                     61:    mentry->titleLines  = 0;
                     62: 
                     63:    /* We need to translate the char * label to a chtype * */
                     64:    if (label != 0)
                     65:    {
                     66:       mentry->label    = char2Chtype (label, &mentry->labelLen, &junk);
                     67:    }
                     68:    boxWidth = mentry->labelLen + fieldWidth + 2;
                     69: 
                     70:    /* Translate the char * items to chtype * */
                     71:    if (title != 0)
                     72:    {
                     73:       temp = CDKsplitString (title, '\n');
                     74:       mentry->titleLines = CDKcountStrings (temp);
                     75: 
                     76:       /* We need to determine the widest title line. */
                     77:       for (x=0; x < mentry->titleLines; x++)
                     78:       {
                     79:         holder = char2Chtype (temp[x], &len, &junk2);
                     80:         maxWidth = MAXIMUM (maxWidth, len);
                     81:         freeChtype (holder);
                     82:       }
                     83: 
                     84:       /*
                     85:        * If one of the title lines is wider than the field and the label,
                     86:        * the box width will expand to accomodate.
                     87:        */
                     88:        if (maxWidth > boxWidth)
                     89:        {
                     90:          horizontalAdjust = (int)((maxWidth - boxWidth) / 2) + 1;
                     91:          boxWidth = maxWidth + 2;
                     92:        }
                     93: 
                     94:       /* For each line in the title, convert from char * to chtype * */
                     95:       for (x=0; x < mentry->titleLines; x++)
                     96:       {
                     97:         mentry->title[x]       = char2Chtype (temp[x], &mentry->titleLen[x], &mentry->titlePos[x]);
                     98:         mentry->titlePos[x]    = justifyString (boxWidth, mentry->titleLen[x], mentry->titlePos[x]);
                     99:       }
                    100: 
                    101:       CDKfreeStrings(temp);
                    102:    }
                    103:    else
                    104:    {
                    105:       /* No title? Set the required variables. */
                    106:       mentry->titleLines = 0;
                    107:    }
                    108:    boxHeight += mentry->titleLines;
                    109: 
                    110:   /*
                    111:    * Make sure we didn't extend beyond the parent window.
                    112:    */
                    113:    boxWidth = MINIMUM (boxWidth, parentWidth);
                    114:    boxHeight = MINIMUM (boxHeight, parentHeight);
                    115:    fieldWidth = (fieldWidth > (boxWidth - mentry->labelLen - 2) ? (boxWidth - mentry->labelLen - 2) : fieldWidth);
                    116:    fieldRows = (fieldRows > (boxHeight - mentry->titleLines - 2) ? (boxHeight - mentry->titleLines - 2) : fieldRows);
                    117: 
                    118:    /* Rejustify the x and y positions if we need to. */
                    119:    alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
                    120: 
                    121:    /* Make the label window. */
                    122:    mentry->win = newwin (boxHeight + !!shadow, boxWidth + !!shadow, ypos, xpos);
                    123: 
                    124:    /* Is the window null??? */
                    125:    if (mentry->win == 0)
                    126:    {
                    127:       /* Free up any memory used. */
                    128:       freeChtype (mentry->label);
                    129:       free (mentry);
                    130: 
                    131:       /* Return a null pointer. */
                    132:       return (0);
                    133:    }
                    134:    keypad (mentry->win, TRUE);
                    135: 
                    136:    if (mentry->titleLines > 0)
                    137:    {
                    138:       /* Make the title window. */
                    139:       mentry->titleWin = subwin (mentry->win,
                    140:                                mentry->titleLines, boxWidth - 2,
                    141:                                ypos + 1, xpos + 1);
                    142:    }
                    143: 
                    144:    /* Create the label window. */
                    145:    if (mentry->label != 0)
                    146:    {
                    147:       mentry->labelWin = subwin (mentry->win, fieldRows, mentry->labelLen,
                    148:                                ypos + mentry->titleLines + 1,
                    149:                                xpos + horizontalAdjust + 1);
                    150:    }
                    151: 
                    152:    /* Make the field window. */
                    153:    mentry->fieldWin = subwin (mentry->win, fieldRows, fieldWidth,
                    154:                                ypos + mentry->titleLines + 1,
                    155:                                xpos + mentry->labelLen + horizontalAdjust + 1);
                    156:    keypad (mentry->fieldWin, TRUE);
                    157: 
                    158:    /* Set up the rest of the structure. */
                    159:    mentry->parent      = cdkscreen->window;
                    160:    mentry->totalWidth  = fieldWidth * logicalRows;
                    161: 
                    162:    /* Create the info char * pointer. */
                    163:    mentry->infoWidth = mentry->totalWidth + 3;
                    164:    mentry->info = (char *)malloc (mentry->infoWidth);
                    165:    cleanChar (mentry->info, mentry->infoWidth, '\0');
                    166: 
                    167:    /* Set up the rest of the widget information. */
                    168:    ScreenOf(mentry)            = cdkscreen;
                    169:    mentry->fieldAttr           = fieldAttr;
                    170:    mentry->fieldWidth          = fieldWidth;
                    171:    mentry->rows                        = fieldRows;
                    172:    mentry->boxHeight           = boxHeight;
                    173:    mentry->boxWidth            = boxWidth;
                    174:    mentry->filler              = filler;
                    175:    mentry->hidden              = filler;
                    176:    ObjOf(mentry)->box          = Box;
                    177:    mentry->currentRow          = 0;
                    178:    mentry->currentCol          = 0;
                    179:    mentry->topRow              = 0;
                    180:    mentry->shadow              = shadow;
                    181:    mentry->dispType            = dispType;
                    182:    mentry->min                 = min;
                    183:    mentry->logicalRows         = logicalRows;
                    184:    mentry->ULChar              = ACS_ULCORNER;
                    185:    mentry->URChar              = ACS_URCORNER;
                    186:    mentry->LLChar              = ACS_LLCORNER;
                    187:    mentry->LRChar              = ACS_LRCORNER;
                    188:    mentry->HChar               = ACS_HLINE;
                    189:    mentry->VChar               = ACS_VLINE;
                    190:    mentry->BoxAttrib           = A_NORMAL;
                    191:    mentry->exitType            = vNEVER_ACTIVATED;
                    192:    mentry->callbackfn          = (void *)&CDKMentryCallBack;
                    193:    mentry->preProcessFunction  = 0;
                    194:    mentry->preProcessData      = 0;
                    195:    mentry->postProcessFunction = 0;
                    196:    mentry->postProcessData     = 0;
                    197: 
                    198:    /* Clean the key bindings. */
                    199:    cleanCDKObjectBindings (vMENTRY, mentry);
                    200: 
                    201:    /* Register this baby. */
                    202:    registerCDKObject (cdkscreen, vMENTRY, mentry);
                    203: 
                    204:    /* Return the pointer to the structure. */
                    205:    return (mentry);
                    206: }
                    207: 
                    208: /*
                    209:  * This actually manages the mentry widget...
                    210:  */
                    211: char *activateCDKMentry (CDKMENTRY *mentry, chtype *actions)
                    212: {
                    213:    /* Declare local variables. */
                    214:    chtype input = 0;
                    215:    char *ret   = 0;
                    216: 
                    217:    /* Draw the mentry widget. */
                    218:    drawCDKMentry (mentry, ObjOf(mentry)->box);
                    219: 
                    220:    /* Check if 'actions' is null. */
                    221:    if (actions == 0)
                    222:    {
                    223:       for (;;)
                    224:       {
                    225:         /* Get the input. */
                    226:         wrefresh (mentry->fieldWin);
                    227:         input = wgetch (mentry->fieldWin);
                    228: 
                    229:         /* Inject this character into the widget. */
                    230:         ret = injectCDKMentry (mentry, input);
                    231:         if (mentry->exitType != vEARLY_EXIT)
                    232:         {
                    233:            return ret;
                    234:         }
                    235:       }
                    236:    }
                    237:    else
                    238:    {
                    239:       int length = chlen (actions);
                    240:       int x;
                    241: 
                    242:       /* Inject each character one at a time. */
                    243:       for (x=0; x < length; x++)
                    244:       {
                    245:         ret = injectCDKMentry (mentry, actions[x]);
                    246:         if (mentry->exitType != vEARLY_EXIT)
                    247:         {
                    248:            return ret;
                    249:         }
                    250:       }
                    251:    }
                    252: 
                    253:    /* Set the exit type and exit. */
                    254:    mentry->exitType = vEARLY_EXIT;
                    255:    return 0;
                    256: }
                    257: 
                    258: /*
                    259:  * This injects a character into the widget.
                    260:  */
                    261: char *injectCDKMentry (CDKMENTRY *mentry, chtype input)
                    262: {
                    263:    /* Declare local variables. */
                    264:    int cursorPos       = ((mentry->currentRow + mentry->topRow) *
                    265:                                mentry->fieldWidth) + mentry->currentCol;
                    266:    int ppReturn                = 1;
                    267:    int x, infoLength, fieldCharacters;
                    268:    char holder;
                    269: 
                    270:    /* Check if there is a pre-process function to be called. */
                    271:    if (mentry->preProcessFunction != 0)
                    272:    {
                    273:       /* Call the pre-process function. */
                    274:       ppReturn = ((PROCESSFN)(mentry->preProcessFunction)) (vMENTRY, mentry, mentry->preProcessData, input);
                    275:    }
                    276: 
                    277:    /* Should we continue? */
                    278:    if (ppReturn != 0)
                    279:    {
                    280:       /* Check for a key binding... */
                    281:       if (checkCDKObjectBind (vMENTRY, mentry, input) != 0)
                    282:       {
                    283:         mentry->exitType = vESCAPE_HIT;
                    284:         return 0;
                    285:       }
                    286:       else
                    287:       {
                    288:         switch (input)
                    289:         {
                    290:            case CDK_BEGOFLINE :
                    291:                 mentry->currentCol = 0;
                    292:                 mentry->currentRow = 0;
                    293:                 mentry->topRow = 0;
                    294:                 break;
                    295: 
                    296:            case CDK_ENDOFLINE :
                    297:                 infoLength = (int)strlen(mentry->info);
                    298:                 fieldCharacters = mentry->rows * mentry->fieldWidth;
                    299:                 if (infoLength < fieldCharacters)
                    300:                 {
                    301:                    mentry->topRow = 0;
                    302:                    mentry->currentRow = infoLength / mentry->fieldWidth;
                    303:                    mentry->currentCol = infoLength % mentry->fieldWidth;
                    304:                 }
                    305:                 else
                    306:                 {
                    307:                    mentry->topRow      = (infoLength / mentry->fieldWidth) - mentry->rows + 1;
                    308:                    mentry->currentRow  = mentry->rows - 1;
                    309:                    mentry->currentCol  = infoLength % mentry->fieldWidth;
                    310:                 }
                    311:                 break;
                    312: 
                    313:            case KEY_LEFT : case CDK_BACKCHAR :
                    314:                 if (mentry->currentCol != 0)
                    315:                 {
                    316:                    mentry->currentCol--;
                    317:                 }
                    318:                 else
                    319:                 {
                    320:                    if (mentry->currentRow == 0)
                    321:                    {
                    322:                       if (mentry->topRow == 0)
                    323:                       {
                    324:                          Beep();
                    325:                       }
                    326:                       else
                    327:                       {
                    328:                          /* Move up one row. */
                    329:                          mentry->currentCol = mentry->fieldWidth - 1;
                    330:                          mentry->topRow--;
                    331:                       }
                    332:                    }
                    333:                    else
                    334:                    {
                    335:                       mentry->currentRow--;
                    336:                       mentry->currentCol = mentry->fieldWidth - 1;
                    337:                    }
                    338:                 }
                    339:                 break;
                    340: 
                    341:            case KEY_RIGHT : case CDK_FORCHAR :
                    342:                 if (mentry->currentCol < (mentry->fieldWidth - 1))
                    343:                 {
                    344:                    if ((((mentry->topRow + mentry->currentRow) * mentry->fieldWidth) + mentry->currentCol + 1) > (int)strlen (mentry->info)-1)
                    345:                    {
                    346:                       Beep();
                    347:                    }
                    348:                    else
                    349:                    {
                    350:                       mentry->currentCol++;
                    351:                    }
                    352:                 }
                    353:                 else
                    354:                 {
                    355:                    if (mentry->currentRow == mentry->rows - 1)
                    356:                    {
                    357:                       if ((mentry->topRow + mentry->currentRow + 1) <= mentry->logicalRows)
                    358:                       {
                    359:                          mentry->currentCol = 0;
                    360:                          mentry->topRow++;
                    361:                       }
                    362:                       else
                    363:                       {
                    364:                          Beep();
                    365:                       }
                    366:                    }
                    367:                    else
                    368:                    {
                    369:                       mentry->currentCol = 0;
                    370:                       mentry->currentRow++;
                    371:                    }
                    372:                 }
                    373:                 break;
                    374: 
                    375:            case KEY_DOWN :
                    376:                 if (mentry->currentRow != (mentry->rows-1))
                    377:                 {
                    378:                    if ((((mentry->topRow + mentry->currentRow + 1) * mentry->fieldWidth) + mentry->currentCol) > (int)strlen (mentry->info)-1)
                    379:                    {
                    380:                       Beep();
                    381:                    }
                    382:                    else
                    383:                    {
                    384:                       mentry->currentRow++;
                    385:                    }
                    386:                 }
                    387:                 else
                    388:                 {
                    389:                    if (mentry->topRow >= mentry->logicalRows - mentry->rows)
                    390:                    {
                    391:                       Beep();
                    392:                    }
                    393:                    else
                    394:                    {
                    395:                       infoLength = (int)strlen(mentry->info);
                    396:                       if (((mentry->topRow + mentry->currentRow + 1) * mentry->fieldWidth) > infoLength)
                    397:                       {
                    398:                          Beep();
                    399:                       }
                    400:                       else
                    401:                       {
                    402:                          mentry->topRow++;
                    403:                       }
                    404:                    }
                    405:                 }
                    406:                 break;
                    407: 
                    408:            case KEY_UP :
                    409:                 if (mentry->currentRow != 0)
                    410:                 {
                    411:                    mentry->currentRow--;
                    412:                 }
                    413:                 else
                    414:                 {
                    415:                    if (mentry->topRow == 0)
                    416:                    {
                    417:                       Beep();
                    418:                    }
                    419:                    else
                    420:                    {
                    421:                       mentry->topRow--;
                    422:                    }
                    423:                 }
                    424:                 break;
                    425: 
                    426:            case DELETE : case KEY_BACKSPACE : case CONTROL('H') : case KEY_DC :
                    427:                 if (mentry->dispType == vVIEWONLY)
                    428:                 {
                    429:                    Beep();
                    430:                 }
                    431:                 else
                    432:                 {
                    433:                    infoLength  = (int)strlen(mentry->info);
                    434: 
                    435:                    /* If there is nothing left to delete, then beep. */
                    436:                    if (infoLength == 0)
                    437:                    {
                    438:                       Beep();
                    439:                    }
                    440:                    else
                    441:                    {
                    442:                       /*
                    443:                        * Check if the cursor is inside the string or
                    444:                        * at the end of the string.
                    445:                         */
                    446:                       if (cursorPos != infoLength)
                    447:                       {
                    448:                          /* We are deleting from the middle of the string.  */
                    449:                          for (x = cursorPos; x < infoLength; x++)
                    450:                          {
                    451:                             mentry->info[x] = mentry->info[x + 1];
                    452:                          }
                    453:                          mentry->info[--infoLength] = '\0';
                    454:                       }
                    455:                       else
                    456:                       {
                    457:                          /* We are deleting from the end of the string. */
                    458:                          mentry->info[--infoLength] = '\0';
                    459: 
                    460:                          /* Adjust the currentRow/currentCol vars. */
                    461:                          if (mentry->currentCol == 0 &&
                    462:                                mentry->currentRow == 0)
                    463:                          {
                    464:                             if (mentry->topRow == 0)
                    465:                             {
                    466:                                Beep();
                    467:                             }
                    468:                             else
                    469:                             {
                    470:                                /* Bump everything down X lines. */
                    471:                                int rows = infoLength / mentry->fieldWidth;
                    472:                                int cols = infoLength % mentry->fieldWidth;
                    473: 
                    474:                                if (rows < mentry->rows)
                    475:                                {
                    476:                                   mentry->topRow = 0;
                    477:                                   mentry->currentCol = cols;
                    478:                                   mentry->currentRow = rows;
                    479:                                }
                    480:                                else
                    481:                                {
                    482:                                   mentry->topRow -= mentry->rows;
                    483:                                   mentry->currentRow = mentry->rows-1;
                    484:                                   mentry->currentCol = cols;
                    485:                                }
                    486:                             }
                    487:                          }
                    488:                          else if (mentry->currentCol == 0)
                    489:                          {
                    490:                             mentry->currentCol = mentry->fieldWidth-1;
                    491:                             mentry->currentRow--;
                    492:                          }
                    493:                          else
                    494:                          {
                    495:                             mentry->currentCol--;
                    496:                          }
                    497:                       }
                    498:                    }
                    499:                 }
                    500:                 break;
                    501: 
                    502:            case CDK_TRANSPOSE :
                    503:                 infoLength = (int)strlen(mentry->info);
                    504:                 if (cursorPos >= infoLength-1)
                    505:                 {
                    506:                    Beep();
                    507:                 }
                    508:                 else
                    509:                 {
                    510:                    holder = mentry->info[cursorPos];
                    511:                    mentry->info[cursorPos] = mentry->info[cursorPos + 1];
                    512:                    mentry->info[cursorPos + 1] = holder;
                    513:                 }
                    514:                 break;
                    515: 
                    516:            case CDK_ERASE :
                    517:                 infoLength = (int)strlen(mentry->info);
                    518:                 if (infoLength != 0)
                    519:                 {
                    520:                    cleanCDKMentry (mentry);
                    521:                 }
                    522:                 break;
                    523: 
                    524:            case CDK_CUT:
                    525:                 infoLength = (int)strlen(mentry->info);
                    526:                 if (infoLength != 0)
                    527:                 {
                    528:                    freeChar (GPasteBuffer);
                    529:                    GPasteBuffer = copyChar (mentry->info);
                    530:                    cleanCDKMentry (mentry);
                    531:                 }
                    532:                 else
                    533:                 {
                    534:                    Beep();
                    535:                 }
                    536:                 break;
                    537: 
                    538:            case CDK_COPY:
                    539:                 infoLength = (int)strlen(mentry->info);
                    540:                 if (infoLength != 0)
                    541:                 {
                    542:                    freeChar (GPasteBuffer);
                    543:                    GPasteBuffer = copyChar (mentry->info);
                    544:                 }
                    545:                 else
                    546:                 {
                    547:                    Beep();
                    548:                 }
                    549:                 break;
                    550: 
                    551:            case CDK_PASTE:
                    552:                 if (GPasteBuffer != 0)
                    553:                 {
                    554:                    setCDKMentryValue (mentry, GPasteBuffer);
                    555:                 }
                    556:                 else
                    557:                 {
                    558:                    Beep();
                    559:                 }
                    560:                 break;
                    561: 
                    562:            case KEY_RETURN : case KEY_TAB : case KEY_ENTER :
                    563:                 infoLength = (int)strlen(mentry->info);
                    564:                 if (infoLength < mentry->min + 1)
                    565:                 {
                    566:                    Beep();
                    567:                 }
                    568:                 else
                    569:                 {
                    570:                    mentry->exitType = vNORMAL;
                    571:                    return (mentry->info);
                    572:                 }
                    573:                 break;
                    574: 
                    575:            case KEY_ESC :
                    576:                 mentry->exitType = vESCAPE_HIT;
                    577:                 return 0;
                    578: 
                    579:            case CDK_REFRESH :
                    580:                 eraseCDKScreen (ScreenOf(mentry));
                    581:                 refreshCDKScreen (ScreenOf(mentry));
                    582:                 break;
                    583: 
                    584:            default :
                    585:                 ((MENTRYCB)mentry->callbackfn)(mentry, input);
                    586:                 break;
                    587:         }
                    588:       }
                    589: 
                    590:       /* Should we do a post-process? */
                    591:       if (mentry->postProcessFunction != 0)
                    592:       {
                    593:         ((PROCESSFN)(mentry->postProcessFunction)) (vMENTRY, mentry, mentry->postProcessData, input);
                    594:       }
                    595:    }
                    596: 
                    597:    /* Refresh the field. */
                    598:    drawCDKMentryField (mentry);
                    599: 
                    600:    /* Set the exit type and return. */
                    601:    mentry->exitType = vEARLY_EXIT;
                    602:    return 0;
                    603: }
                    604: 
                    605: /*
                    606:  * This moves the mentry field to the given location.
                    607:  */
                    608: static void _moveCDKMentry (CDKOBJS *object, int xplace, int yplace, boolean relative, boolean refresh_flag)
                    609: {
                    610:    CDKMENTRY *mentry = (CDKMENTRY *)object;
                    611: 
                    612:    /*
                    613:     * If this is a relative move, then we will adjust where we want
                    614:     * to move to.
                    615:     */
                    616:    if (relative)
                    617:    {
                    618:       xplace += getbegx(mentry->win);
                    619:       yplace += getbegy(mentry->win);
                    620:    }
                    621: 
                    622:    /* Adjust the window if we need to. */
                    623:    alignxy (WindowOf(mentry), &xplace, &yplace, mentry->boxWidth, mentry->boxHeight);
                    624: 
                    625:    /* Move the window to the new location. */
                    626:    moveCursesWindow(mentry->win, xplace, yplace);
                    627: 
                    628:    /* Redraw the window, if they asked for it. */
                    629:    if (refresh_flag)
                    630:    {
                    631:       drawCDKMentry (mentry, ObjOf(mentry)->box);
                    632:    }
                    633: }
                    634: 
                    635: /*
                    636:  * This function redraws the multiple line entry field.
                    637:  */
                    638: void drawCDKMentryField (CDKMENTRY *mentry)
                    639: {
                    640:    /* Declare local variables. */
                    641:    int currchar                = (mentry->fieldWidth * mentry->topRow);
                    642:    int length          = 0;
                    643:    int lastpos         = 0;
                    644:    int x, y;
                    645: 
                    646:    /* Check the value of info. */
                    647:    if (mentry->info == 0)
                    648:    {
                    649:       return;
                    650:    }
                    651: 
                    652:    /* The information isn't null, redraw the field. */
                    653:    length = (int)strlen (mentry->info);
                    654:    lastpos = ((chtype)mentry->info[length] == (chtype)mentry->filler ? length-1 : length);
                    655: 
                    656:    /* Start redrawing the fields. */
                    657:    for (x=0; x < mentry->rows; x++)
                    658:    {
                    659:       for (y=0; y < mentry->fieldWidth ; y++)
                    660:       {
                    661:         if (currchar < lastpos)
                    662:         {
                    663:            if (mentry->dispType == vHCHAR ||
                    664:                        mentry->dispType == vHINT ||
                    665:                        mentry->dispType == vHMIXED ||
                    666:                        mentry->dispType == vUHCHAR ||
                    667:                        mentry->dispType == vLHCHAR ||
                    668:                        mentry->dispType == vUHMIXED ||
                    669:                        mentry->dispType == vLHMIXED)
                    670:            {
                    671:               mvwaddch (mentry->fieldWin, x, y, mentry->filler);
                    672:            }
                    673:            else
                    674:            {
                    675:               mvwaddch (mentry->fieldWin, x, y,
                    676:                        (mentry->info[currchar++] & A_CHARTEXT) | mentry->fieldAttr);
                    677:            }
                    678:         }
                    679:         else
                    680:         {
                    681:            mvwaddch (mentry->fieldWin, x, y, mentry->filler);
                    682:         }
                    683:       }
                    684:    }
                    685: 
                    686:    /* Refresh the screen. */
                    687:    wmove (mentry->fieldWin, mentry->currentRow, mentry->currentCol);
                    688:    wnoutrefresh (mentry->fieldWin);
                    689:    wnoutrefresh (mentry->win);
                    690: }
                    691: 
                    692: /*
                    693:  * This is a generic character parser for the mentry field. It is used as a
                    694:  * callback function, so any personal modifications can be made by creating
                    695:  * a new function and calling that one the mentry activation.
                    696:  */
                    697: static void CDKMentryCallBack (CDKMENTRY *mentry, chtype character)
                    698: {
                    699:    /* Declare local variables. */
                    700:    int cursorPos = ((mentry->currentRow + mentry->topRow) *
                    701:                         mentry->fieldWidth) + mentry->currentCol;
                    702:    int infoLength = (int)strlen (mentry->info);
                    703:    char plainchar = (character & A_CHARTEXT);
                    704:    int x;
                    705: 
                    706:    /* Check the type of character we are looking for. */
                    707:    if ((mentry->dispType == vINT ||
                    708:        mentry->dispType == vHINT) &&
                    709:        !isdigit((int)plainchar))
                    710:    {
                    711:       Beep();
                    712:    }
                    713:    else if ((mentry->dispType == vCHAR ||
                    714:                mentry->dispType == vUCHAR ||
                    715:                mentry->dispType == vLCHAR ||
                    716:                mentry->dispType == vUHCHAR ||
                    717:                mentry->dispType == vLHCHAR) &&
                    718:                isdigit((int)plainchar))
                    719:    {
                    720:       Beep();
                    721:    }
                    722:    else if (mentry->dispType == vVIEWONLY)
                    723:    {
                    724:       Beep();
                    725:    }
                    726:    else
                    727:    {
                    728:       if ((int)strlen (mentry->info) == mentry->totalWidth)
                    729:       {
                    730:         Beep();
                    731:       }
                    732:       else
                    733:       {
                    734:         /* We will make any adjustments to the case of the character. */
                    735:         if ((mentry->dispType == vUCHAR ||
                    736:                mentry->dispType == vUHCHAR ||
                    737:                mentry->dispType == vUMIXED ||
                    738:                mentry->dispType == vUHMIXED) &&
                    739:                !isdigit((int)plainchar))
                    740:         {
                    741:            plainchar = toupper (plainchar);
                    742:         }
                    743:         else if ((mentry->dispType == vLCHAR ||
                    744:                        mentry->dispType == vLHCHAR ||
                    745:                        mentry->dispType == vLMIXED ||
                    746:                        mentry->dispType == vLHMIXED) &&
                    747:                        !isdigit((int)plainchar))
                    748:         {
                    749:            plainchar = tolower (plainchar);
                    750:         }
                    751: 
                    752:         /*
                    753:          * Check if we are adding onto the end or we are adding
                    754:          * into the middle?
                    755:          */
                    756:         if (cursorPos != infoLength-1)
                    757:         {
                    758:            /* We are adding in the middle of the string. */
                    759:            for (x = infoLength + 1; x > cursorPos; x--)
                    760:            {
                    761:               mentry->info[x] = mentry->info[x-1];
                    762:            }
                    763:            mentry->info[cursorPos] = plainchar;
                    764:            mentry->currentCol++;
                    765:         }
                    766:         else
                    767:         {
                    768:            /* We are adding onto the end of the string. */
                    769:            mentry->info[infoLength-1]  = plainchar;
                    770:            mentry->info[infoLength]    = mentry->filler;
                    771: 
                    772:            /* Add the character on the screen */
                    773:            if (mentry->dispType == vHCHAR ||
                    774:                        mentry->dispType == vHINT ||
                    775:                        mentry->dispType == vHMIXED ||
                    776:                        mentry->dispType == vUHCHAR ||
                    777:                        mentry->dispType == vLHCHAR ||
                    778:                        mentry->dispType == vUHMIXED ||
                    779:                        mentry->dispType == vLHMIXED)
                    780:            {
                    781:               mvwaddch (mentry->fieldWin,
                    782:                        mentry->currentRow,
                    783:                        mentry->currentCol++,
                    784:                        mentry->filler);
                    785:            }
                    786:            else
                    787:            {
                    788:               mvwaddch (mentry->fieldWin,
                    789:                        mentry->currentRow,
                    790:                        mentry->currentCol++,
                    791:                        plainchar|mentry->fieldAttr);
                    792:            }
                    793:         }
                    794: 
                    795:         /* Have we gone out of bounds. */
                    796:         if (mentry->currentCol == mentry->fieldWidth)
                    797:         {
                    798:            /* Update the row and col values. */
                    799:            mentry->currentCol = 0;
                    800:            mentry->currentRow++;
                    801: 
                    802:            /*
                    803:             * If we have gone outside of the visual boundries, we
                    804:             * need to scroll the window.
                    805:             */
                    806:            if (mentry->currentRow == mentry->rows)
                    807:            {
                    808:               /* We have to redraw the screen. */
                    809:               mentry->currentRow--;
                    810:               mentry->topRow++;
                    811:               drawCDKMentryField (mentry);
                    812:            }
                    813:         }
                    814:       }
                    815:    }
                    816: }
                    817: 
                    818: /*
                    819:  * This function draws the multiple line entry field.
                    820:  */
                    821: static void _drawCDKMentry (CDKOBJS *object, boolean Box)
                    822: {
                    823:    CDKMENTRY *mentry = (CDKMENTRY *)object;
                    824:    int x;
                    825: 
                    826:    /* Box the widget if asked. */
                    827:    if (Box)
                    828:    {
                    829:       attrbox (mentry->win,
                    830:                mentry->ULChar, mentry->URChar,
                    831:                mentry->LLChar, mentry->LRChar,
                    832:                mentry->HChar,  mentry->VChar,
                    833:                mentry->BoxAttrib,
                    834:                mentry->shadow);
                    835:    }
                    836: 
                    837:    if (mentry->titleLines > 0)
                    838:    {
                    839:       /* Draw in the title if there is one. */
                    840:       for (x=0; x < mentry->titleLines; x++)
                    841:       {
                    842:         writeChtype (mentry->titleWin,
                    843:                        mentry->titlePos[x], x,
                    844:                        mentry->title[x],
                    845:                        HORIZONTAL, 0,
                    846:                        mentry->titleLen[x]);
                    847:       }
                    848:       wnoutrefresh (mentry->titleWin);
                    849:    }
                    850: 
                    851:    /* Draw in the label to the widget. */
                    852:    if (mentry->label != 0)
                    853:    {
                    854:       writeChtype (mentry->labelWin, 0, 0,
                    855:                        mentry->label,
                    856:                        HORIZONTAL, 0,
                    857:                        mentry->labelLen);
                    858:       wnoutrefresh (mentry->labelWin);
                    859:    }
                    860: 
                    861:    /* Draw the mentry field. */
                    862:    drawCDKMentryField (mentry);
                    863: }
                    864: 
                    865: /*
                    866:  * These functions set the drawing characters of the widget.
                    867:  */
                    868: void setCDKMentryULChar (CDKMENTRY *mentry, chtype character)
                    869: {
                    870:    mentry->ULChar = character;
                    871: }
                    872: void setCDKMentryURChar (CDKMENTRY *mentry, chtype character)
                    873: {
                    874:    mentry->URChar = character;
                    875: }
                    876: void setCDKMentryLLChar (CDKMENTRY *mentry, chtype character)
                    877: {
                    878:    mentry->LLChar = character;
                    879: }
                    880: void setCDKMentryLRChar (CDKMENTRY *mentry, chtype character)
                    881: {
                    882:    mentry->LRChar = character;
                    883: }
                    884: void setCDKMentryVerticalChar (CDKMENTRY *mentry, chtype character)
                    885: {
                    886:    mentry->VChar = character;
                    887: }
                    888: void setCDKMentryHorizontalChar (CDKMENTRY *mentry, chtype character)
                    889: {
                    890:    mentry->HChar = character;
                    891: }
                    892: void setCDKMentryBoxAttribute (CDKMENTRY *mentry, chtype character)
                    893: {
                    894:    mentry->BoxAttrib = character;
                    895: }
                    896: 
                    897: /*
                    898:  * This sets the background color of the widget.
                    899:  */
                    900: void setCDKMentryBackgroundColor (CDKMENTRY *mentry, char *color)
                    901: {
                    902:    chtype *holder = 0;
                    903:    int junk1, junk2;
                    904: 
                    905:    /* Make sure the color isn't null. */
                    906:    if (color == 0)
                    907:    {
                    908:       return;
                    909:    }
                    910: 
                    911:    /* Convert the value of the environment variable to a chtype. */
                    912:    holder = char2Chtype (color, &junk1, &junk2);
                    913: 
                    914:    /* Set the widgets background color. */
                    915:    wbkgd (mentry->win, holder[0]);
                    916:    wbkgd (mentry->fieldWin, holder[0]);
                    917:    if (mentry->label != 0)
                    918:    {
                    919:       wbkgd (mentry->labelWin, holder[0]);
                    920:    }
                    921: 
                    922:    /* Clean up. */
                    923:    freeChtype (holder);
                    924: }
                    925: 
                    926: /*
                    927:  * This function erases the multiple line entry field from the screen.
                    928:  */
                    929: static void _eraseCDKMentry (CDKOBJS *object)
                    930: {
                    931:    CDKMENTRY *mentry = (CDKMENTRY *)object;
                    932: 
                    933:    eraseCursesWindow (mentry->win);
                    934: }
                    935: 
                    936: /*
                    937:  * This function destroys a multiple line entry field widget.
                    938:  */
                    939: void destroyCDKMentry (CDKMENTRY *mentry)
                    940: {
                    941:    int x;
                    942: 
                    943:    /* Erase the object. */
                    944:    eraseCDKMentry (mentry);
                    945: 
                    946:    /* Clean up the char pointers. */
                    947:    for (x=0; x < mentry->titleLines; x++)
                    948:    {
                    949:       freeChtype (mentry->title[x]);
                    950:    }
                    951:    freeChtype (mentry->label);
                    952:    freeChar (mentry->info);
                    953: 
                    954:    /* Clean up the windows. */
                    955:    deleteCursesWindow (mentry->win);
                    956: 
                    957:    /* Unregister this object. */
                    958:    unregisterCDKObject (vMENTRY, mentry);
                    959: 
                    960:    /* Finish cleaning up. */
                    961:    free (mentry);
                    962: }
                    963: 
                    964: /*
                    965:  * This sets multiple attributes of the widget.
                    966:  */
                    967: void setCDKMentry (CDKMENTRY *mentry, char *value, int min, boolean Box)
                    968: {
                    969:    setCDKMentryValue (mentry, value);
                    970:    setCDKMentryMin (mentry, min);
                    971:    setCDKMentryBox (mentry, Box);
                    972: }
                    973: 
                    974: /*
                    975:  * This removes the old information in the entry field and keeps the
                    976:  * new information given.
                    977:  */
                    978: void setCDKMentryValue (CDKMENTRY *mentry, char *newValue)
                    979: {
                    980:    /* Declare local variables. */
                    981:    int fieldCharacters = mentry->rows * mentry->fieldWidth;
                    982:    int len             = 0;
                    983:    int rowsUsed;
                    984: 
                    985:    /* Just to be sure, if lets make sure the new value isn't null. */
                    986:    if (newValue == 0)
                    987:    {
                    988:       /* Then we want to just erase the old value. */
                    989:       cleanChar (mentry->info, mentry->infoWidth, '\0');
                    990:       return;
                    991:    }
                    992: 
                    993:    /* Determine how many characters we need to copy. */
                    994:    len         = (int)strlen (newValue);
                    995: 
                    996:    /* OK, erase the old value, and copy in the new value. */
                    997:    cleanChar (mentry->info, mentry->infoWidth, '\0');
                    998:    strncpy (mentry->info, newValue, mentry->infoWidth);
                    999: 
                   1000:    /* Set the cursor/row info. */
                   1001:    if (len < fieldCharacters)
                   1002:    {
                   1003:       mentry->topRow = 0;
                   1004:       mentry->currentRow = len / mentry->fieldWidth;
                   1005:       mentry->currentCol = len % mentry->fieldWidth;
                   1006:    }
                   1007:    else
                   1008:    {
                   1009:       rowsUsed                 = len / mentry->fieldWidth;
                   1010:       mentry->topRow           = rowsUsed - mentry->rows + 1;
                   1011:       mentry->currentRow       = mentry->rows - 1;
                   1012:       mentry->currentCol       = len % mentry->fieldWidth;
                   1013:    }
                   1014: 
                   1015:    /* Redraw the widget. */
                   1016:    drawCDKMentryField (mentry);
                   1017: }
                   1018: char *getCDKMentryValue (CDKMENTRY *mentry)
                   1019: {
                   1020:    return mentry->info;
                   1021: }
                   1022: 
                   1023: /*
                   1024:  * This sets the filler character to use when drawing the widget.
                   1025:  */
                   1026: void setCDKMentryFillerChar (CDKMENTRY *mentry, chtype filler)
                   1027: {
                   1028:    mentry->filler = filler;
                   1029: }
                   1030: chtype getCDKMentryFillerChar (CDKMENTRY *mentry)
                   1031: {
                   1032:    return mentry->filler;
                   1033: }
                   1034: 
                   1035: /*
                   1036:  * This sets the character to use when a hidden character type is used.
                   1037:  */
                   1038: void setCDKMentryHiddenChar (CDKMENTRY *mentry, chtype character)
                   1039: {
                   1040:    mentry->hidden = character;
                   1041: }
                   1042: chtype getCDKMentryHiddenChar (CDKMENTRY *mentry)
                   1043: {
                   1044:    return mentry->hidden;
                   1045: }
                   1046: 
                   1047: /*
                   1048:  * This sets the minimum length of the widget.
                   1049:  */
                   1050: void setCDKMentryMin (CDKMENTRY *mentry, int min)
                   1051: {
                   1052:    mentry->min = min;
                   1053: }
                   1054: int getCDKMentryMin (CDKMENTRY *mentry)
                   1055: {
                   1056:    return mentry->min;
                   1057: }
                   1058: 
                   1059: /*
                   1060:  * This sets the widgets box attribute.
                   1061:  */
                   1062: void setCDKMentryBox (CDKMENTRY *mentry, boolean Box)
                   1063: {
                   1064:    ObjOf(mentry)->box = Box;
                   1065: }
                   1066: boolean getCDKMentryBox (CDKMENTRY *mentry)
                   1067: {
                   1068:    return ObjOf(mentry)->box;
                   1069: }
                   1070: 
                   1071: /*
                   1072:  * This erases the information in the multiple line entry widget.
                   1073:  */
                   1074: void cleanCDKMentry (CDKMENTRY *mentry)
                   1075: {
                   1076:    /* Erase the information in the character pointer. */
                   1077:    cleanChar (mentry->info, mentry->infoWidth, '\0');
                   1078: 
                   1079:    mentry->currentRow  = 0;
                   1080:    mentry->currentCol  = 0;
                   1081:    mentry->topRow      = 0;
                   1082: }
                   1083: 
                   1084: /*
                   1085:  * This sets the callback function.
                   1086:  */
                   1087: void setCDKMentryCB (CDKMENTRY *mentry, MENTRYCB callback)
                   1088: {
                   1089:    mentry->callbackfn = (void *)callback;
                   1090: }
                   1091: 
                   1092: /*
                   1093:  * This function sets the pre-process function.
                   1094:  */
                   1095: void setCDKMentryPreProcess (CDKMENTRY *mentry, PROCESSFN callback, void *data)
                   1096: {
                   1097:    mentry->preProcessFunction = callback;
                   1098:    mentry->preProcessData = data;
                   1099: }
                   1100: 
                   1101: /*
                   1102:  * This function sets the post-process function.
                   1103:  */
                   1104: void setCDKMentryPostProcess (CDKMENTRY *mentry, PROCESSFN callback, void *data)
                   1105: {
                   1106:    mentry->postProcessFunction = callback;
                   1107:    mentry->postProcessData = data;
                   1108: }

CVSweb <webmaster@jp.NetBSD.org>