home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Generic Field Edit System
- *
- * (C) 1990 Vision Software
- *
- * $Id: edit.c 1.2002 91/05/04 17:18:43 pcalvin beta $
- *
- * Comments:
- *
- * This class provides the user with the ability to edit multiple fields
- * within a specific window. Input validation is handled by Clipper-like
- * pictures and validation functions. In addition, validation may now be
- * done by set validation (i.e using cent/pent to create fields)
- *
- * Bugs:
- *
- * None documented
- *
- */
- #include <stdio.h>
- #include <string.h>
-
- #include <stdhdr.h>
-
- #include <adl.h>
- #include <menu.h>
- #include <edit.h>
-
- #include "lowlevel.h"
-
- /*
- * Simple construction. Determines the Title and if the class should
- * ask for exit confirmation
- */
- EDIT::EDIT(BOOL fConfirm,SZ sz) : help(szNil)
- {
- fConfirmExit = fConfirm;
- szTtl = sz;
- pedLast = pedNil;
- pedFirst = pedNil;
- pedCurrent = pedNil;
- pifCurrent = pifNil;
- rowEditMax = rowNil;
- colEditMax = colNil;
- chLeft = '[';
- chRight = ']';
- }
-
- /*
- * Be sure to clean up any allocated memory..
- */
- EDIT::~EDIT()
- {
- /*
- * Delete any active Fields
- */
- while (pedLast != pedNil)
- {
- PED ped = (PED)pedLast->pifPrev;
-
- delete (pedLast);
- pedLast = ped;
- }
-
- /*
- * Delete any active Information layers
- */
- while (pifCurrent != pifNil)
- {
- PIF pif = pifCurrent->pifPrev;
-
- delete (pifCurrent);
- pifCurrent = pif;
- }
- }
-
- /*
- * Field creating. May be constructed in various fashions, all end up being
- * placed in chain..
- */
- VOID EDIT::Field(ROW row,COL col,SZ szMsg,SZ sz,CCH cch,SZ szHelp,CENT cent,PENT pent,CENT centDefault)
- {
- PED ped = new ED(wndEdit,row,col,szMsg,sz,cch,szHelp,cent,pent,centDefault);
-
- Verify(FInsertNewPed(ped));
- }
-
- VOID EDIT::Field(ROW row,COL col,SZ szMsg,SZ sz,CHAR ch,CCH cch,SZ szHelp,SZ szDefault)
- {
- PED ped = new ED(wndEdit,row,col,szMsg,sz,ch,cch,szHelp,szDefault);
-
- Verify(FInsertNewPed(ped));
- }
-
- VOID EDIT::Field(ROW row,COL col,SZ szMsg,SZ sz,SZ szPicture,SZ szHelp,SZ szDefault)
- {
- PED ped = new ED(wndEdit,row,col,szMsg,sz,szPicture,szHelp,szDefault);
-
- Verify(FInsertNewPed(ped));
- }
-
- VOID EDIT::Title(ROW row,COL col,SZ sz)
- {
- PIF pif = new IF(wndEdit,row,col,sz);
-
- /*
- * No constructors, must initialize ourselves
- */
- Assert(pif != pifNil);
- pif->pifNext = pifNil;
- pif->pifPrev = pifCurrent;
-
- /*
- * Must consider titles when computing dimensions of window
- */
- rowEditMax = Max(row,rowEditMax);
- colEditMax = Max(col+pif->ColRight(),colEditMax);
-
- if (pifCurrent != pifNil)
- pifCurrent->pifNext = pif;
-
- pifCurrent = pif;
- }
-
- VOID EDIT::Read()
- {
- AssertSz(pedFirst != pedNil,"EDIT::Read() called without fields");
-
- CURSOR crs(fTrue);
- BOOL fContinue = fTrue;
- PED ped = pedLast;
- PIF pif = pifCurrent;
-
- /*
- * Compute dimensions of window
- */
- ROW rowTop = (rowGlobalWindowBottom - rowEditMax) >> 1;
- ROW rowBottom = rowTop + rowEditMax + 1;
- COL colLeft = (colGlobalWindowRight - colEditMax) >> 1;
- COL colRight = colLeft + colEditMax + 1;
-
- /*
- * Simple Text window
- */
- wndEdit = WINDOW(rowTop,colLeft,rowBottom,colRight,coBlack,coCyan,szTtl);
- wndEdit.Open();
-
- /*
- * Display any title information
- */
- while (pif != pifNil)
- {
- pif->SayMessage();
- pif = pif->pifPrev;
- }
-
- /*
- * And titles/delimiters for messages..
- */
- while (ped != pedNil)
- {
- ped->SayMessage();
- ped->ShowDelimiters(chLeft,chRight);
-
- ped = (PED)ped->pifPrev;
- }
-
- /*
- * Start editing at first entered field..
- */
- Rewind();
- RedrawFields();
-
- while (fContinue)
- {
- /*
- * Cursor position at current edit
- */
- wndEdit.SetRowCol(pedCurrent->RowEdit(),pedCurrent->ColEdit());
-
- /*
- * Input handling is virtual..
- */
- fContinue = FHandleCd(CdInput());
- }
-
- /*
- * Cleanup the screen..
- */
- wndEdit.Close();
- }
-
- /*
- * Adds PED to the current list..
- */
- BOOL EDIT::FInsertNewPed(PED ped)
- {
- PointerAssert(ped);
-
- /*
- * Keep track of the first one..
- */
- if (pedFirst == pedNil)
- pedFirst = ped;
-
- /*
- * Setup links between both..
- */
- ped->pifNext = pedNil;
- ped->pifPrev = pedLast;
- /*
- * Determine the number of rows to display
- */
- rowEditMax = Max(ped->RowEdit(),rowEditMax);
- colEditMax = Max(ped->ColRight(),colEditMax);
-
- if (pedLast != pedNil)
- pedLast->pifNext = ped;
-
- pedLast = ped;
-
- return (fTrue);
- }
-
- /*
- * Force the edit to be considered "unchanged"
- */
- VOID EDIT::ForceNoChanges()
- {
- PED ped = pedLast;
-
- while (ped != pedNil)
- {
- ped->SetUnchanged();
- ped = (PED)ped->pifPrev;
- }
- }
-
- /*
- * Answers if any of the fields have been modified.
- */
- BOOL EDIT::FModified()
- {
- PED ped = pedLast;
- BOOL fChanges = fFalse;
-
- while (!fChanges && ped != pedNil)
- {
- fChanges = ped->FModified();
- ped = (PED)ped->pifPrev;
- }
-
- return (fChanges);
- }
-
- VOID EDIT::RedrawFields()
- {
- CURSOR crs(fFalse);
- REGISTER PED ped = pedLast;
-
- while (ped != pedNil)
- {
- ped->SetCursor();
- ped->SayEdit((ped == pedCurrent) ? fTrue : fFalse);
- ped = (PED)ped->pifPrev;
- }
- }
-
- BOOL EDIT::FExit(void)
- {
- /*
- * If user does not want to continue, edit will resume at the
- * start.
- */
- NewPed(pedNil);
- Rewind();
- RedrawFields();
-
- /*
- * And answer with user response
- */
- return (FAskSz("Terminate Current Edit?","Press \"Y\" to terminate edit, \"N\" to resume."));
- }
-
- VOID EDIT::Rewind()
- {
- NewPed(pedFirst);
- }
-
- VOID EDIT::ClearFields()
- {
- PED ped = pedLast;
-
- while (ped != pedNil)
- {
- ped->Clear();
- ped = (PED)ped->pifPrev;
- }
- }
-
- VOID EDIT::Delimiters(CHAR chL,CHAR chR)
- {
- chLeft = chL;
- chRight = chR;
- }
-
-
- BOOL EDIT::FHandleCd(CD cd)
- {
- BOOL fContinue = fTrue;
-
- switch (cd)
- {
- case cdEscape:
- if (!fConfirmExit || FExit())
- fContinue = fFalse;
-
- break;
- case cdReturn:
- case cdCursorDown:
- if (pedCurrent->FValidate())
- {
- if (pedCurrent->pifNext != pedNil)
- NewPed((PED)pedCurrent->pifNext);
- else if (cd == cdReturn && (!fConfirmExit || FExit()))
- fContinue = fFalse;
- }
- break;
- case cdCursorUp:
- if (pedCurrent->FValidate())
- {
- if (pedCurrent->pifPrev != pedNil)
- NewPed((PED)pedCurrent->pifPrev);
- }
- break;
- case cdCursorLeft:
- pedCurrent->CursorLeft();
- break;
- case cdCursorRight:
- pedCurrent->CursorRight();
- break;
- case cdBackSpace:
- Verify(pedCurrent->FDelete());
- break;
- default:
- Verify(pedCurrent->FInsertCd(cd));
- break;
- }
-
- return (fContinue);
- }
-
- /*
- * Answers with the last ED() structure created.
- */
- PED EDIT::PedQuery()
- {
- return (pedLast);
- }
-
- /*
- * Redraws current and new edit.
- */
- VOID EDIT::NewPed(PED ped)
- {
- if (pedCurrent != pedNil)
- {
- pedCurrent->SayEdit(fFalse);
- }
-
- if (ped != pedNil)
- {
- ped->SayEdit(fTrue);
- ped->SetCursor();
- ped->UpdateHelp(help);
- }
-
- pedCurrent = ped;
- }
-
-