/* @(#)tbledit.c 17.1.1.1 (ES0-DMD) 01/25/02 17:40:11 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++ .LANGUAGE C .TYPE Module .NAME tbledit.c .VERSION 0.0 17-Mar-1989: First design .VERSION 1.1 24-Nov-1989: Corrected (FO) .VERSION 1.2 12-Feb-1990: Row boundary checking. JDP. Check if several commands are given, to speed up .VERSION 1.3 28-Oct-1990: Just patch for new version. .AUTHOR Daniel Ponz, Francois Ochsenbein .CATEGORY Table Editor .COMMENTS Just here Field i/o *** The provisional implementation assumes the functions ClearError() removes error text, if any ShowError(text) shows error text *** Actions NEXTCOL returned for `asking to move to next (right) col' PREVCOL returned for `asking to move to previous (left) col' HOMECOL returned for `asking to move to first (left) col' BAD_KEY returned for unknown key .ENVIRONMENT MIDAS, TermWindows ------------------------------------------------------------------------*/ #include /* Window system */ #include /* Just OK / NOK definitions */ #include /* General purpose macros, e.g. MAX */ #include /* General string handling */ #include #include #include #include #include #define MAXEDT_ELEMENT 255 /* Maximal size for getting a single * table element */ static char buffer[MAXEDT_ELEMENT+1]; static char buf_er[MAXEDT_ELEMENT+1]; static double variable[(MAXEDT_ELEMENT+7)/8]; /*========================================================================*/ int compute_col() /*++++++++ .PURPOSE Compute the current column from cursor position in range [0, edt_nc] .REMARKS Should be a general function ? should thecol be external (known to all edt functions) ? .RETURNS The number ---------*/ { int j, col1; GetCursor(data_subwindow, cursor_pos); col1 = cursor_pos[1]; for (j=0; col1 > FMT[j].LAST; j++) ; return(j); } static int Edit(str) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Convert from Binary (in variable) to str .REMARKS Used in cunjunction with ModsWithCheck .RETURNS OK=1 (str is correct) / NOK=0 (Bad char) ------------------------------------------------------------------------*/ char *str; /* OUT: Edited number */ { return (TCEEDC(edt_tid, (char *)variable, FMT[thecol].colno, str)); } static int Convert(str) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Convert from Char to Binary .REMARKS Used in conjunction with ModsWithCheck .RETURNS 0 (NULL) / -1 (error) / positive number if OK ------------------------------------------------------------------------*/ char *str; /* IN: String to Convert */ { int status, i; status = TCETRC(edt_tid, (char *)variable, FMT[thecol].colno, str); if (status) status = -1; /* Error */ else status = *str; return(status); } /*========================================================================*/ static int check(w, str, size) /*++++++++++++++ .PURPOSE Check Function for Input of an Element .REMARKS Used in cunjunction with ModsWithCheck .RETURNS OK=1 (input is correct) / NOK=0 (Bad input) .METHOD Convert str to Binary (if not a char string!), tne convert back. --------------*/ WINDOW *w; /* IN: The Window */ char *str; /* MOD: What the user typed */ int size; /* IN: Size of str buffer */ { char temp[MAXEDT_ELEMENT+80]; int status; int cur_col, cur_row; status = -1; if (strcomp(buf_er,str) == 0) status = -2; if (status == -1) status = Convert(str); if (status == -1) { status = NOK; ShowError(">>> Format Error"), Bell(); } else { /* Correct Entry. Modify underlying table */ SetAttr(w, _NORMAL_); /* Will be redisplayed correctly */ if (status >= 0) { /* A modification of the value ... */ GetCursor(data_subwindow, cursor_pos); cur_col = edt_column[compute_col()]; cur_row = edt_row[cursor_pos[0]]; if (cur_row <= 0 || cur_row > edt_narow) { status = NOK; /* check row boundaries */ ShowError(" Limit of the table "); Bell(); return(status); } if (status == 0) { /* NULL value */ sprintf(temp,"Delete row %d, column %d", cur_row,cur_col); TCEDEL(edt_tid, cur_row, cur_col); } else { sprintf(temp,"Rewrite row %d, column %d, element %s ", cur_row, cur_col, str); TCEWRC(edt_tid, cur_row, cur_col, str); } ShowError(temp); } if (status > 0) Edit(str); /* Converts back using Format */ SetAttr(w, _NORMAL_); /* Will be redisplayed correctly */ status = OK; } return(status); } /*========================================================================*/ int edt_edfield() /*++++++++ .PURPOSE Edit any table element. What the user entered is checked. **** Note: EnableArrows(data_subwindow) and EnableKeypad(data_subwindow) is in effect (normally called after OpenWindow) .RETURNS The action hit by the user. Can be just Return. .REMARKS Process here only one element. ----------*/ { int lencol; /* Width of the current column */ int key_group; /* The group of keys (_KEYPAD_, etc) */ char key_hit; /* Explanation within key_group */ int key1, key2; /* input key(s) */ int i; thecol = compute_col(); /* Just know the index in FMT tables */ lencol = FMT[thecol].LAST - FMT[thecol].FIRST; lencol = MIN(lencol, sizeof(buffer)-1); /* The acquisistion of the contents of the current column * is made via TranslateWindow. Is there a better solution ? */ /* Suppress cursor mouvements echo */ DeactiveWindow(data_subwindow); CursorTo(data_subwindow, cursor_pos[0], FMT[thecol].FIRST); TranslateWindow(data_subwindow, buffer, lencol); buffer[lencol] = '\0'; for (i = lencol-1; i >= 0 && buffer[i] == ' '; buffer[i--] = '\0') ; oscopy(buf_er,buffer,lencol+1); Input_Loop: SetAttr(data_subwindow, _REVERSE_); /* Before asking for the input, check if some command * was already typed in. Useless to repaint the screen... */ if (CheckInput()){ key_group = GetChar(&key_hit); if ( (key_group == _STANDARD_) && isprint(key_hit)) { UngetChar(&key_hit); goto Get_User_Input; } if (key_hit == '\r') key_hit = EOS; buffer[0] = key_hit; goto Execute_User_Input; } /* Ready now for Input. Buffer contains a copy of the * element (in Character). It will be redisplayed in Reverse */ Get_User_Input: ActiveWindow(data_subwindow); key_group = ModsWithCheck(data_subwindow, buffer, lencol+1, check); Execute_User_Input: SetAttr(data_subwindow, _NORMAL_); /* The result of Mods may be: * _INTERRUPT_ : take the original (no modif) * _STANDARD_ : terminated by the Carriage Return * 0 : We must look what was exactly the key via GetKey * Other : A special key was hit as the FIRST input */ switch(key_group) { case _INTERRUPT_: ShowError("***INTERRUPT*** Hit Return"); oscopy(buffer,buf_er,lencol+1); goto Input_Loop; case _STANDARD_: if (buffer[0] && iscntrl(buffer[0])) {key_hit = buffer[0], buffer[0] = EOS; break;} return(NEXTFIELD); case 0: key_group = GetKey(data_subwindow, &key_hit); break; case _EOF_: break; default: key_hit = buffer[0], buffer[0] = EOS; break; } if (key_group == _EOF_) return(COMMAND); if (key_group == _STANDARD_) key_group = 0; key1 = key_group<<8 | key_hit; key2 = 0; switch(tk_check(key1)) { case 0: return (BAD_KEY); /* Doesn't map to an action */ case 2: key_group = GetKey(data_subwindow, &key_hit); key2 = key_group<<8 | key_hit; case 1: return (tk_exec(key1, key2)); } return(BAD_KEY); } /*========================================================================*/ int tbl_edit() /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Edit table .KEYWORDS Tables, Editor .ALGORITHM .RETURNS Status 0 OK - save table; -1 NOK - no save the table ------------------------------------------------------------------*/ { int iend, old_direction, old_state; int old_err; /* iteration on input */; TCOGET("display_errors", &old_err); /* Don't Display */ TCOSET("display_errors", 0); /* Don't Display */ while ((edt_action = edt_edfield()) != TERMINATE) { /* decide upon main actions */ switch (edt_action) { case NEXTFIELD: GetCursor(data_subwindow, cursor_pos); thecol = compute_col(); if ((thecol+1 >= edt_nc) && (edt_column[edt_nc-1] >= edt_ncol)) { /* Must go to First Column, next line */ if (cursor_pos[0]+1 >= data_lines) /* Must scroll */ { old_direction = edt_advance; edt_advance = TRUE; iend = edt_row[edt_nr-1]; if (++iend > edt_narow) /* End of Table */ edt_nextcol(); else { old_state = DeactiveWindow(editor_window); CursorHome(data_subwindow), cursor_pos[0] = cursor_pos[1] = 0; if (edt_column[0] > 1) edt_leftpage(); edt_newpage(); CursorDown(data_subwindow, iend - edt_row[0]); if (old_state) ActiveWindow(editor_window); } edt_advance = old_direction; } else /* I don't have to scroll. However, verify */ { if (edt_column[0] > 1) edt_leftpage(); edt_nextline(); } } else edt_nextcol(); break; case INTERRUPT : return (-1); case BAD_KEY: edt_badkey(); break; case NEXTCOL: edt_nextcol(); break; case COMMAND: edt_command(); if (edt_action == TERMINATE) return (0); break; } } TCOSET("display_errors", old_err); /* Reset at its previous value */ return (0); }