home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Edit Batch entries. Uses EDIT object as a parent Class
- *
- * (C) 1990 Vision Software
- *
- * $Id: batch.c 1.2003 91/05/06 14:23:40 pcalvin beta $
- *
- * Comments:
- *
- * This class allows the user to Add/Edit and Delete structures without
- * the usual headaches. This class is a collection of various others
- * EDIT handles the Field I/O. DATABASE handles the Record I/O. Not
- * much to do but sit back and take the credit..
- *
- * Bugs:
- *
- * None documented
- */
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <conio.h>
- #include <io.h>
-
- #include <stdhdr.h>
-
- #include <adl.h>
- #include <menu.h>
- #include <dbase.h>
- #include <edit.h>
- #include <batch.h>
-
- #include "lowlevel.h"
-
- /*
- * Strings used for the various run-time operations
- */
- STATIC SZ szAskCreate = "Would you like to create this record?";
- STATIC SZ szHlpCreate = "Press \"Y\" to create, \"N\" to abandon";
- STATIC SZ szAskSave = "Would you like to save the changes?";
- STATIC SZ szHlpSave = "Press \"Y\" to save this record, \"N\" to abandon changes";
- STATIC SZ szAskDelete = "Delete this record, Are you sure?";
- STATIC SZ szHlpDelete = "Press \"Y\" to delete record, \"N\" to abort";
- STATIC SZ szHlpIndex = "Select key for record ordering";
-
- INLINE VOID BATCH::PrepRecForRead()
- {
- if (pfnRead != Nil)
- pfnRead(pdtb->PdbQuery());
- }
-
- INLINE VOID BATCH::PrepRecForWrite()
- {
- if (pfnWrite != Nil)
- pfnWrite(pdtb->PdbQuery());
- }
-
- /*
- * Must open the DATABASE ourselves. No problem
- */
- BATCH::BATCH(DBASE *pdb,CCH cchRecord,SZ szFileName,SZ sz,FNPDB pfnR,FNPDB pfnW) : EDIT(fTrue,sz)
- {
- pdtb = new DATABASE(pdb,cchRecord,szFileName,fTrue);
- fDeleteDatabase = fTrue;
- fCreateRecord = fFalse;
- pfnRead = pfnR;
- pfnWrite = pfnW;
- cmiMac = cmiNil;
- pmiCurrent = pmiNil;
- }
-
- /*
- * Database is already created. It will remain open after BATCH
- */
- BATCH::BATCH(DATABASE &rdtbOriginal,SZ sz,FNPDB pfnR,FNPDB pfnW) : EDIT(fTrue,sz)
- {
- pdtb = &rdtbOriginal;
- fDeleteDatabase = fFalse;
- fCreateRecord = fFalse;
- pfnRead = pfnR;
- pfnWrite = pfnW;
- cmiMac = cmiNil;
- pmiCurrent = pmiNil;
- }
-
- /*
- * Close the DATABASE if it was created
- */
- BATCH::~BATCH()
- {
- if (fDeleteDatabase)
- delete pdtb;
- }
-
- /*
- * Initializes the read. Simply rewinds the DATABASE and calls
- * EDIT.
- */
- VOID BATCH::Read()
- {
- if (cmiMac > cmiNil)
- Verify(FSelectCmi(cmiNil));
- else
- fCreateRecord = !pdtb->FFirst();
-
- EDIT::Read();
- }
-
- /*
- * Creates a field() that may be used to change the active
- * index file within an edit..
- */
- VOID BATCH::IndexSelector(ROW row,COL col,SZ szMsg,CENT cent,PENT pent,CENT centDefault)
- {
- Assert(centDefault < cent);
- Assert(pent != pentNil);
-
- CCH cch = CchFromCentPent(cent,pent);
-
- Field(row,col,szMsg,szSelector,'X',cch,szHlpIndex,pent[centDefault].sz);
-
- centIndex = cent;
- pentIndex = pent;
- pedIndex = PedQuery();
-
- pedIndex->Adjust(BATCH::FSelect,this,fFalse);
- }
-
- /*
- * Sets up an index field.
- */
- BOOL BATCH::FCreateIndex(SZ szIndex,CID cid,PED ped)
- {
- AssertSz(cmiMac < cmiOpenMax,"Too many index files");
-
- CMI cmi = cmiMac++;
- SZ sz = pdtb->SzIndex(cid);
- CCH cch = pdtb->CchIndex(cid);
-
- /*
- * Initialize index record, if there is a default string, copy that
- * into the index address.
- */
- pmiCurrent = &rgmiActive[cmi];
-
- pmiCurrent->cid = cid;
- pmiCurrent->szIndex = szIndex;
- pmiCurrent->sz = sz;
- pmiCurrent->cch = cch;
- pmiCurrent->row = ped->RowEdit() - 2;
- pmiCurrent->col = ped->ColLeft() - 1;
-
- strncpy(pmiCurrent->szIndex,sz,cch);
-
- /*
- * And select this as the current index.
- */
- return (FSelectCmi(cmiNil));
- }
-
- /*
- * Hooks up an index field. CID must be valid or program will ASSERT
- */
- VOID BATCH::Index(ROW row,COL col,CID cid,SZ szMessage,CHAR ch,SZ szHelp,SZ szDflt)
- {
- CCH cch = pdtb->CchIndex(cid);
- SZ sz = pdtb->SzIndex(cid);
- SZ szIndex = new CHAR[cch];
- SZ szDefault = (szDflt == szNil) ? szIndex : szDflt;
-
- Field(row,col,szMessage,szIndex,ch,cch,szHelp,szDefault);
-
- PED ped = PedQuery();
- ped->Adjust(BATCH::FChange,this,fFalse);
-
- if (szDefault != szIndex)
- strncpy(sz,szDefault,cch);
-
- Verify(FCreateIndex(szIndex,cid,ped));
- }
-
- /*
- * Sets up the index field for this batch
- */
- VOID BATCH::Index(ROW row,COL col,SZ szFile,SZ szMessage,SZ sz,CHAR ch,CCH cch,SZ szHelp,SZ szDflt)
- {
- SZ szIndex = new CHAR[cch];
- SZ szDefault = (szDflt == szNil) ? szIndex : szDflt;
-
- Field(row,col,szMessage,szIndex,ch,cch,szHelp,szDefault);
-
- PED ped = PedQuery();
- ped->Adjust(BATCH::FChange,this,fFalse);
-
- if (szDefault != szIndex)
- strncpy(sz,szDefault,cch);
-
- Verify(FCreateIndex(szIndex,pdtb->CidIndexOn(szFile,sz,cch),ped));
- }
-
- /*
- * Copies all indexes to their temporary storage areas..
- */
- VOID BATCH::SaveIndexes()
- {
- for (CMI cmi = cmiNil; cmi < cmiMac; cmi++)
- {
- strncpy(rgmiActive[cmi].szIndex,rgmiActive[cmi].sz,rgmiActive[cmi].cch);
- }
- }
-
- /*
- * Copies all indexes back from the temporary storage area..
- */
- VOID BATCH::RestoreIndexes()
- {
- for (CMI cmi = cmiNil; cmi < cmiMac; cmi++)
- {
- strncpy(rgmiActive[cmi].sz,rgmiActive[cmi].szIndex,rgmiActive[cmi].cch);
- }
- }
-
- /*
- * Selects new index file.
- */
- BOOL BATCH::FSelectCmi(CMI cmi)
- {
- BOOL fValid = fFalse;
-
- if (cmi < cmiMac)
- {
- pmiCurrent = &rgmiActive[cmi];
-
- Verify(pdtb->FIndexTo(pmiCurrent->cid));
-
- /*
- * If no records are available, clear the fields..
- */
- if (pdtb->FFirst())
- {
- fCreateRecord = fFalse;
- PrepRecForRead();
- }
- else
- {
- fCreateRecord = fTrue;
- ClearFields();
- }
-
- strcpy(szSelector,pentIndex[cmi].sz);
- SaveIndexes();
- RedrawFields();
- fValid = fTrue;
- }
-
- return (fValid);
- }
- /*
- * If the current record was modified, AND the user wants it saved,
- * do so, then clear the changed flags
- */
- VOID BATCH::MaybeSaveCurrent()
- {
- if (FModified())
- {
- /*
- * The field has been modified, must check if the record needs to be created
- * as well as saved..
- */
- if (fCreateRecord)
- {
- fCreateRecord = fFalse;
-
- if (FAskSz(szAskCreate,szHlpCreate))
- {
- RestoreIndexes();
- PrepRecForWrite();
- Verify(pdtb->FCreate());
- Verify(pdtb->FSave());
- }
- else
- {
- ClearFields();
- }
- }
- else if (FAskSz(szAskSave,szHlpSave))
- {
- PrepRecForWrite();
- Verify(pdtb->FSave());
- }
- }
-
- /*
- * Force "Unchanged" status.
- */
- ForceNoChanges();
- }
-
- /*
- * Asks if should Exit, continue or whatever
- */
- BOOL BATCH::FExit(void)
- {
- /*
- * Save if needed..
- */
- MaybeSaveCurrent();
- /*
- * Normal exit procedure
- */
- return (EDIT::FExit());
- }
-
- /*
- * Some new functionality added to our EDIT keys.
- *
- * PgUp: Next record
- * PgDn: Previous record
- * Home: First record
- * End: Last record
- * Del: Delete current record
- * Ins: Create record (Useful if creating duplicate key)
- */
- BOOL BATCH::FHandleCd(CD cd)
- {
- BOOL fContinue = fTrue;
-
- switch (cd)
- {
- case cdInsert:
- if (pmiCurrent->szIndex[0] != chNil && FAskSz(szAskCreate,szHlpCreate))
- {
- RestoreIndexes();
- PrepRecForWrite();
- Verify(pdtb->FCreate());
- ClearFields();
- Rewind();
- SaveIndexes();
- RedrawFields();
- Verify(pdtb->FSave());
- }
- break;
- case cdHome:
- /*
- * Be sure to save any changes..
- */
- MaybeSaveCurrent();
-
- if (pdtb->FFirst())
- {
- PrepRecForRead();
- SaveIndexes();
- RedrawFields();
- }
- break;
- case cdEnd:
- /*
- * Be sure to save any changes..
- */
- MaybeSaveCurrent();
-
- if (pdtb->FLast())
- {
- PrepRecForRead();
- SaveIndexes();
- RedrawFields();
- }
- break;
- case cdPageUp:
- /*
- * Be sure to save any changes..
- */
- MaybeSaveCurrent();
-
- if (pdtb->FPrevious())
- {
- PrepRecForRead();
- SaveIndexes();
- RedrawFields();
- }
- break;
- case cdPageDown:
- /*
- * Be sure to save any changes..
- */
- MaybeSaveCurrent();
-
- if (pdtb->FNext())
- {
- PrepRecForRead();
- SaveIndexes();
- RedrawFields();
- }
- break;
- case cdDelete:
- if (!fCreateRecord && FAskSz(szAskDelete,szHlpDelete))
- {
- fCreateRecord = !pdtb->FDelete();
- PrepRecForRead();
- Rewind();
- SaveIndexes();
- RedrawFields();
- }
- break;
- default:
- fContinue = EDIT::FHandleCd(cd);
- }
-
- return (fContinue);
- }
-
- /*
- * Checks for a change in the current field. If changes are found
- * Ask if save is wanted and attempt to edit the new Field..
- * Because a non-static member function requires a "this" pointer, we
- * make this a static member and pass the "this" pointer explicitly
- */
- BOOL BATCH::FChange(SZ sz,VOID *pv)
- {
- BATCH *pvThis = (BATCH *)pv;
- BOOL fContinue = fTrue;
-
- if (pvThis->pmiCurrent->szIndex == sz)
- {
- /*
- * Save record if needed
- */
- pvThis->MaybeSaveCurrent();
-
- /*
- * If the key is empty, provide a finder. Otherwise, edit or create
- * that key.
- */
- if (*sz == chNil)
- {
- ROW row = pvThis->wndEdit.RowQuery() + pvThis->pmiCurrent->row;
- COL col = pvThis->wndEdit.ColQuery() + pvThis->pmiCurrent->col;
-
- /*
- * Doesn't make sense to provide a finder, if there is nothing to find
- * If no finder provided, answer with an error. We cannot have
- * blank keys created..
- */
- if (pvThis->pdtb->FFirst())
- {
- VSCROLL vscr(row,col,10,*pvThis->pdtb);
- HELP help("Use cursor keys to select the desired record");
-
- /*
- * Supply finder to pick record, illegal entry if finder is ignored.
- */
- if (vscr.CentGet() != centError)
- {
- pvThis->PrepRecForRead();
- pvThis->SaveIndexes();
- }
- else
- {
- pvThis->ClearFields();
- fContinue = fFalse;
- }
- }
- else
- {
- fContinue = fFalse;
- }
- }
- else if (pvThis->pdtb->FGotoSz(sz,fTrue))
- {
- pvThis->PrepRecForRead();
- pvThis->SaveIndexes();
- }
- else
- {
- pvThis->fCreateRecord = fTrue;
- pvThis->ClearFields();
- }
-
- /*
- * Update display
- */
- pvThis->RedrawFields();
- }
-
- return (fContinue);
- }
-
- /*
- * Index selector. Used to provide finder if user wants to
- * change indexes..
- */
- BOOL BATCH::FSelect(SZ sz,VOID *pv)
- {
- BATCH *pvThis = (BATCH *)pv;
- ROW row = pvThis->wndEdit.RowQuery() + pvThis->pedIndex->RowEdit() - 2;
- COL col = pvThis->wndEdit.ColQuery() + pvThis->pedIndex->ColLeft() - 1;
- POPUP pop(row,col,pvThis->centIndex,pvThis->pentIndex);
- CENT cent = pop.CentGet();
-
- return ((cent == centError) ? fFalse : pvThis->FSelectCmi(cent));
- }
-