frm_def.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /****************************************************************************
  2. * Copyright (c) 1998 Free Software Foundation, Inc. *
  3. * *
  4. * Permission is hereby granted, free of charge, to any person obtaining a *
  5. * copy of this software and associated documentation files (the *
  6. * "Software"), to deal in the Software without restriction, including *
  7. * without limitation the rights to use, copy, modify, merge, publish, *
  8. * distribute, distribute with modifications, sublicense, and/or sell *
  9. * copies of the Software, and to permit persons to whom the Software is *
  10. * furnished to do so, subject to the following conditions: *
  11. * *
  12. * The above copyright notice and this permission notice shall be included *
  13. * in all copies or substantial portions of the Software. *
  14. * *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
  16. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
  18. * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
  19. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
  20. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
  21. * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
  22. * *
  23. * Except as contained in this notice, the name(s) of the above copyright *
  24. * holders shall not be used in advertising or otherwise to promote the *
  25. * sale, use or other dealings in this Software without prior written *
  26. * authorization. *
  27. ****************************************************************************/
  28. /****************************************************************************
  29. * Author: Juergen Pfeifer <juergen.pfeifer@gmx.net> 1995,1997 *
  30. ****************************************************************************/
  31. #include "form.priv.h"
  32. MODULE_ID("$Id$")
  33. /* this can't be readonly */
  34. static FORM default_form = {
  35. 0, /* status */
  36. 0, /* rows */
  37. 0, /* cols */
  38. 0, /* currow */
  39. 0, /* curcol */
  40. 0, /* toprow */
  41. 0, /* begincol */
  42. -1, /* maxfield */
  43. -1, /* maxpage */
  44. -1, /* curpage */
  45. ALL_FORM_OPTS, /* opts */
  46. (WINDOW *)0, /* win */
  47. (WINDOW *)0, /* sub */
  48. (WINDOW *)0, /* w */
  49. (FIELD **)0, /* field */
  50. (FIELD *)0, /* current */
  51. (_PAGE *)0, /* page */
  52. (char *)0, /* usrptr */
  53. NULL, /* forminit */
  54. NULL, /* formterm */
  55. NULL, /* fieldinit */
  56. NULL /* fieldterm */
  57. };
  58. FORM *_nc_Default_Form = &default_form;
  59. /*---------------------------------------------------------------------------
  60. | Facility : libnform
  61. | Function : static FIELD *Insert_Field_By_Position(
  62. | FIELD *new_field,
  63. | FIELD *head )
  64. |
  65. | Description : Insert new_field into sorted fieldlist with head "head"
  66. | and return new head of sorted fieldlist. Sorting
  67. | criteria is (row,column). This is a circular list.
  68. |
  69. | Return Values : New head of sorted fieldlist
  70. +--------------------------------------------------------------------------*/
  71. static FIELD *Insert_Field_By_Position(FIELD *newfield, FIELD *head)
  72. {
  73. FIELD *current, *newhead;
  74. assert(newfield != 0);
  75. if (!head)
  76. { /* empty list is trivial */
  77. newhead = newfield->snext = newfield->sprev = newfield;
  78. }
  79. else
  80. {
  81. newhead = current = head;
  82. while((current->frow < newfield->frow) ||
  83. ((current->frow==newfield->frow) &&
  84. (current->fcol < newfield->fcol)) )
  85. {
  86. current = current->snext;
  87. if (current==head)
  88. { /* We cycled through. Reset head to indicate that */
  89. head = (FIELD *)0;
  90. break;
  91. }
  92. }
  93. /* we leave the loop with current pointing to the field after newfield*/
  94. newfield->snext = current;
  95. newfield->sprev = current->sprev;
  96. newfield->snext->sprev = newfield;
  97. newfield->sprev->snext = newfield;
  98. if (current==head)
  99. newhead = newfield;
  100. }
  101. return(newhead);
  102. }
  103. /*---------------------------------------------------------------------------
  104. | Facility : libnform
  105. | Function : static void Disconnect_Fields(FORM *form)
  106. |
  107. | Description : Break association between form and array of fields.
  108. |
  109. | Return Values : -
  110. +--------------------------------------------------------------------------*/
  111. static void Disconnect_Fields( FORM * form )
  112. {
  113. if (form->field)
  114. {
  115. FIELD **fields;
  116. for(fields=form->field;*fields;fields++)
  117. {
  118. if (form == (*fields)->form)
  119. (*fields)->form = (FORM *)0;
  120. }
  121. form->rows = form->cols = 0;
  122. form->maxfield = form->maxpage = -1;
  123. form->field = (FIELD **)0;
  124. if (form->page)
  125. free(form->page);
  126. form->page = (_PAGE *)0;
  127. }
  128. }
  129. /*---------------------------------------------------------------------------
  130. | Facility : libnform
  131. | Function : static int Connect_Fields(FORM *form, FIELD **fields)
  132. |
  133. | Description : Set association between form and array of fields.
  134. |
  135. | Return Values : E_OK - no error
  136. | E_CONNECTED - a field is already connected
  137. | E_BAD_ARGUMENT - Invalid form pointer or field array
  138. | E_SYSTEM_ERROR - not enough memory
  139. +--------------------------------------------------------------------------*/
  140. static int Connect_Fields(FORM * form, FIELD ** fields)
  141. {
  142. int field_cnt, j;
  143. int page_nr;
  144. int maximum_row_in_field, maximum_col_in_field;
  145. _PAGE *pg;
  146. assert(form != 0);
  147. form->field = fields;
  148. form->maxfield = 0;
  149. form->maxpage = 0;
  150. if (!fields)
  151. RETURN(E_OK);
  152. page_nr = 0;
  153. /* store formpointer in fields and count pages */
  154. for(field_cnt=0;fields[field_cnt];field_cnt++)
  155. {
  156. if (fields[field_cnt]->form)
  157. RETURN(E_CONNECTED);
  158. if ( field_cnt==0 ||
  159. (fields[field_cnt]->status & _NEWPAGE))
  160. page_nr++;
  161. fields[field_cnt]->form = form;
  162. }
  163. if (field_cnt==0)
  164. RETURN(E_BAD_ARGUMENT);
  165. /* allocate page structures */
  166. if ( (pg = (_PAGE *)malloc(page_nr * sizeof(_PAGE))) != (_PAGE *)0 )
  167. {
  168. form->page = pg;
  169. }
  170. else
  171. RETURN(E_SYSTEM_ERROR);
  172. /* Cycle through fields and calculate page boundaries as well as
  173. size of the form */
  174. for(j=0;j<field_cnt;j++)
  175. {
  176. if (j==0)
  177. pg->pmin = j;
  178. else
  179. {
  180. if (fields[j]->status & _NEWPAGE)
  181. {
  182. pg->pmax = j-1;
  183. pg++;
  184. pg->pmin = j;
  185. }
  186. }
  187. maximum_row_in_field = fields[j]->frow + fields[j]->rows;
  188. maximum_col_in_field = fields[j]->fcol + fields[j]->cols;
  189. if (form->rows < maximum_row_in_field)
  190. form->rows = maximum_row_in_field;
  191. if (form->cols < maximum_col_in_field)
  192. form->cols = maximum_col_in_field;
  193. }
  194. pg->pmax = field_cnt-1;
  195. form->maxfield = field_cnt;
  196. form->maxpage = page_nr;
  197. /* Sort fields on form pages */
  198. for(page_nr = 0;page_nr < form->maxpage; page_nr++)
  199. {
  200. FIELD *fld = (FIELD *)0;
  201. for(j = form->page[page_nr].pmin;j <= form->page[page_nr].pmax;j++)
  202. {
  203. fields[j]->index = j;
  204. fields[j]->page = page_nr;
  205. fld = Insert_Field_By_Position(fields[j],fld);
  206. }
  207. form->page[page_nr].smin = fld->index;
  208. form->page[page_nr].smax = fld->sprev->index;
  209. }
  210. RETURN(E_OK);
  211. }
  212. /*---------------------------------------------------------------------------
  213. | Facility : libnform
  214. | Function : static int Associate_Fields(FORM *form, FIELD **fields)
  215. |
  216. | Description : Set association between form and array of fields.
  217. | If there are fields, position to first active field.
  218. |
  219. | Return Values : E_OK - success
  220. | any other - error occurred
  221. +--------------------------------------------------------------------------*/
  222. INLINE static int Associate_Fields(FORM *form, FIELD **fields)
  223. {
  224. int res = Connect_Fields(form,fields);
  225. if (res == E_OK)
  226. {
  227. if (form->maxpage>0)
  228. {
  229. form->curpage = 0;
  230. form_driver(form,FIRST_ACTIVE_MAGIC);
  231. }
  232. else
  233. {
  234. form->curpage = -1;
  235. form->current = (FIELD *)0;
  236. }
  237. }
  238. return(res);
  239. }
  240. /*---------------------------------------------------------------------------
  241. | Facility : libnform
  242. | Function : FORM *new_form( FIELD **fields )
  243. |
  244. | Description : Create new form with given array of fields.
  245. |
  246. | Return Values : Pointer to form. NULL if error occurred.
  247. +--------------------------------------------------------------------------*/
  248. FORM *new_form(FIELD ** fields)
  249. {
  250. int err = E_SYSTEM_ERROR;
  251. FORM *form = (FORM *)malloc(sizeof(FORM));
  252. if (form)
  253. {
  254. *form = *_nc_Default_Form;
  255. if ((err=Associate_Fields(form,fields))!=E_OK)
  256. {
  257. free_form(form);
  258. form = (FORM *)0;
  259. }
  260. }
  261. if (!form)
  262. SET_ERROR(err);
  263. return(form);
  264. }
  265. /*---------------------------------------------------------------------------
  266. | Facility : libnform
  267. | Function : int free_form( FORM *form )
  268. |
  269. | Description : Release internal memory associated with form.
  270. |
  271. | Return Values : E_OK - no error
  272. | E_BAD_ARGUMENT - invalid form pointer
  273. | E_POSTED - form is posted
  274. +--------------------------------------------------------------------------*/
  275. int free_form(FORM * form)
  276. {
  277. if ( !form )
  278. RETURN(E_BAD_ARGUMENT);
  279. if ( form->status & _POSTED)
  280. RETURN(E_POSTED);
  281. Disconnect_Fields( form );
  282. if (form->page)
  283. free(form->page);
  284. free(form);
  285. RETURN(E_OK);
  286. }
  287. /*---------------------------------------------------------------------------
  288. | Facility : libnform
  289. | Function : int set_form_fields( FORM *form, FIELD **fields )
  290. |
  291. | Description : Set a new association of an array of fields to a form
  292. |
  293. | Return Values : E_OK - no error
  294. | E_BAD_ARGUMENT - invalid form pointer
  295. | E_POSTED - form is posted
  296. +--------------------------------------------------------------------------*/
  297. int set_form_fields(FORM * form, FIELD ** fields)
  298. {
  299. FIELD **old;
  300. int res;
  301. if ( !form )
  302. RETURN(E_BAD_ARGUMENT);
  303. if ( form->status & _POSTED )
  304. RETURN(E_POSTED);
  305. old = form->field;
  306. Disconnect_Fields( form );
  307. if( (res = Associate_Fields( form, fields )) != E_OK )
  308. Connect_Fields( form, old );
  309. RETURN(res);
  310. }
  311. /*---------------------------------------------------------------------------
  312. | Facility : libnform
  313. | Function : FIELD **form_fields( const FORM *form )
  314. |
  315. | Description : Retrieve array of fields
  316. |
  317. | Return Values : Pointer to field array
  318. +--------------------------------------------------------------------------*/
  319. FIELD **form_fields(const FORM * form)
  320. {
  321. return (Normalize_Form( form )->field);
  322. }
  323. /*---------------------------------------------------------------------------
  324. | Facility : libnform
  325. | Function : int field_count( const FORM *form )
  326. |
  327. | Description : Retrieve number of fields
  328. |
  329. | Return Values : Number of fields, -1 if none are defined
  330. +--------------------------------------------------------------------------*/
  331. int field_count(const FORM * form)
  332. {
  333. return (Normalize_Form( form )->maxfield);
  334. }
  335. /* frm_def.c ends here */