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