* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#define _GNU_SOURCE
-
+#if defined(HAVE_CONFIG_H)
#include "config.h"
+#endif
#include <linux/input.h> /* This must be included before ncurses.h */
#if defined HAVE_NCURSESW_CURSES_H
#include <log/log.h>
#include <util/util.h>
-#include "config.h"
#include "nc-cui.h"
#include "nc-widgets.h"
void (*widget_focus)(struct nc_widget *, void *);
void *widget_focus_arg;
FIELD *cur_field;
+
+ /* custom validators */
+ FIELDTYPE *ipv4_multi_type;
};
struct nc_widget {
};
struct nc_widget_textbox {
+ struct nc_widgetset *set;
struct nc_widget widget;
};
FIELD *f;
textbox = talloc_zero(set, struct nc_widget_textbox);
+ textbox->set = set;
textbox->widget.height = 1;
textbox->widget.width = len;
textbox->widget.x = x;
return textbox;
}
+void widget_textbox_set_fixed_size(struct nc_widget_textbox *textbox)
+{
+ field_opts_on(textbox->widget.field, O_STATIC);
+}
+
+void widget_textbox_set_validator_integer(struct nc_widget_textbox *textbox,
+ long min, long max)
+{
+ set_field_type(textbox->widget.field, TYPE_INTEGER, 1, min, max);
+}
+
+void widget_textbox_set_validator_ipv4(struct nc_widget_textbox *textbox)
+{
+ set_field_type(textbox->widget.field, TYPE_IPV4);
+}
+
+static bool check_ipv4_multi_char(int c,
+ const void *arg __attribute__((unused)))
+{
+ return isdigit(c) || c == '.' || c == ' ';
+}
+
+static bool check_ipv4_multi_field(FIELD *field,
+ const void *arg __attribute__((unused)))
+{
+ char *buf = field_buffer(field, 0);
+ unsigned int ip[4];
+ int n, len;
+
+ while (*buf != '\0') {
+ n = sscanf(buf, "%u.%u.%u.%u%n",
+ &ip[0], &ip[1], &ip[2], &ip[3], &len);
+ if (n != 4)
+ return false;
+
+ if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255)
+ return false;
+
+ for (buf += len; *buf != '\0'; buf++) {
+ if (isspace(*buf))
+ continue;
+ else if (isdigit(*buf))
+ break;
+ else
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void widget_textbox_set_validator_ipv4_multi(struct nc_widget_textbox *textbox)
+{
+ if (!textbox->set->ipv4_multi_type) {
+ textbox->set->ipv4_multi_type = new_fieldtype(
+ check_ipv4_multi_field,
+ check_ipv4_multi_char);
+ }
+ set_field_type(textbox->widget.field, textbox->set->ipv4_multi_type);
+}
+
static void select_option_change(struct select_option *opt, bool selected)
{
const char *str;
bool widgetset_process_key(struct nc_widgetset *set, int key)
{
struct nc_widget *widget;
- FIELD *field;
+ FIELD *field, *tmp;
int req = 0;
+ bool tab;
field = current_field(set->form);
assert(field);
+ tab = false;
+
/* handle field change events */
switch (key) {
case KEY_BTAB:
+ tab = true;
+ /* fall through */
case KEY_UP:
req = REQ_PREV_FIELD;
break;
case '\t':
+ tab = true;
+ /* fall through */
case KEY_DOWN:
req = REQ_NEXT_FIELD;
break;
if (req) {
widget_focus_change(widget, field, false);
form_driver(set->form, req);
- form_driver(set->form, REQ_END_FIELD);
+
+ /* if we're doing a tabbed-field-change, skip until we
+ * see the next widget */
+ tmp = field;
field = current_field(set->form);
+
+ for (; tab && tmp != field && field_userptr(field) == widget;) {
+ form_driver(set->form, req);
+ field = current_field(set->form);
+ }
+
+ form_driver(set->form, REQ_END_FIELD);
widget = field_userptr(field);
widget_focus_change(widget, field, true);
if (widget->field_focus)
{
struct nc_widgetset *set = ptr;
free_form(set->form);
+ if (set->ipv4_multi_type)
+ free_fieldtype(set->ipv4_multi_type);
return 0;
}