Example #1
0
/*
 * Post the form to the screen.
 */
int
post_form(FORM *form)
{
	int rows, cols, status;
	
	if (form == NULL)
		return E_BAD_ARGUMENT;

	if (form->posted == 1)
		return E_POSTED;

	if ((form->fields == NULL) || (form->fields[0] == NULL))
		return E_NOT_CONNECTED;

	if (form->in_init == 1)
		return E_BAD_STATE;

	if (scale_form(form, &rows, &cols) != E_OK)
		return E_SYSTEM_ERROR;
	
	if ((form->scrwin != NULL) && ((rows > getmaxy(form->scrwin))
				       || (cols > getmaxx(form->scrwin)))) {
		return E_NO_ROOM;
	}

	form->in_init = 1;
	if (form->form_init != NULL)
		form->form_init(form);

	if (form->field_init != NULL)
		form->field_init(form);
	form->in_init = 0;

	_formi_pos_first_field(form);
	if ((status = _formi_draw_page(form)) != E_OK)
		return status;

	form->posted = 1;
	pos_form_cursor(form);
	
	return E_OK;
}
Example #2
0
int
form_driver(FORM *form, int c)
{
	FIELD *fieldp;
	int update_page, update_field, old_field, old_page, status;
	int start_field;
	unsigned int pos;
	
	if (form == NULL)
		return E_BAD_ARGUMENT;

	if ((form->fields == NULL) || (*(form->fields) == NULL))
		return E_INVALID_FIELD;

	if (form->posted != 1)
		return E_NOT_POSTED;

	if (form->in_init == 1)
		return E_BAD_STATE;


	old_field = start_field = form->cur_field;
	fieldp = form->fields[form->cur_field];
	update_page = update_field = 0;
	status = E_OK;
	
	if (c < REQ_MIN_REQUEST) {
		if (isprint(c) || isblank(c)) {
			do {
				pos = fieldp->start_char + fieldp->row_xpos;
				
			      /* check if we are allowed to edit this field */
				if ((fieldp->opts & O_EDIT) != O_EDIT)
					return E_REQUEST_DENIED;
				
				if ((status =
				     (_formi_add_char(fieldp, pos, c)))
				    == E_REQUEST_DENIED) {
			
					  /*
					   * Need to check here if we
					   * want to autoskip.  we
					   * call the form driver
					   * recursively to pos us on
					   * the next field and then
					   * we loop back to ensure
					   * the next field selected
					   * can have data added to it
					   */
					if ((fieldp->opts & O_AUTOSKIP)
					    != O_AUTOSKIP)
						return E_REQUEST_DENIED;
					status = form_driver(form,
							     REQ_NEXT_FIELD);
					if (status != E_OK)
						return status;

					  /*
					   * check if we have looped
                                           * around all the fields.
                                           * This can easily happen if
                                           * all the fields are full.
					   */
					if (start_field == form->cur_field)
						return E_REQUEST_DENIED;
					
					old_field = form->cur_field;
					fieldp = form->fields[form->cur_field];
					status = _formi_add_char(fieldp,
							fieldp->start_char
							+ fieldp->cursor_xpos,
							c);
				} else if (status == E_INVALID_FIELD)
					  /* char failed validation, just
					   * return the status.
					   */
					return status;
				else if (status == E_NO_ROOM)
					  /* we will get this if the line
					   * wrapping fails.  Deny the
					   * request.
					   */
					return E_REQUEST_DENIED;
			}
			while (status != E_OK);
			update_field = (status == E_OK);
		} else
			return E_REQUEST_DENIED;
	} else {
		if (c > REQ_MAX_COMMAND)
			return E_UNKNOWN_COMMAND;

		if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) {
			  /* first check the field we are in is ok */
			if (_formi_validate_field(form) != E_OK)
				return E_INVALID_FIELD;

			if (form->field_term != NULL)
				form->field_term(form);

			  /*
			   * if we have a page movement then the form term
			   * needs to be called too
			   */ 
			if ((c <= REQ_LAST_PAGE) && (form->form_term != NULL))
				form->form_term(form);
		}
		
			
		switch (c) {
		case REQ_NEXT_PAGE:
			if (form->page < form->max_page) {
				old_page = form->page;
				form->page++;
				update_page = 1;
				if (_formi_pos_first_field(form) != E_OK) {
					form->page = old_page;
					status = E_REQUEST_DENIED;
				}
			} else
				status = E_REQUEST_DENIED;
			break;
		
		case REQ_PREV_PAGE:
			if (form->page > 0) {
				old_page = form->page;
				form->page--;
				update_page = 1;
				if (_formi_pos_first_field(form) != E_OK) {
					form->page = old_page;
					status = E_REQUEST_DENIED;
				}
			} else
				status = E_REQUEST_DENIED;
			break;
		
		case REQ_FIRST_PAGE:
			old_page = form->page;
			form->page = 0;
			update_page = 1;
			if (_formi_pos_first_field(form) != E_OK) {
				form->page = old_page;
				status = E_REQUEST_DENIED;
			}
			break;
		
		case REQ_LAST_PAGE:
			old_page = form->page;
			form->page = form->max_page - 1;
			update_page = 1;
			if (_formi_pos_first_field(form) != E_OK) {
				form->page = old_page;
				status = E_REQUEST_DENIED;
			}
			break;
		
		case REQ_NEXT_FIELD:
			status = _formi_pos_new_field(form, _FORMI_FORWARD,
						      FALSE);
			update_field = 1;
			break;
		
		case REQ_PREV_FIELD:
			status = _formi_pos_new_field(form, _FORMI_BACKWARD,
						      FALSE);
			update_field = 1;
			break;
		
		case REQ_FIRST_FIELD:
			form->cur_field = 0;
			update_field = 1;
			break;
		
		case REQ_LAST_FIELD:
			form->cur_field = form->field_count - 1;
			update_field = 1;
			break;
		
		case REQ_SNEXT_FIELD:
			status = _formi_pos_new_field(form, _FORMI_FORWARD,
						      TRUE);
			update_field = 1;
			break;
		
		case REQ_SPREV_FIELD:
			status = _formi_pos_new_field(form, _FORMI_BACKWARD,
						      TRUE);
			update_field = 1;
			break;
		
		case REQ_SFIRST_FIELD:
			fieldp = TAILQ_FIRST(&form->sorted_fields);
			form->cur_field = fieldp->index;
			update_field = 1;
			break;
		
		case REQ_SLAST_FIELD:
			fieldp = TAILQ_LAST(&form->sorted_fields,
			    _formi_sort_head);
			form->cur_field = fieldp->index;
			update_field = 1;
			break;

			  /*
			   * The up, down, left and right field traversals
			   * are rolled up into a single function, allow a
			   * fall through to that function.
			   */
		case REQ_LEFT_FIELD:
		case REQ_RIGHT_FIELD:
		case REQ_UP_FIELD:
		case REQ_DOWN_FIELD:
			status = traverse_form_links(form, c);
			update_field = 1;
			break;

			  /* the following commands modify the buffer, check if
			     this is allowed first before falling through. */

		case REQ_DEL_PREV:
			  /*
			   * need to check for the overloading of this
			   * request.  If overload flag set and we are
			   * at the start of field this request turns
			   * into a previous field request. Otherwise
			   * fallthrough to the field handler.
			   */
			if ((form->opts & O_BS_OVERLOAD) == O_BS_OVERLOAD) {
				if ((fieldp->start_char == 0) &&
				    (fieldp->start_line == 0) &&
				    (fieldp->row_xpos == 0)) {
					update_field =
						_formi_manipulate_field(form,
							REQ_PREV_FIELD);
					break;
				}
			}

			  /* FALLTHROUGH */
		case REQ_NEW_LINE:
			  /*
			   * need to check for the overloading of this
			   * request.  If overload flag set and we are
			   * at the start of field this request turns
			   * into a next field request. Otherwise
			   * fallthrough to the field handler.
			   */
			if ((form->opts & O_NL_OVERLOAD) == O_NL_OVERLOAD) {
				if ((fieldp->start_char == 0) &&
				    (fieldp->start_line == 0) &&
				    (fieldp->row_xpos == 0)) {
					update_field =
						_formi_manipulate_field(form,
							REQ_NEXT_FIELD);
					break;
				}
			}

			  /* FALLTHROUGH */
		case REQ_INS_CHAR:
		case REQ_INS_LINE:
		case REQ_DEL_CHAR:
		case REQ_DEL_LINE:
		case REQ_DEL_WORD:
		case REQ_CLR_EOL:
		case REQ_CLR_EOF:
		case REQ_CLR_FIELD:
		case REQ_OVL_MODE:
		case REQ_INS_MODE:
			  /* check if we are allowed to edit the field and fall
			   * through if we are.
			   */
			if ((form->fields[form->cur_field]->opts & O_EDIT) != O_EDIT)
				return E_REQUEST_DENIED;
		
			  /* the following manipulate the field contents, bundle
			     them into one function.... */
			  /* FALLTHROUGH */
		case REQ_NEXT_CHAR:
		case REQ_PREV_CHAR:
		case REQ_NEXT_LINE:
		case REQ_PREV_LINE:
		case REQ_NEXT_WORD:
		case REQ_PREV_WORD:
		case REQ_BEG_FIELD:
		case REQ_END_FIELD:
		case REQ_BEG_LINE:
		case REQ_END_LINE:
		case REQ_LEFT_CHAR:
		case REQ_RIGHT_CHAR:
		case REQ_UP_CHAR:
		case REQ_DOWN_CHAR:
		case REQ_SCR_FLINE:
		case REQ_SCR_BLINE:
		case REQ_SCR_FPAGE:
		case REQ_SCR_BPAGE:
		case REQ_SCR_FHPAGE:
		case REQ_SCR_BHPAGE:
		case REQ_SCR_FCHAR:
		case REQ_SCR_BCHAR:
		case REQ_SCR_HFLINE:
		case REQ_SCR_HBLINE:
		case REQ_SCR_HFHALF:
		case REQ_SCR_HBHALF:
			update_field = _formi_manipulate_field(form, c);
			break;
		
		case REQ_VALIDATION:
			return _formi_validate_field(form);
			  /* NOTREACHED */
			break;
		
		case REQ_PREV_CHOICE:
		case REQ_NEXT_CHOICE:
			update_field = _formi_field_choice(form, c);
			  /* reinit the cursor pos just in case */
			if (update_field == 1) {
				_formi_init_field_xpos(fieldp);
				fieldp->row_xpos = 0;
			}
			break;

		default: /* should not need to do this, but.... */
			return E_UNKNOWN_COMMAND;
			  /* NOTREACHED */
			break;
		}
	}

	  /* call the field and form init functions if required. */
	if ((c >= REQ_NEXT_PAGE) && (c <= REQ_DOWN_FIELD)) {
		if (form->field_init != NULL)
			form->field_init(form);

		  /*
		   * if we have a page movement then the form init
		   * needs to be called too
		   */ 
		if ((c <= REQ_LAST_PAGE) && (form->form_init != NULL))
			form->form_init(form);

		  /*
		   * if there was an error just return now...
		   */
		if (status != E_OK)
			return status;

		  /* if we have no error, reset the various offsets */
		fieldp = form->fields[form->cur_field];
		fieldp->start_char = 0;
		fieldp->start_line = fieldp->alines;
		fieldp->cur_line = fieldp->alines;
		fieldp->row_xpos = 0;
		fieldp->cursor_ypos = 0;
		_formi_init_field_xpos(fieldp);
	}
	
	if (update_field < 0)
		return update_field;

	if (update_field == 1)
		update_page |= _formi_update_field(form, old_field);

	if (update_page == 1)
		_formi_draw_page(form);

	pos_form_cursor(form);

	if ((update_page == 1) || (update_field == 1))
		wrefresh(form->scrwin);
	
	return E_OK;
}