home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / hl10osrc.zoo / Lib / EditForm.cc < prev    next >
Text File  |  2009-11-06  |  8KB  |  266 lines

  1. /* -*- Mode: C -*- */ 
  2. /* EditForm.cc - EditForm class - editing form.
  3.  * Created by Robert Heller on Thu Dec 12 19:29:12 1991
  4.  *
  5.  * ------------------------------------------------------------------
  6.  * Home Libarian by Deepwoods Software
  7.  * Common Class library implementation code
  8.  * ------------------------------------------------------------------
  9.  * Modification History:
  10.  * ------------------------------------------------------------------
  11.  * Contents:
  12.  * ------------------------------------------------------------------
  13.  * 
  14.  * 
  15.  * Copyright (c) 1991,1992 by Robert heller (D/B/A Deepwoods Software)
  16.  *        All Rights Reserved
  17.  * 
  18.  */
  19.  
  20. #include <EditForm.h>
  21. #include <fstream.h>
  22. #include <osfcn.h>
  23. #include <unistd.h>
  24. #ifdef OSK
  25. #define O_RDONLY S_IREAD
  26. #endif
  27.  
  28. char EditForm::EditorCommand[48];
  29. Boolean EditForm::EditorCmdInit;
  30.  
  31. void EditForm::HiliteField(int fieldno,Boolean hilite)
  32. {
  33.     int row = fields[fieldno-1].row;
  34.     int col = fields[fieldno-1].col;
  35.     int width = fields[fieldno-1].width;
  36.     int height = fields[fieldno-1].height;
  37.     char* s;
  38.     char temp[80];
  39.     switch (fields[fieldno-1].type) {
  40.         case Literal:
  41.         case String:  
  42.         case EditorString: s = (char*) fields[fieldno-1].fieldp; break;
  43.         case Int: sprintf(temp,"%d",*((int*)fields[fieldno-1].fieldp));
  44.               s = temp;break;
  45.         case Float: sprintf(temp,"%f",*((float*)fields[fieldno-1].fieldp));
  46.               s = temp;break;
  47.         case Special: s = (*fields[fieldno-1].ftos)(fields[fieldno-1].fieldp);break;
  48.     }        
  49.     Terminal::term->PenPos(row,col);
  50.     if (hilite) Terminal::term->RevsPen();
  51.     else Terminal::term->PlainPen();
  52.     Terminal::term->PutStrInBox(row,col,width,height,s);
  53.     if (!hilite) Terminal::term->RevsPen();
  54.     else Terminal::term->PlainPen();
  55.     Terminal::term->PenPos(row,col);
  56. }
  57.  
  58. EditForm::EditForm(char* title,int fieldcount,Field* infields,int bindcount,
  59.            KeyBinding* inbinds)
  60. {
  61.     if (!EditorCmdInit) {
  62.         char* p = getenv("EDITOR");
  63.         if (p == 0) strcpy(EditorCommand,DEFAULTEDITOR);
  64.         else strcpy(EditorCommand,p);
  65.         EditorCmdInit = true;
  66.     }
  67.     strcpy(Title,title);
  68.     fields = new Field[fieldcount];
  69.     nFields = fieldcount;
  70.     for (int i = 0;i < fieldcount;i++) {
  71.         fields[i] = infields[i];
  72.         if (fields[i].height <= 0) fields[i].height = 1;
  73.     }
  74.     nBinds = bindcount;
  75.     if (bindcount > 0) {
  76.         bindings = new KeyBinding[bindcount];
  77.         for (i = 0;i < bindcount;i++) bindings[i] = inbinds[i];
  78.     }
  79.     currentField = 0;
  80.     for (i = 0;i < nFields;i++) {
  81.         if (fields[i].type != Literal) {
  82.             currentField = i+1;
  83.             break;
  84.         }
  85.     }
  86. }
  87.  
  88. EditForm::~EditForm()
  89. {
  90.     delete fields;
  91.     if (nBinds > 0) delete bindings;
  92. }
  93.  
  94. void EditForm::RePaint()
  95. {
  96.     int c = (Terminal::term->colms - strlen(Title)) >> 1;
  97.     Terminal::term->Clear();
  98.     Terminal::term->RevsPen();
  99.     Terminal::term->PutStrAt(1,c,Title);
  100.     Terminal::term->PlainPen();
  101.     for (int i = 0;i < nFields;i++) {
  102.         char* s;
  103.         char temp[80];
  104.         switch (fields[i].type) {
  105.             case Literal:
  106.             case EditorString: 
  107.             case String:  s = (char*) fields[i].fieldp;
  108.                      break;
  109.             case Int: sprintf(temp,"%d",*((int*)fields[i].fieldp));
  110.                   s = temp;break;
  111.             case Float: sprintf(temp,"%f",*((float*)fields[i].fieldp));
  112.                   s = temp;break;
  113.             case Special: s = (*fields[i].ftos)(fields[i].fieldp);break;
  114.         }        
  115.         if ((i+1) == currentField) Terminal::term->RevsPen();
  116.         Terminal::term->PutStrInBox(fields[i].row,fields[i].col,
  117.                         fields[i].width,fields[i].height,s);
  118.         if ((i+1) == currentField) Terminal::term->PlainPen();
  119.     }
  120.     if (IsModified) Terminal::term->PutCharAt(0,0,'*');
  121.     Terminal::term->PenPos(fields[currentField-1].row,
  122.                    fields[currentField-1].col);
  123. }
  124.  
  125. Boolean EditForm::RunForm()
  126. {
  127.     RePaint();
  128.     for (;;) {
  129.         int nFld,next,key,i;
  130.         static char buffer[80];
  131.         Field* fld = &fields[currentField-1];
  132.         switch (key = Terminal::term->GetKey()) {
  133.             case upCmd:
  134.             case leftCmd:
  135.                 if (currentField > 1) {
  136.                     for (nFld = currentField-1;
  137.                          nFld > 0 && fields[nFld-1].type == Literal;
  138.                          nFld--) ;
  139.                     if (nFld > 0 && fields[nFld-1].type != Literal) next = nFld;
  140.                     else next = 0;
  141.                 } else next = 0;
  142.                 break;
  143.             case 'i':
  144.             case 'I': switch (fld->type) {
  145.                           case String:
  146.                                Terminal::term->GetLine((char*)fld->fieldp,
  147.                                                 fld->width);
  148.                          break;
  149.                     case Int:
  150.                          Terminal::term->GetLine(buffer,fld->width);
  151.                          *((int*)(fld->fieldp)) = atoi(buffer);
  152.                          break;
  153.                     case Float:
  154.                          Terminal::term->GetLine(buffer,fld->width);
  155.                          *((float*)(fld->fieldp)) = atof(buffer);
  156.                          break;
  157.                      case Special:
  158.                          Terminal::term->GetLine(buffer,fld->width);
  159.                          (*fld->stof)(buffer,fld->fieldp);
  160.                          break;
  161.                      case EditorString:
  162.                          {
  163.                              static char tempname[] = "EDXXXXXX";
  164.                              static char tname[32];
  165.                              strcpy(tname,mktemp(tempname));
  166.                         {ofstream file;
  167.                         file.open(tname);
  168.                         file << ((char*)fld->fieldp);
  169.                         file.close();
  170.                         } 
  171.                              static char* editargs[] = {
  172.                                  EditorCommand,
  173.                                  tname,
  174.                                  0
  175.                              };
  176.                              int status = Terminal::term->forkprog(editargs);
  177.                              if (status == 1) {
  178. #ifdef USETREAM
  179.                             ifstream file;
  180.                             file.open(tname);
  181.                             file.seekg(0,ios::end);
  182.                             streampos size = file.tellg();
  183.                             cerr << "*** file size=" << size << "\n";
  184.                             file.seekg(0,ios::beg);
  185.                             if ((size+1) > fld->buffersize) 
  186.                                      size = fld->buffersize-1;
  187.                                  file.read(fld->fieldp,size);
  188.                                  //file >> ((char [size])(fld->fieldp));
  189.                                  file.close();
  190. #else
  191.                             int fd;
  192.                             fd = open(tname,O_RDONLY);
  193.                             int size = lseek(fd,0L,SEEK_END);
  194.                             lseek(fd,0L,SEEK_SET);
  195.                             if ((size+1) > fld->buffersize) 
  196.                                      size = fld->buffersize-1;
  197.                                  read(fd,fld->fieldp,size);
  198.                             close(fd);
  199. #endif
  200.                                  unlink(tname);
  201.                                  *(((char*)(fld->fieldp))+size) = '\0';
  202.                                  RePaint();
  203.                              } else if (status == 0) {
  204.                                  Terminal::term->PutStrAt(0,0,"Hit any key to continue");
  205.                                  Terminal::term->GetKey();
  206.                                  RePaint();
  207.                                  unlink(tname);
  208.                             continue;
  209.                              } else {
  210.                                  unlink(tname);
  211.                             continue;
  212.                         }
  213.                          }
  214.                          break;
  215.                   }
  216.                   IsModified = true;
  217.                   Terminal::term->PutCharAt(0,0,'*');
  218.             case downCmd:
  219.             case rightCmd:
  220.             case '\t':
  221.                 if (currentField < nFields) {
  222.                     for (nFld = currentField+1;
  223.                          nFld < nFields && fields[nFld-1].type == Literal;
  224.                          nFld++) ;
  225.                     if (fields[nFld-1].type != Literal) next = nFld;
  226.                     else next = 0;
  227.                 } else next = 0;
  228.                 break;
  229.             case escCmd: return(IsModified);
  230.             case '\014': RePaint(); break;
  231.             case '?':
  232.                 Terminal::term->Clear();
  233.                 Terminal::term->PutStrAt(2,0,"Global Key bingings:");
  234.                 Terminal::term->PutStrAt(4,0,"UP,LEFT: Previous field");
  235.                 Terminal::term->PutStrAt(5,0,"i,I: Insert/update field");
  236.                 Terminal::term->PutStrAt(6,0,"DOWN,RIGHT,TAB: Next field");
  237.                 Terminal::term->PutStrAt(7,0,"HOME: Exit");
  238.                 Terminal::term->PutStrAt(8,0,"^L: Repaint");
  239.                 Terminal::term->PutStrAt(9,0,"?: This screen");
  240.                 Terminal::term->PutStrAt(11,0,"Local Key Bindings");
  241.                 for (i = 0;i < nBinds;i++) {
  242.                     Terminal::term->PutStrAt(13+i,0,bindings[i].docstring);
  243.                 }
  244.                 Terminal::term->PutStrAt(0,0,"Hit any key to resume editing:");
  245.                 Terminal::term->GetKey();
  246.                 RePaint();
  247.                 continue;
  248.             default:
  249.                 for (i = 0;i < nBinds;i++) {
  250.                     if (key == bindings[i].keycode) break;
  251.                 }
  252.                 if (i == nBinds) Terminal::term->Bell();
  253.                 else (*bindings[i].fun)(*this);
  254.                 continue;
  255.         }
  256.         if (next == 0) Terminal::term->Bell();
  257.         else {
  258.             HiliteField(currentField,false);
  259.             fld = &fields[(currentField = next) - 1];
  260.             HiliteField(currentField,true);
  261.         }
  262.     }
  263. }
  264.  
  265.  
  266.