1056 lines
23 KiB
C
1056 lines
23 KiB
C
/*
|
|
TELE.C
|
|
|
|
Written by DavidW
|
|
Started on 20/11/91
|
|
|
|
*/
|
|
|
|
#include <p_std.h>
|
|
#include <p_file.h>
|
|
#include <p_dbf.h>
|
|
#include <wlib.h>
|
|
#include <hwif.h>
|
|
|
|
GLREF_D UWORD DatLocked;
|
|
GLREF_D TEXT *DatUsedPathNamePtr;
|
|
|
|
|
|
LOCAL_D TEXT *cmds[]=
|
|
{
|
|
"nNew",
|
|
"oOpen",
|
|
"mMerge",
|
|
"sSave as",
|
|
"kCompress",
|
|
"xExit",
|
|
"iInsert",
|
|
"cCopy",
|
|
"uUpdate",
|
|
"aAdd",
|
|
"dDelete",
|
|
"rFind previous",
|
|
"fFind",
|
|
"gFind next",
|
|
"jJump to",
|
|
"zSort",
|
|
"lDial",
|
|
"yPrint setup",
|
|
"pPrint",
|
|
NULL
|
|
};
|
|
|
|
#define FILE_ITEMS 6
|
|
#define EDIT_ITEMS 5
|
|
#define FIND_ITEMS 3
|
|
#define SPECIAL_ITEMS 5
|
|
|
|
#define ITEMS_BEFORE_FILE 0
|
|
#define ITEMS_BEFORE_EDIT FILE_ITEMS
|
|
#define ITEMS_BEFORE_FIND (ITEMS_BEFORE_EDIT+EDIT_ITEMS)
|
|
#define ITEMS_BEFORE_SPECIAL (ITEMS_BEFORE_FIND+FIND_ITEMS)
|
|
|
|
LOCAL_D H_MENU_DATA mdata[]=
|
|
{
|
|
"File",FILE_ITEMS,
|
|
"Edit",EDIT_ITEMS,
|
|
"Find",FIND_ITEMS,
|
|
"Special",SPECIAL_ITEMS,
|
|
NULL
|
|
};
|
|
|
|
GLDEF_D TEXT ** _cmds=(&cmds[0]);
|
|
GLDEF_D H_MENU_DATA * _mdata=(&mdata[0]);
|
|
|
|
|
|
LOCAL_D UINT MainWid;
|
|
|
|
LOCAL_D struct
|
|
{
|
|
UWORD dataStart;
|
|
UWORD needVersion;
|
|
UWORD firHeader;
|
|
UBYTE fir[3];
|
|
} ModelHeader=
|
|
{
|
|
DbfHeaderLength,
|
|
0x100f,
|
|
(DbfRecordTypeFir<<12)|3,
|
|
{
|
|
DbfFieldTypeString,
|
|
DbfFieldTypeString,
|
|
DbfFieldTypeWord
|
|
}
|
|
};
|
|
|
|
LOCAL_D TEXT filename[P_FNAMESIZE];
|
|
LOCAL_D VOID *dH;
|
|
LOCAL_D UBYTE dBuf[512];
|
|
LOCAL_D UWORD dOff;
|
|
|
|
typedef struct
|
|
{
|
|
TEXT nam[20];
|
|
TEXT dep[4];
|
|
WORD nmb;
|
|
} ENTRY;
|
|
|
|
LOCAL_D ENTRY clip;
|
|
LOCAL_D UWORD clipfill=FALSE;
|
|
|
|
LOCAL_D TEXT find[22]={0};
|
|
|
|
LOCAL_D UWORD PrintState;
|
|
LOCAL_D TEXT PrintBuf[10];
|
|
LOCAL_D UWORD PrintRec;
|
|
LOCAL_D ENTRY PrintEnt;
|
|
|
|
#define NAME_TLY 4
|
|
#define DEPT_TLY 24
|
|
#define TELE_TLY 44
|
|
#define COUNT_TLY 58
|
|
#define TEXT_HEIGHT 18
|
|
#define TEXT_ASCENT 16
|
|
|
|
#define LABEL_TLX 15
|
|
#define LABEL_WID 30
|
|
#define FIELD_TLX 65
|
|
#define FIELD_WID 120
|
|
#define COUNT_TLX 105
|
|
#define COUNT_WID 75
|
|
|
|
#define TRN_CALL call(reg_param=>(bx,si),reg_saved=>(cx,dx,di,EPOC_SAVE))
|
|
|
|
|
|
LOCAL_C VOID DisplayPrompt(INT tly,TEXT *buf)
|
|
{
|
|
P_RECT box;
|
|
|
|
box.tl.y=tly;
|
|
box.tl.x=LABEL_TLX;
|
|
box.br.x=LABEL_TLX+LABEL_WID;
|
|
box.br.y=tly+TEXT_HEIGHT;
|
|
gPrintBoxText(&box,TEXT_ASCENT,G_TEXT_ALIGN_CENTRE,0,buf,p_slen(buf));
|
|
}
|
|
|
|
LOCAL_C VOID DisplayPrompts(VOID)
|
|
{
|
|
DisplayPrompt(NAME_TLY,"Name");
|
|
DisplayPrompt(DEPT_TLY,"Dept");
|
|
DisplayPrompt(TELE_TLY,"\05");
|
|
}
|
|
|
|
LOCAL_C VOID DisplayField(INT tly,TEXT *buf,INT len)
|
|
{
|
|
P_RECT box;
|
|
|
|
box.tl.y=tly;
|
|
box.tl.x=FIELD_TLX;
|
|
box.br.x=FIELD_TLX+FIELD_WID;
|
|
box.br.y=tly+TEXT_HEIGHT;
|
|
gPrintBoxText(&box,TEXT_ASCENT,G_TEXT_ALIGN_LEFT,0,buf,len);
|
|
}
|
|
|
|
LOCAL_C VOID DisplayCount(TEXT *buf)
|
|
{
|
|
P_RECT box;
|
|
|
|
box.tl.x=COUNT_TLX;
|
|
box.tl.y=COUNT_TLY;
|
|
box.br.x=COUNT_TLX+COUNT_WID;
|
|
box.br.y=COUNT_TLY+TEXT_HEIGHT;
|
|
gPrintBoxText(&box,TEXT_ASCENT,G_TEXT_ALIGN_RIGHT,0,buf,p_slen(buf));
|
|
}
|
|
|
|
LOCAL_C VOID BufToEntry(ENTRY *pent)
|
|
{
|
|
UBYTE *psrc;
|
|
INT len;
|
|
|
|
psrc=(&dBuf[dOff+2]);
|
|
len=(*psrc)+1;
|
|
p_bcpy(&pent->nam[0],psrc,len);
|
|
psrc+=len;
|
|
len=(*psrc)+1;
|
|
p_bcpy(&pent->dep[0],psrc,len);
|
|
psrc+=len;
|
|
pent->nmb=(*(WORD *)psrc);
|
|
}
|
|
|
|
LOCAL_C VOID CleanEntry(ENTRY *pent)
|
|
{
|
|
p_bfil(pent,sizeof(ENTRY),0);
|
|
}
|
|
|
|
LOCAL_C VOID Display(VOID)
|
|
{
|
|
ENTRY ent;
|
|
UWORD count;
|
|
TEXT buf[12];
|
|
TEXT num[4];
|
|
INT len;
|
|
|
|
count=DbfCount(dH);
|
|
if (count)
|
|
{
|
|
p_atos(&buf[0],"%u/%u",DbfSense(dH)+1,count);
|
|
BufToEntry(&ent);
|
|
}
|
|
else
|
|
{
|
|
p_scpy(&buf[0],"Empty");
|
|
CleanEntry(&ent);
|
|
}
|
|
DisplayField(NAME_TLY,&ent.nam[1],ent.nam[0]);
|
|
DisplayField(DEPT_TLY,&ent.dep[1],ent.dep[0]);
|
|
if (ent.nmb)
|
|
len=p_itob(&num[0],ent.nmb);
|
|
else
|
|
len=0;
|
|
DisplayField(TELE_TLY,&num[0],len);
|
|
DisplayCount(&buf[0]);
|
|
}
|
|
|
|
LOCAL_C INT EditEntry(ENTRY *pent,TEXT *title)
|
|
{
|
|
H_DI_EDIT edname;
|
|
H_DI_EDIT eddept;
|
|
LONG lnumb;
|
|
H_DI_NUMBER numb;
|
|
|
|
if (uOpenDialog(title))
|
|
return(-1);
|
|
edname.len=19;
|
|
edname.str=(&pent->nam[0]);
|
|
if (uAddDialogItem(H_DIALOG_EDIT,"Name",&edname))
|
|
return(-1);
|
|
eddept.len=3;
|
|
eddept.str=(&pent->dep[0]);
|
|
if (uAddDialogItem(H_DIALOG_EDIT,"Dept",&eddept))
|
|
return(-1);
|
|
lnumb=pent->nmb;
|
|
numb.value=(&lnumb);
|
|
numb.low=100;
|
|
numb.high=999;
|
|
if (uAddDialogItem(H_DIALOG_NUMBER,"Number",&numb))
|
|
return(-1);
|
|
if (uRunDialog()<=0)
|
|
return(-1);
|
|
pent->nmb=lnumb;
|
|
return(0);
|
|
}
|
|
|
|
LOCAL_C INT EntryToBuf(ENTRY *pent)
|
|
{
|
|
INT len1;
|
|
INT len2;
|
|
UBYTE *pb;
|
|
|
|
len1=pent->nam[0]+1;
|
|
pb=(&dBuf[2]);
|
|
pb=p_bcpy(pb,&pent->nam[0],len1);
|
|
len2=pent->dep[0]+1;
|
|
pb=p_bcpy(pb,&pent->dep[0],len2);
|
|
*(WORD *)pb=pent->nmb;
|
|
dOff=0;
|
|
return(len1+len2+2);
|
|
}
|
|
|
|
LOCAL_C INT Check(INT val)
|
|
{
|
|
TEXT buf[64];
|
|
|
|
if (val<0 && val!=E_FILE_EOF)
|
|
{
|
|
uForceToFront();
|
|
DatLocked=TRUE;
|
|
p_errs(&buf[0],val);
|
|
wsAlertW(WS_ALERT_CLIENT,&buf[0],"Terminating application",0);
|
|
p_exit(0);
|
|
}
|
|
return(val);
|
|
}
|
|
|
|
LOCAL_C VOID DoUpdate(INT len)
|
|
{
|
|
INT state;
|
|
|
|
state=DbfStateDisabled;
|
|
Check(DbfUpdate(&state,dH,len));
|
|
}
|
|
|
|
LOCAL_C VOID DoAppend(INT len)
|
|
{
|
|
Check(DbfAppend(dH,len));
|
|
Display();
|
|
}
|
|
|
|
LOCAL_C VOID AddRecord(VOID)
|
|
{
|
|
ENTRY new;
|
|
|
|
CleanEntry(&new);
|
|
if (!EditEntry(&new,"Add new record"))
|
|
DoAppend(EntryToBuf(&new));
|
|
}
|
|
|
|
LOCAL_C VOID UpdateRecord(VOID)
|
|
{
|
|
ENTRY ent;
|
|
|
|
if (!DbfCount(dH))
|
|
{
|
|
wInfoMsg("No record to update");
|
|
return;
|
|
}
|
|
BufToEntry(&ent);
|
|
if (!EditEntry(&ent,"Update record"))
|
|
{
|
|
DoUpdate(EntryToBuf(&ent));
|
|
Display();
|
|
}
|
|
}
|
|
|
|
LOCAL_C INT Transition(
|
|
#pragma save,TRN_CALL
|
|
INT pf(VOID *,UWORD *))
|
|
#pragma restore
|
|
{
|
|
return(Check(pf(dH,&dOff)));
|
|
}
|
|
|
|
LOCAL_C VOID DeleteRecord(VOID)
|
|
{
|
|
INT state;
|
|
|
|
if (!DbfCount(dH))
|
|
{
|
|
wInfoMsg("No record to delete");
|
|
return;
|
|
}
|
|
if (uOpenDialog("Delete current record"))
|
|
return;
|
|
if (uAddButtonList("No",-'n',"Yes",'y',NULL))
|
|
return;
|
|
if (uRunDialog()!='y')
|
|
return;
|
|
state=DbfStateDisabled;
|
|
if (Check(DbfEraseRead(&state,dH,&dOff))<0)
|
|
Transition(DbfBackRead);
|
|
Display();
|
|
}
|
|
|
|
LOCAL_C VOID InsertFromClipboard(VOID)
|
|
{
|
|
if (!clipfill)
|
|
{
|
|
wInfoMsg("No record to insert");
|
|
return;
|
|
}
|
|
DoAppend(EntryToBuf(&clip));
|
|
}
|
|
|
|
LOCAL_C VOID CopyToClipboard(VOID)
|
|
{
|
|
if (!DbfCount(dH))
|
|
{
|
|
wInfoMsg("No record to copy");
|
|
return;
|
|
}
|
|
BufToEntry(&clip);
|
|
clipfill=TRUE;
|
|
wInfoMsg("Record copied");
|
|
}
|
|
|
|
LOCAL_C INT Search(INT dir)
|
|
{
|
|
UINT state;
|
|
INT len;
|
|
INT ret;
|
|
|
|
len=find[0];
|
|
find[0]='*';
|
|
find[len+1]='*';
|
|
state=DbfStateDisabled;
|
|
ret=Check(DbfFindRead(&state,dH,&find[0],len+2,
|
|
255|dir|DbfFindCaseIndependent,2,&dOff));
|
|
find[0]=len;
|
|
return(ret);
|
|
}
|
|
|
|
LOCAL_C INT ResetTo(UINT current)
|
|
{
|
|
return(Check(DbfAbsRead(dH,current,&dOff)));
|
|
}
|
|
|
|
LOCAL_C VOID DoFind(INT dir)
|
|
{
|
|
UINT current;
|
|
|
|
current=DbfSense(dH);
|
|
if (Search(dir)>=0)
|
|
Display();
|
|
else
|
|
{
|
|
ResetTo(current);
|
|
wInfoMsg("Not found");
|
|
}
|
|
}
|
|
|
|
LOCAL_C VOID FindAgain(INT dir1,INT dir2,
|
|
#pragma save,TRN_CALL
|
|
INT pf(VOID *,UWORD *))
|
|
#pragma restore
|
|
{
|
|
UINT current;
|
|
|
|
current=DbfSense(dH);
|
|
if (Transition(pf)>=0 && Search(dir1)>=0
|
|
|| Search(dir2)>=0 && DbfSense(dH)!=current)
|
|
Display();
|
|
else
|
|
{
|
|
ResetTo(current);
|
|
wInfoMsg("No more found");
|
|
}
|
|
}
|
|
|
|
LOCAL_C VOID FindNext(VOID)
|
|
{
|
|
FindAgain(DbfFindForwards,DbfFindFirst,DbfNextRead);
|
|
}
|
|
|
|
LOCAL_C VOID FindPrevious(VOID)
|
|
{
|
|
FindAgain(DbfFindBackwards,DbfFindLast,DbfBackRead);
|
|
}
|
|
|
|
LOCAL_C VOID FindRecord(VOID)
|
|
{
|
|
H_DI_EDIT edfind;
|
|
|
|
if (uOpenDialog(NULL))
|
|
return;
|
|
edfind.str=(&find[0]);
|
|
edfind.len=19;
|
|
if (uAddDialogItem(H_DIALOG_EDIT,"Find",&edfind))
|
|
return;
|
|
if (uAddButtonList("Cancel",W_KEY_ESCAPE,"Find backwards",W_KEY_TAB,
|
|
"Find forwards",W_KEY_RETURN,NULL))
|
|
return;
|
|
switch (uRunDialog())
|
|
{
|
|
case W_KEY_TAB:
|
|
DoFind(DbfFindLast);
|
|
case 0:
|
|
return;
|
|
case W_KEY_RETURN:
|
|
DoFind(DbfFindFirst);
|
|
}
|
|
}
|
|
|
|
LOCAL_C VOID DialNumber(VOID)
|
|
{
|
|
ENTRY tmp;
|
|
TEXT buf[4];
|
|
|
|
if (!DbfCount(dH))
|
|
{
|
|
wInfoMsg("No number to dial");
|
|
return;
|
|
}
|
|
BufToEntry(&tmp);
|
|
buf[p_itob(&buf[0],tmp.nmb)]=0;
|
|
if (hDTMFString(&buf[0]))
|
|
wInfoMsg("Sound device busy");
|
|
}
|
|
|
|
LOCAL_C VOID CompressFile(VOID)
|
|
{
|
|
UINT state;
|
|
|
|
if (!hIsDbfCompressible(dH))
|
|
wInfoMsg("Cannot compress on Flash");
|
|
else
|
|
{
|
|
state=DbfStateDisabled;
|
|
Check(DbfCompress(&state,dH));
|
|
wInfoMsg("File compressed");
|
|
}
|
|
}
|
|
|
|
LOCAL_C VOID ChangeName(TEXT *newname)
|
|
{
|
|
p_scpy(&filename[0],newname);
|
|
hSetUpStatusNames(&filename[0]);
|
|
wsUpdate(WS_UPDATE_NAME);
|
|
}
|
|
|
|
LOCAL_C VOID DisplayStart(VOID)
|
|
{
|
|
Transition(DbfFirstRead);
|
|
Display();
|
|
}
|
|
|
|
LOCAL_C VOID ChangeOverTo(VOID *newdH,TEXT *newname)
|
|
{
|
|
DbfClose(dH);
|
|
dH=newdH;
|
|
ChangeName(newname);
|
|
DisplayStart();
|
|
}
|
|
|
|
LOCAL_C INT doOpen(VOID **pdH,TEXT *pb,INT flags,DbfHeader *pHead)
|
|
{
|
|
INT state;
|
|
|
|
state=DbfStateDisabled;
|
|
p_scpy((TEXT *)&pHead->fileType[0],"OPLDatabaseFile");
|
|
return(uErrorValue(DbfOpen(&state,pdH,pb,flags,pHead,&dBuf[0],512,1)));
|
|
}
|
|
|
|
LOCAL_C INT TryOpenDbf(TEXT *pb,VOID **pdH)
|
|
{
|
|
DbfHeader Header;
|
|
|
|
return(doOpen(pdH,pb,P_FOPEN|P_FUPDATE|P_FRANDOM,&Header));
|
|
}
|
|
|
|
LOCAL_C VOID SetupFilename(TEXT *pb)
|
|
{
|
|
p_bcpy(pb+1,DatUsedPathNamePtr,*pb=p_slen(DatUsedPathNamePtr));
|
|
}
|
|
|
|
LOCAL_C VOID OpenDbf(VOID)
|
|
{
|
|
H_DI_FSEL open;
|
|
TEXT openbuf[P_FNAMESIZE+2];
|
|
VOID *newdH;
|
|
UINT current;
|
|
|
|
current=DbfSense(dH);
|
|
SetupFilename(open.fname=(&openbuf[0]));
|
|
open.flags=H_FILE_PICK_SELECTOR|H_FILE_RESTRICT_LIST|H_FILE_SET_DEFEXT;
|
|
FOREVER
|
|
{
|
|
if (uOpenDialog("Open telephone file"))
|
|
break;
|
|
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&open))
|
|
break;
|
|
if (uRunDialog()<=0)
|
|
break;
|
|
openbuf[1+openbuf[0]]=0;
|
|
if (!TryOpenDbf(&openbuf[1],&newdH))
|
|
{
|
|
ChangeOverTo(newdH,&openbuf[1]);
|
|
return;
|
|
}
|
|
}
|
|
ResetTo(current);
|
|
}
|
|
|
|
LOCAL_C INT TryNewDbf(TEXT *pb,VOID **pdH)
|
|
{
|
|
DbfHeader Header;
|
|
|
|
hEnsurePath(pb);
|
|
Header.createVersion=DbfVersion();
|
|
p_bcpy(&Header.dataStart,&ModelHeader,sizeof(ModelHeader));
|
|
return(doOpen(pdH,pb,P_FREPLACE|P_FUPDATE|P_FRANDOM,&Header));
|
|
}
|
|
|
|
LOCAL_C VOID NewDbf(VOID)
|
|
{
|
|
H_DI_FSEL new;
|
|
TEXT newbuf[P_FNAMESIZE+2];
|
|
VOID *newdH;
|
|
UINT current;
|
|
|
|
current=DbfSense(dH);
|
|
SetupFilename(new.fname=(&newbuf[0]));
|
|
new.flags=H_FILE_NEW_EDITOR|H_FILE_SET_DEFEXT;
|
|
FOREVER
|
|
{
|
|
if (uOpenDialog("New telephone file"))
|
|
break;
|
|
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&new))
|
|
break;
|
|
if (uRunDialog()<=0)
|
|
break;
|
|
newbuf[1+newbuf[0]]=0;
|
|
if (!TryNewDbf(&newbuf[1],&newdH))
|
|
{
|
|
ChangeOverTo(newdH,&newbuf[1]);
|
|
return;
|
|
}
|
|
}
|
|
ResetTo(current);
|
|
}
|
|
|
|
LOCAL_C INT DoMerge(TEXT *pb,INT flags,INT dir)
|
|
{
|
|
UINT state;
|
|
|
|
state=DbfStateDisabled;
|
|
return(uErrorValue(DbfCopyFile(&state,dH,pb,flags,1,dir)));
|
|
}
|
|
|
|
LOCAL_C VOID MergeDbf(VOID)
|
|
{
|
|
H_DI_FSEL merge;
|
|
TEXT mergebuf[P_FNAMESIZE+2];
|
|
UINT current;
|
|
|
|
current=DbfSense(dH);
|
|
SetupFilename(merge.fname=(&mergebuf[0]));
|
|
merge.flags=H_FILE_PICK_SELECTOR|H_FILE_RESTRICT_LIST|H_FILE_SET_DEFEXT;
|
|
FOREVER
|
|
{
|
|
if (uOpenDialog("Merge telephone file"))
|
|
break;
|
|
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&merge))
|
|
break;
|
|
if (uRunDialog()<=0)
|
|
break;
|
|
mergebuf[1+mergebuf[0]]=0;
|
|
if (!DoMerge(&mergebuf[1],P_FOPEN,DbfCopyToHandle))
|
|
{
|
|
wInfoMsg("File merged");
|
|
DisplayStart();
|
|
return;
|
|
}
|
|
}
|
|
ResetTo(current);
|
|
}
|
|
|
|
LOCAL_C VOID DoSave(TEXT *pb,INT usenew)
|
|
{
|
|
if (DoMerge(pb,P_FUPDATE|P_FREPLACE,DbfCopyFromHandle))
|
|
return;
|
|
if (usenew)
|
|
{
|
|
DbfClose(dH);
|
|
ChangeName(pb);
|
|
while (TryOpenDbf(pb,&dH))
|
|
;
|
|
DisplayStart();
|
|
}
|
|
wInfoMsg("Saved");
|
|
}
|
|
|
|
LOCAL_C VOID SaveDbfAs(VOID)
|
|
{
|
|
H_DI_FSEL save;
|
|
TEXT savebuf[P_FNAMESIZE+2];
|
|
UWORD usenew;
|
|
|
|
if (uOpenDialog("Save as"))
|
|
return;
|
|
SetupFilename(save.fname=(&savebuf[0]));
|
|
save.flags=H_FILE_NEW_EDITOR|H_FILE_SET_DEFEXT;
|
|
if (uAddDialogItem(H_DIALOG_FSEL,"File:",&save))
|
|
return;
|
|
usenew=1;
|
|
if (uAddChoiceList("Use new file",&usenew,"No","Yes",NULL))
|
|
return;
|
|
if (uRunDialog())
|
|
{
|
|
savebuf[1+savebuf[0]]=0;
|
|
hEnsurePath(&savebuf[1]);
|
|
DoSave(&savebuf[1],usenew==2);
|
|
}
|
|
}
|
|
|
|
LOCAL_C INT ordf(INT r1,INT r2,VOID *base)
|
|
{
|
|
UBYTE *table;
|
|
UBYTE *e1;
|
|
UBYTE *e2;
|
|
INT entlen;
|
|
|
|
table=(UBYTE *)base;
|
|
entlen=(*(UWORD *)table);
|
|
table+=2;
|
|
r1=(*(UWORD *)(table+r1*entlen));
|
|
r2=(*(UWORD *)(table+r2*entlen));
|
|
table+=2;
|
|
e1=table+r1*entlen;
|
|
e2=table+r2*entlen;
|
|
return(p_bcmp(e1+1,*e1,e2+1,*e2));
|
|
}
|
|
|
|
LOCAL_C VOID excf(INT r1,INT r2,VOID *base)
|
|
{
|
|
UBYTE *table;
|
|
INT entlen;
|
|
UWORD *p1;
|
|
UWORD *p2;
|
|
UWORD swap;
|
|
|
|
table=(UBYTE *)base;
|
|
entlen=(*(UWORD *)table);
|
|
table+=2;
|
|
p1=(UWORD *)(table+r1*entlen);
|
|
p2=(UWORD *)(table+r2*entlen);
|
|
swap=(*p1);
|
|
*p1=(*p2);
|
|
*p2=swap;
|
|
}
|
|
|
|
LOCAL_C INT DoSort(UINT k,INT len)
|
|
{
|
|
INT entlen;
|
|
UBYTE *table;
|
|
INT i,j;
|
|
INT thislen;
|
|
UBYTE *target;
|
|
UBYTE *source;
|
|
UWORD moved;
|
|
INT ret;
|
|
|
|
entlen=len+3;
|
|
table=p_alloc(2+k*entlen);
|
|
if (!table)
|
|
{
|
|
uErrorString("Insufficient memory");
|
|
return(-1);
|
|
}
|
|
*(UWORD *)table=entlen;
|
|
Transition(DbfFirstRead);
|
|
target=table+2;
|
|
for (i=0; i<k; i++)
|
|
{
|
|
source=(&dBuf[dOff+2]);
|
|
thislen=(*source++);
|
|
if (thislen>len)
|
|
thislen=len;
|
|
*(UWORD *)target=i;
|
|
*(target+2)=thislen;
|
|
p_bcpy(target+3,source,thislen);
|
|
target+=entlen;
|
|
Transition(DbfNextRead);
|
|
}
|
|
if (p_qsort(k,ordf,excf,table))
|
|
{
|
|
uErrorString("Internal sort stack overflow");
|
|
ret=(-1);
|
|
}
|
|
else
|
|
{
|
|
for (i=0; i<k; i++)
|
|
{
|
|
moved=(*(UWORD *)(table+2+i*entlen));
|
|
ResetTo(moved);
|
|
DoUpdate(DbfCopyDown(dH,dOff));
|
|
target=table+2;
|
|
for (j=0; j<k; j++)
|
|
{
|
|
if (*(UWORD *)target>moved)
|
|
(*(UWORD *)target)--;
|
|
target+=entlen;
|
|
}
|
|
}
|
|
ret=0;
|
|
wInfoMsg("Sorted");
|
|
DisplayStart();
|
|
}
|
|
p_free(table);
|
|
return(ret);
|
|
}
|
|
|
|
LOCAL_C VOID SortDbf(VOID)
|
|
{
|
|
UINT k;
|
|
LONG len;
|
|
H_DI_NUMBER num;
|
|
UINT current;
|
|
|
|
k=DbfCount(dH);
|
|
if (!k)
|
|
{
|
|
wInfoMsg("No records to sort");
|
|
return;
|
|
}
|
|
current=DbfSense(dH);
|
|
len=19;
|
|
num.low=1;
|
|
num.high=19;
|
|
num.value=(&len);
|
|
FOREVER
|
|
{
|
|
if (uOpenDialog("Sort file by name"))
|
|
break;
|
|
if (uAddDialogItem(H_DIALOG_NUMBER,"Key length",&num))
|
|
break;
|
|
if (uRunDialog()<=0)
|
|
break;
|
|
if (DoSort(k,(INT)len))
|
|
return;
|
|
}
|
|
ResetTo(current);
|
|
}
|
|
|
|
LOCAL_C VOID JumpTo(VOID)
|
|
{
|
|
INT count;
|
|
LONG curr;
|
|
H_DI_NUMBER num;
|
|
|
|
count=DbfCount(dH);
|
|
if (!count)
|
|
{
|
|
wInfoMsg("No records to jump to");
|
|
return;
|
|
}
|
|
if (uOpenDialog(NULL))
|
|
return;
|
|
curr=DbfSense(dH)+1;
|
|
num.value=(&curr);
|
|
num.low=1;
|
|
num.high=count;
|
|
if (uAddDialogItem(H_DIALOG_NUMBER,"Jump to record",&num))
|
|
return;
|
|
if (uRunDialog()<=0)
|
|
return;
|
|
ResetTo((UINT)(curr-1));
|
|
Display();
|
|
}
|
|
|
|
LOCAL_C INT PrintLine(H_PRINT *pr)
|
|
{
|
|
switch (PrintState++)
|
|
{
|
|
case 0:
|
|
if (ResetTo(PrintRec++)<0)
|
|
return(0);
|
|
BufToEntry(&PrintEnt);
|
|
pr->buf=(&PrintEnt.nam[1]);
|
|
pr->blen=PrintEnt.nam[0];
|
|
pr->style|=2;
|
|
break;
|
|
case 1:
|
|
pr->buf=(&PrintEnt.dep[1]);
|
|
pr->blen=PrintEnt.dep[0];
|
|
break;
|
|
case 2:
|
|
pr->buf=(&PrintBuf[0]);
|
|
pr->blen=p_itob(&PrintBuf[0],PrintEnt.nmb);
|
|
break;
|
|
case 3:
|
|
pr->blen=0;
|
|
PrintState=0;
|
|
return(TRUE);
|
|
}
|
|
pr->flags|=0x8000;
|
|
return(TRUE);
|
|
}
|
|
|
|
LOCAL_C VOID DoPrint(VOID)
|
|
{
|
|
UINT current;
|
|
|
|
current=DbfSense(dH);
|
|
PrintState=0;
|
|
PrintRec=0;
|
|
hPrint(PrintLine);
|
|
ResetTo(current);
|
|
}
|
|
|
|
LOCAL_C VOID ManageCommand(INT index)
|
|
{
|
|
switch (index)
|
|
{
|
|
case ITEMS_BEFORE_FILE:
|
|
NewDbf();
|
|
break;
|
|
case ITEMS_BEFORE_FILE+1:
|
|
OpenDbf();
|
|
break;
|
|
case ITEMS_BEFORE_FILE+2:
|
|
MergeDbf();
|
|
break;
|
|
case ITEMS_BEFORE_FILE+3:
|
|
SaveDbfAs();
|
|
break;
|
|
case ITEMS_BEFORE_FILE+4:
|
|
CompressFile();
|
|
break;
|
|
case ITEMS_BEFORE_FILE+5:
|
|
p_exit(0);
|
|
case ITEMS_BEFORE_EDIT:
|
|
InsertFromClipboard();
|
|
break;
|
|
case ITEMS_BEFORE_EDIT+1:
|
|
CopyToClipboard();
|
|
break;
|
|
case ITEMS_BEFORE_EDIT+2:
|
|
UpdateRecord();
|
|
break;
|
|
case ITEMS_BEFORE_EDIT+3:
|
|
AddRecord();
|
|
break;
|
|
case ITEMS_BEFORE_EDIT+4:
|
|
DeleteRecord();
|
|
break;
|
|
case ITEMS_BEFORE_FIND:
|
|
FindPrevious();
|
|
break;
|
|
case ITEMS_BEFORE_FIND+1:
|
|
FindRecord();
|
|
break;
|
|
case ITEMS_BEFORE_FIND+2:
|
|
FindNext();
|
|
break;
|
|
case ITEMS_BEFORE_SPECIAL:
|
|
JumpTo();
|
|
break;
|
|
case ITEMS_BEFORE_SPECIAL+1:
|
|
SortDbf();
|
|
break;
|
|
case ITEMS_BEFORE_SPECIAL+2:
|
|
DialNumber();
|
|
break;
|
|
case ITEMS_BEFORE_SPECIAL+3:
|
|
hPrintSetupDialog();
|
|
break;
|
|
case ITEMS_BEFORE_SPECIAL+4:
|
|
DoPrint();
|
|
}
|
|
}
|
|
|
|
LOCAL_C INT ObeySystemCommand(INT cmd,TEXT *pb,VOID **pdH)
|
|
{
|
|
return((cmd=='O'? TryOpenDbf: TryNewDbf)(pb,pdH));
|
|
}
|
|
|
|
LOCAL_C VOID ProcessSystemCommand(VOID)
|
|
{
|
|
TEXT buf[P_FNAMESIZE+2];
|
|
VOID *newdH;
|
|
|
|
wGetCommand((UBYTE *)&buf[0]);
|
|
if (buf[0]=='X')
|
|
p_exit(0);
|
|
if (!ObeySystemCommand(buf[0],&buf[1],&newdH))
|
|
ChangeOverTo(newdH,&buf[1]);
|
|
}
|
|
|
|
LOCAL_C VOID TryExecuteCommand(INT keycode)
|
|
{
|
|
keycode=uLocateCommand(keycode);
|
|
if (keycode>=0)
|
|
ManageCommand(keycode);
|
|
}
|
|
|
|
LOCAL_C VOID MainLoop(VOID)
|
|
{
|
|
INT ret;
|
|
WMSG_KEY key;
|
|
|
|
FOREVER
|
|
{
|
|
uGetKey(&key);
|
|
if (key.keycode&W_EVENT_KEY)
|
|
{
|
|
if (key.keycode==CONS_EVENT_COMMAND)
|
|
ProcessSystemCommand();
|
|
}
|
|
else if (key.keycode&W_SPECIAL_KEY)
|
|
TryExecuteCommand(key.keycode&(~W_SPECIAL_KEY));
|
|
else
|
|
{
|
|
switch (key.keycode)
|
|
{
|
|
case W_KEY_MENU:
|
|
if (!(key.modifiers&W_CTRL_MODIFIER))
|
|
{
|
|
ret=uPresentMenus();
|
|
if (ret>0)
|
|
TryExecuteCommand(ret);
|
|
}
|
|
break;
|
|
case W_KEY_LEFT:
|
|
if (Transition(DbfBackRead)>=0)
|
|
{
|
|
Display();
|
|
break;
|
|
}
|
|
case W_KEY_HOME:
|
|
Transition(DbfFirstRead);
|
|
Display();
|
|
break;
|
|
case W_KEY_RIGHT:
|
|
if (Transition(DbfNextRead)>=0)
|
|
{
|
|
Display();
|
|
break;
|
|
}
|
|
case W_KEY_END:
|
|
Transition(DbfLastRead);
|
|
Display();
|
|
break;
|
|
case W_KEY_DELETE_LEFT:
|
|
DeleteRecord();
|
|
break;
|
|
case W_KEY_TAB:
|
|
key.modifiers^=W_SHIFT_MODIFIER;
|
|
case W_KEY_RETURN:
|
|
if (key.modifiers&W_SHIFT_MODIFIER)
|
|
FindPrevious();
|
|
else
|
|
FindNext();
|
|
break;
|
|
case W_KEY_HELP:
|
|
if (key.modifiers&W_PSION_MODIFIER)
|
|
DialNumber();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LOCAL_C VOID ReduceScreenSize(VOID)
|
|
{
|
|
W_WINDATA wd;
|
|
|
|
wd.extent.tl.x=wd.extent.tl.y=0;
|
|
wd.extent.width=189;
|
|
wd.extent.height=80;
|
|
wSetWindow(MainWid,W_WIN_EXTENT,&wd);
|
|
if (uErrorValue(wCheckPoint()))
|
|
p_exit(0);
|
|
}
|
|
|
|
LOCAL_C VOID CreateGC(VOID)
|
|
{
|
|
G_GC gc;
|
|
INT hgc;
|
|
|
|
gc.style=G_STY_DOUBLE;
|
|
hgc=gCreateGC(MainWid,G_GC_MASK_STYLE,&gc);
|
|
if (hgc<0)
|
|
p_exit(hgc);
|
|
}
|
|
|
|
LOCAL_C VOID SpecificInit(VOID)
|
|
{
|
|
INT command;
|
|
|
|
MainWid=uFindMainWid();
|
|
CreateGC();
|
|
command=hCrackCommandLine();
|
|
if (ObeySystemCommand(command,DatUsedPathNamePtr,&dH))
|
|
p_exit(0);
|
|
ReduceScreenSize();
|
|
gBorder(W_BORD_CORNER_4);
|
|
wsEnable();
|
|
DisplayPrompts();
|
|
DisplayStart();
|
|
}
|
|
|
|
GLDEF_C VOID main(VOID)
|
|
{
|
|
uCommonInit();
|
|
SpecificInit();
|
|
MainLoop();
|
|
}
|