home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
APPS
/
hl10osrc.lzh
/
Lib
/
EditForm.cc
< prev
next >
Wrap
Text File
|
1994-04-23
|
8KB
|
266 lines
/* -*- Mode: C -*- */
/* EditForm.cc - EditForm class - editing form.
* Created by Robert Heller on Thu Dec 12 19:29:12 1991
*
* ------------------------------------------------------------------
* Home Libarian by Deepwoods Software
* Common Class library implementation code
* ------------------------------------------------------------------
* Modification History:
* ------------------------------------------------------------------
* Contents:
* ------------------------------------------------------------------
*
*
* Copyright (c) 1991,1992 by Robert heller (D/B/A Deepwoods Software)
* All Rights Reserved
*
*/
#include <EditForm.h>
#include <fstream.h>
#include <osfcn.h>
#include <unistd.h>
#ifdef OSK
#define O_RDONLY S_IREAD
#endif
char EditForm::EditorCommand[48];
Boolean EditForm::EditorCmdInit;
void EditForm::HiliteField(int fieldno,Boolean hilite)
{
int row = fields[fieldno-1].row;
int col = fields[fieldno-1].col;
int width = fields[fieldno-1].width;
int height = fields[fieldno-1].height;
char* s;
char temp[80];
switch (fields[fieldno-1].type) {
case Literal:
case String:
case EditorString: s = (char*) fields[fieldno-1].fieldp; break;
case Int: sprintf(temp,"%d",*((int*)fields[fieldno-1].fieldp));
s = temp;break;
case Float: sprintf(temp,"%f",*((float*)fields[fieldno-1].fieldp));
s = temp;break;
case Special: s = (*fields[fieldno-1].ftos)(fields[fieldno-1].fieldp);break;
}
Terminal::term->PenPos(row,col);
if (hilite) Terminal::term->RevsPen();
else Terminal::term->PlainPen();
Terminal::term->PutStrInBox(row,col,width,height,s);
if (!hilite) Terminal::term->RevsPen();
else Terminal::term->PlainPen();
Terminal::term->PenPos(row,col);
}
EditForm::EditForm(char* title,int fieldcount,Field* infields,int bindcount,
KeyBinding* inbinds)
{
if (!EditorCmdInit) {
char* p = getenv("EDITOR");
if (p == 0) strcpy(EditorCommand,DEFAULTEDITOR);
else strcpy(EditorCommand,p);
EditorCmdInit = true;
}
strcpy(Title,title);
fields = new Field[fieldcount];
nFields = fieldcount;
for (int i = 0;i < fieldcount;i++) {
fields[i] = infields[i];
if (fields[i].height <= 0) fields[i].height = 1;
}
nBinds = bindcount;
if (bindcount > 0) {
bindings = new KeyBinding[bindcount];
for (i = 0;i < bindcount;i++) bindings[i] = inbinds[i];
}
currentField = 0;
for (i = 0;i < nFields;i++) {
if (fields[i].type != Literal) {
currentField = i+1;
break;
}
}
}
EditForm::~EditForm()
{
delete fields;
if (nBinds > 0) delete bindings;
}
void EditForm::RePaint()
{
int c = (Terminal::term->colms - strlen(Title)) >> 1;
Terminal::term->Clear();
Terminal::term->RevsPen();
Terminal::term->PutStrAt(1,c,Title);
Terminal::term->PlainPen();
for (int i = 0;i < nFields;i++) {
char* s;
char temp[80];
switch (fields[i].type) {
case Literal:
case EditorString:
case String: s = (char*) fields[i].fieldp;
break;
case Int: sprintf(temp,"%d",*((int*)fields[i].fieldp));
s = temp;break;
case Float: sprintf(temp,"%f",*((float*)fields[i].fieldp));
s = temp;break;
case Special: s = (*fields[i].ftos)(fields[i].fieldp);break;
}
if ((i+1) == currentField) Terminal::term->RevsPen();
Terminal::term->PutStrInBox(fields[i].row,fields[i].col,
fields[i].width,fields[i].height,s);
if ((i+1) == currentField) Terminal::term->PlainPen();
}
if (IsModified) Terminal::term->PutCharAt(0,0,'*');
Terminal::term->PenPos(fields[currentField-1].row,
fields[currentField-1].col);
}
Boolean EditForm::RunForm()
{
RePaint();
for (;;) {
int nFld,next,key,i;
static char buffer[80];
Field* fld = &fields[currentField-1];
switch (key = Terminal::term->GetKey()) {
case upCmd:
case leftCmd:
if (currentField > 1) {
for (nFld = currentField-1;
nFld > 0 && fields[nFld-1].type == Literal;
nFld--) ;
if (nFld > 0 && fields[nFld-1].type != Literal) next = nFld;
else next = 0;
} else next = 0;
break;
case 'i':
case 'I': switch (fld->type) {
case String:
Terminal::term->GetLine((char*)fld->fieldp,
fld->width);
break;
case Int:
Terminal::term->GetLine(buffer,fld->width);
*((int*)(fld->fieldp)) = atoi(buffer);
break;
case Float:
Terminal::term->GetLine(buffer,fld->width);
*((float*)(fld->fieldp)) = atof(buffer);
break;
case Special:
Terminal::term->GetLine(buffer,fld->width);
(*fld->stof)(buffer,fld->fieldp);
break;
case EditorString:
{
static char tempname[] = "EDXXXXXX";
static char tname[32];
strcpy(tname,mktemp(tempname));
{ofstream file;
file.open(tname);
file << ((char*)fld->fieldp);
file.close();
}
static char* editargs[] = {
EditorCommand,
tname,
0
};
int status = Terminal::term->forkprog(editargs);
if (status == 1) {
#ifdef USETREAM
ifstream file;
file.open(tname);
file.seekg(0,ios::end);
streampos size = file.tellg();
cerr << "*** file size=" << size << "\n";
file.seekg(0,ios::beg);
if ((size+1) > fld->buffersize)
size = fld->buffersize-1;
file.read(fld->fieldp,size);
//file >> ((char [size])(fld->fieldp));
file.close();
#else
int fd;
fd = open(tname,O_RDONLY);
int size = lseek(fd,0L,SEEK_END);
lseek(fd,0L,SEEK_SET);
if ((size+1) > fld->buffersize)
size = fld->buffersize-1;
read(fd,fld->fieldp,size);
close(fd);
#endif
unlink(tname);
*(((char*)(fld->fieldp))+size) = '\0';
RePaint();
} else if (status == 0) {
Terminal::term->PutStrAt(0,0,"Hit any key to continue");
Terminal::term->GetKey();
RePaint();
unlink(tname);
continue;
} else {
unlink(tname);
continue;
}
}
break;
}
IsModified = true;
Terminal::term->PutCharAt(0,0,'*');
case downCmd:
case rightCmd:
case '\t':
if (currentField < nFields) {
for (nFld = currentField+1;
nFld < nFields && fields[nFld-1].type == Literal;
nFld++) ;
if (fields[nFld-1].type != Literal) next = nFld;
else next = 0;
} else next = 0;
break;
case escCmd: return(IsModified);
case '\014': RePaint(); break;
case '?':
Terminal::term->Clear();
Terminal::term->PutStrAt(2,0,"Global Key bingings:");
Terminal::term->PutStrAt(4,0,"UP,LEFT: Previous field");
Terminal::term->PutStrAt(5,0,"i,I: Insert/update field");
Terminal::term->PutStrAt(6,0,"DOWN,RIGHT,TAB: Next field");
Terminal::term->PutStrAt(7,0,"HOME: Exit");
Terminal::term->PutStrAt(8,0,"^L: Repaint");
Terminal::term->PutStrAt(9,0,"?: This screen");
Terminal::term->PutStrAt(11,0,"Local Key Bindings");
for (i = 0;i < nBinds;i++) {
Terminal::term->PutStrAt(13+i,0,bindings[i].docstring);
}
Terminal::term->PutStrAt(0,0,"Hit any key to resume editing:");
Terminal::term->GetKey();
RePaint();
continue;
default:
for (i = 0;i < nBinds;i++) {
if (key == bindings[i].keycode) break;
}
if (i == nBinds) Terminal::term->Bell();
else (*bindings[i].fun)(*this);
continue;
}
if (next == 0) Terminal::term->Bell();
else {
HiliteField(currentField,false);
fld = &fields[(currentField = next) - 1];
HiliteField(currentField,true);
}
}
}