frm_def.c revision 174993
150276Speter/**************************************************************************** 2174993Srafan * Copyright (c) 1998-2006,2007 Free Software Foundation, Inc. * 350276Speter * * 450276Speter * Permission is hereby granted, free of charge, to any person obtaining a * 550276Speter * copy of this software and associated documentation files (the * 650276Speter * "Software"), to deal in the Software without restriction, including * 750276Speter * without limitation the rights to use, copy, modify, merge, publish, * 850276Speter * distribute, distribute with modifications, sublicense, and/or sell * 950276Speter * copies of the Software, and to permit persons to whom the Software is * 1050276Speter * furnished to do so, subject to the following conditions: * 1150276Speter * * 1250276Speter * The above copyright notice and this permission notice shall be included * 1350276Speter * in all copies or substantial portions of the Software. * 1450276Speter * * 1550276Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 1650276Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 1750276Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 1850276Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 1950276Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 2050276Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 2150276Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 2250276Speter * * 2350276Speter * Except as contained in this notice, the name(s) of the above copyright * 2450276Speter * holders shall not be used in advertising or otherwise to promote the * 2550276Speter * sale, use or other dealings in this Software without prior written * 2650276Speter * authorization. * 2750276Speter ****************************************************************************/ 2850276Speter 2950276Speter/**************************************************************************** 30166124Srafan * Author: Juergen Pfeifer, 1995,1997 * 3150276Speter ****************************************************************************/ 3250276Speter 3350276Speter#include "form.priv.h" 3450276Speter 35174993SrafanMODULE_ID("$Id: frm_def.c,v 1.22 2007/10/13 19:31:17 tom Exp $") 3650276Speter 3750276Speter/* this can't be readonly */ 38166124Srafanstatic FORM default_form = 39166124Srafan{ 40166124Srafan 0, /* status */ 41166124Srafan 0, /* rows */ 42166124Srafan 0, /* cols */ 43166124Srafan 0, /* currow */ 44166124Srafan 0, /* curcol */ 45166124Srafan 0, /* toprow */ 46166124Srafan 0, /* begincol */ 47166124Srafan -1, /* maxfield */ 48166124Srafan -1, /* maxpage */ 49166124Srafan -1, /* curpage */ 50166124Srafan ALL_FORM_OPTS, /* opts */ 51166124Srafan (WINDOW *)0, /* win */ 52166124Srafan (WINDOW *)0, /* sub */ 53166124Srafan (WINDOW *)0, /* w */ 54166124Srafan (FIELD **)0, /* field */ 55166124Srafan (FIELD *)0, /* current */ 56166124Srafan (_PAGE *) 0, /* page */ 57166124Srafan (char *)0, /* usrptr */ 58166124Srafan NULL, /* forminit */ 59166124Srafan NULL, /* formterm */ 60166124Srafan NULL, /* fieldinit */ 61166124Srafan NULL /* fieldterm */ 6250276Speter}; 6350276Speter 6476726SpeterNCURSES_EXPORT_VAR(FORM *) _nc_Default_Form = &default_form; 6550276Speter 6650276Speter/*--------------------------------------------------------------------------- 6750276Speter| Facility : libnform 6850276Speter| Function : static FIELD *Insert_Field_By_Position( 6950276Speter| FIELD *new_field, 7050276Speter| FIELD *head ) 7150276Speter| 7250276Speter| Description : Insert new_field into sorted fieldlist with head "head" 7350276Speter| and return new head of sorted fieldlist. Sorting 7450276Speter| criteria is (row,column). This is a circular list. 7550276Speter| 7650276Speter| Return Values : New head of sorted fieldlist 7750276Speter+--------------------------------------------------------------------------*/ 78166124Srafanstatic FIELD * 79166124SrafanInsert_Field_By_Position(FIELD *newfield, FIELD *head) 8050276Speter{ 8150276Speter FIELD *current, *newhead; 82166124Srafan 8350276Speter assert(newfield); 8450276Speter 8550276Speter if (!head) 86166124Srafan { /* empty list is trivial */ 8750276Speter newhead = newfield->snext = newfield->sprev = newfield; 8850276Speter } 8950276Speter else 9050276Speter { 9150276Speter newhead = current = head; 92166124Srafan while ((current->frow < newfield->frow) || 93166124Srafan ((current->frow == newfield->frow) && 94166124Srafan (current->fcol < newfield->fcol))) 9550276Speter { 9650276Speter current = current->snext; 97166124Srafan if (current == head) 98166124Srafan { /* We cycled through. Reset head to indicate that */ 9950276Speter head = (FIELD *)0; 10050276Speter break; 10150276Speter } 10250276Speter } 103166124Srafan /* we leave the loop with current pointing to the field after newfield */ 104166124Srafan newfield->snext = current; 105166124Srafan newfield->sprev = current->sprev; 10650276Speter newfield->snext->sprev = newfield; 10750276Speter newfield->sprev->snext = newfield; 108166124Srafan if (current == head) 10950276Speter newhead = newfield; 11050276Speter } 111166124Srafan return (newhead); 11250276Speter} 11350276Speter 11450276Speter/*--------------------------------------------------------------------------- 11550276Speter| Facility : libnform 11650276Speter| Function : static void Disconnect_Fields(FORM *form) 11750276Speter| 11850276Speter| Description : Break association between form and array of fields. 11950276Speter| 12050276Speter| Return Values : - 12150276Speter+--------------------------------------------------------------------------*/ 122166124Srafanstatic void 123166124SrafanDisconnect_Fields(FORM *form) 12450276Speter{ 12550276Speter if (form->field) 12650276Speter { 12750276Speter FIELD **fields; 12850276Speter 129166124Srafan for (fields = form->field; *fields; fields++) 13050276Speter { 131166124Srafan if (form == (*fields)->form) 13250276Speter (*fields)->form = (FORM *)0; 13350276Speter } 134166124Srafan 13550276Speter form->rows = form->cols = 0; 13650276Speter form->maxfield = form->maxpage = -1; 13750276Speter form->field = (FIELD **)0; 138166124Srafan if (form->page) 13950276Speter free(form->page); 140166124Srafan form->page = (_PAGE *) 0; 141166124Srafan } 14250276Speter} 14350276Speter 14450276Speter/*--------------------------------------------------------------------------- 14550276Speter| Facility : libnform 14650276Speter| Function : static int Connect_Fields(FORM *form, FIELD **fields) 14750276Speter| 14850276Speter| Description : Set association between form and array of fields. 14950276Speter| 15050276Speter| Return Values : E_OK - no error 15150276Speter| E_CONNECTED - a field is already connected 15250276Speter| E_BAD_ARGUMENT - Invalid form pointer or field array 15350276Speter| E_SYSTEM_ERROR - not enough memory 15450276Speter+--------------------------------------------------------------------------*/ 155166124Srafanstatic int 156166124SrafanConnect_Fields(FORM *form, FIELD **fields) 15750276Speter{ 15850276Speter int field_cnt, j; 15950276Speter int page_nr; 16050276Speter int maximum_row_in_field, maximum_col_in_field; 16150276Speter _PAGE *pg; 162166124Srafan 163166124Srafan T((T_CALLED("Connect_Fields(%p,%p)"), form, fields)); 164166124Srafan 16550276Speter assert(form); 16650276Speter 167166124Srafan form->field = fields; 16850276Speter form->maxfield = 0; 169166124Srafan form->maxpage = 0; 17050276Speter 17150276Speter if (!fields) 17250276Speter RETURN(E_OK); 173166124Srafan 17450276Speter page_nr = 0; 17550276Speter /* store formpointer in fields and count pages */ 176166124Srafan for (field_cnt = 0; fields[field_cnt]; field_cnt++) 17750276Speter { 178166124Srafan if (fields[field_cnt]->form) 17950276Speter RETURN(E_CONNECTED); 180166124Srafan if (field_cnt == 0 || 181166124Srafan (fields[field_cnt]->status & _NEWPAGE)) 18250276Speter page_nr++; 18350276Speter fields[field_cnt]->form = form; 184166124Srafan } 185166124Srafan if (field_cnt == 0 || (short)field_cnt < 0) 18650276Speter RETURN(E_BAD_ARGUMENT); 187166124Srafan 18850276Speter /* allocate page structures */ 189174993Srafan if ((pg = typeMalloc(_PAGE, page_nr)) != (_PAGE *) 0) 19050276Speter { 191174993Srafan T((T_CREATE("_PAGE %p"), pg)); 19250276Speter form->page = pg; 19350276Speter } 19450276Speter else 19550276Speter RETURN(E_SYSTEM_ERROR); 196166124Srafan 19750276Speter /* Cycle through fields and calculate page boundaries as well as 19850276Speter size of the form */ 199166124Srafan for (j = 0; j < field_cnt; j++) 20050276Speter { 201166124Srafan if (j == 0) 20250276Speter pg->pmin = j; 20350276Speter else 20450276Speter { 20550276Speter if (fields[j]->status & _NEWPAGE) 20650276Speter { 207166124Srafan pg->pmax = j - 1; 20850276Speter pg++; 20950276Speter pg->pmin = j; 21050276Speter } 21150276Speter } 212166124Srafan 21350276Speter maximum_row_in_field = fields[j]->frow + fields[j]->rows; 21450276Speter maximum_col_in_field = fields[j]->fcol + fields[j]->cols; 215166124Srafan 216166124Srafan if (form->rows < maximum_row_in_field) 21750276Speter form->rows = maximum_row_in_field; 218166124Srafan if (form->cols < maximum_col_in_field) 21950276Speter form->cols = maximum_col_in_field; 22050276Speter } 221166124Srafan 222166124Srafan pg->pmax = field_cnt - 1; 22350276Speter form->maxfield = field_cnt; 224166124Srafan form->maxpage = page_nr; 225166124Srafan 22650276Speter /* Sort fields on form pages */ 227166124Srafan for (page_nr = 0; page_nr < form->maxpage; page_nr++) 22850276Speter { 22950276Speter FIELD *fld = (FIELD *)0; 230166124Srafan 231166124Srafan for (j = form->page[page_nr].pmin; j <= form->page[page_nr].pmax; j++) 23250276Speter { 23350276Speter fields[j]->index = j; 234166124Srafan fields[j]->page = page_nr; 235166124Srafan fld = Insert_Field_By_Position(fields[j], fld); 23650276Speter } 23750276Speter form->page[page_nr].smin = fld->index; 23850276Speter form->page[page_nr].smax = fld->sprev->index; 23950276Speter } 24050276Speter RETURN(E_OK); 24150276Speter} 24250276Speter 24350276Speter/*--------------------------------------------------------------------------- 24450276Speter| Facility : libnform 24550276Speter| Function : static int Associate_Fields(FORM *form, FIELD **fields) 24650276Speter| 24750276Speter| Description : Set association between form and array of fields. 24850276Speter| If there are fields, position to first active field. 24950276Speter| 25050276Speter| Return Values : E_OK - success 251166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 252166124Srafan| E_CONNECTED - a field is already connected 253166124Srafan| E_SYSTEM_ERROR - not enough memory 25450276Speter+--------------------------------------------------------------------------*/ 255166124SrafanNCURSES_INLINE static int 256166124SrafanAssociate_Fields(FORM *form, FIELD **fields) 25750276Speter{ 258166124Srafan int res = Connect_Fields(form, fields); 259166124Srafan 26050276Speter if (res == E_OK) 26150276Speter { 262166124Srafan if (form->maxpage > 0) 26350276Speter { 26450276Speter form->curpage = 0; 265166124Srafan form_driver(form, FIRST_ACTIVE_MAGIC); 26650276Speter } 26750276Speter else 26850276Speter { 26950276Speter form->curpage = -1; 27050276Speter form->current = (FIELD *)0; 271166124Srafan } 27250276Speter } 273166124Srafan return (res); 27450276Speter} 275166124Srafan 27650276Speter/*--------------------------------------------------------------------------- 27750276Speter| Facility : libnform 27850276Speter| Function : FORM *new_form( FIELD **fields ) 27950276Speter| 28050276Speter| Description : Create new form with given array of fields. 28150276Speter| 282166124Srafan| Return Values : Pointer to form. NULL if error occurred. 283166124Srafan! Set errno: 284166124Srafan| E_OK - success 285166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 286166124Srafan| E_CONNECTED - a field is already connected 287166124Srafan| E_SYSTEM_ERROR - not enough memory 28850276Speter+--------------------------------------------------------------------------*/ 28976726SpeterNCURSES_EXPORT(FORM *) 290166124Srafannew_form(FIELD **fields) 291166124Srafan{ 29250276Speter int err = E_SYSTEM_ERROR; 29350276Speter 294174993Srafan FORM *form = typeMalloc(FORM, 1); 295166124Srafan 296166124Srafan T((T_CALLED("new_form(%p)"), fields)); 29750276Speter if (form) 29850276Speter { 299174993Srafan T((T_CREATE("form %p"), form)); 30050276Speter *form = *_nc_Default_Form; 301166124Srafan if ((err = Associate_Fields(form, fields)) != E_OK) 30250276Speter { 30350276Speter free_form(form); 30450276Speter form = (FORM *)0; 30550276Speter } 30650276Speter } 30750276Speter 30850276Speter if (!form) 30950276Speter SET_ERROR(err); 310166124Srafan 311166124Srafan returnForm(form); 31250276Speter} 31350276Speter 31450276Speter/*--------------------------------------------------------------------------- 31550276Speter| Facility : libnform 31650276Speter| Function : int free_form( FORM *form ) 31750276Speter| 31850276Speter| Description : Release internal memory associated with form. 31950276Speter| 32050276Speter| Return Values : E_OK - no error 32150276Speter| E_BAD_ARGUMENT - invalid form pointer 32250276Speter| E_POSTED - form is posted 32350276Speter+--------------------------------------------------------------------------*/ 32476726SpeterNCURSES_EXPORT(int) 325166124Srafanfree_form(FORM *form) 32650276Speter{ 327166124Srafan T((T_CALLED("free_form(%p)"), form)); 328166124Srafan 329166124Srafan if (!form) 33050276Speter RETURN(E_BAD_ARGUMENT); 33150276Speter 332166124Srafan if (form->status & _POSTED) 33350276Speter RETURN(E_POSTED); 334166124Srafan 335166124Srafan Disconnect_Fields(form); 336166124Srafan if (form->page) 33750276Speter free(form->page); 33850276Speter free(form); 339166124Srafan 34050276Speter RETURN(E_OK); 34150276Speter} 34250276Speter 34350276Speter/*--------------------------------------------------------------------------- 34450276Speter| Facility : libnform 34550276Speter| Function : int set_form_fields( FORM *form, FIELD **fields ) 34650276Speter| 34750276Speter| Description : Set a new association of an array of fields to a form 34850276Speter| 349166124Srafan| Return Values : E_OK - no error 350166124Srafan| E_BAD_ARGUMENT - Invalid form pointer or field array 351166124Srafan| E_CONNECTED - a field is already connected 352166124Srafan| E_POSTED - form is posted 353166124Srafan| E_SYSTEM_ERROR - not enough memory 35450276Speter+--------------------------------------------------------------------------*/ 35576726SpeterNCURSES_EXPORT(int) 356166124Srafanset_form_fields(FORM *form, FIELD **fields) 35750276Speter{ 35850276Speter FIELD **old; 35950276Speter int res; 360166124Srafan 361166124Srafan T((T_CALLED("set_form_fields(%p,%p)"), form, fields)); 362166124Srafan 363166124Srafan if (!form) 36450276Speter RETURN(E_BAD_ARGUMENT); 36550276Speter 366166124Srafan if (form->status & _POSTED) 36750276Speter RETURN(E_POSTED); 368166124Srafan 36950276Speter old = form->field; 370166124Srafan Disconnect_Fields(form); 371166124Srafan 372166124Srafan if ((res = Associate_Fields(form, fields)) != E_OK) 373166124Srafan Connect_Fields(form, old); 374166124Srafan 37550276Speter RETURN(res); 37650276Speter} 377166124Srafan 37850276Speter/*--------------------------------------------------------------------------- 37950276Speter| Facility : libnform 38050276Speter| Function : FIELD **form_fields( const FORM *form ) 38150276Speter| 38250276Speter| Description : Retrieve array of fields 38350276Speter| 38450276Speter| Return Values : Pointer to field array 38550276Speter+--------------------------------------------------------------------------*/ 38676726SpeterNCURSES_EXPORT(FIELD **) 387166124Srafanform_fields(const FORM *form) 38850276Speter{ 389166124Srafan T((T_CALLED("form_field(%p)"), form)); 390166124Srafan returnFieldPtr(Normalize_Form(form)->field); 39150276Speter} 39250276Speter 39350276Speter/*--------------------------------------------------------------------------- 39450276Speter| Facility : libnform 39550276Speter| Function : int field_count( const FORM *form ) 39650276Speter| 39750276Speter| Description : Retrieve number of fields 39850276Speter| 39950276Speter| Return Values : Number of fields, -1 if none are defined 40050276Speter+--------------------------------------------------------------------------*/ 40176726SpeterNCURSES_EXPORT(int) 402166124Srafanfield_count(const FORM *form) 40350276Speter{ 404166124Srafan T((T_CALLED("field_count(%p)"), form)); 405166124Srafan 406166124Srafan returnCode(Normalize_Form(form)->maxfield); 40750276Speter} 40850276Speter 40950276Speter/* frm_def.c ends here */ 410