#include #include #include #include #include "diadef.h" #include "dialog.h" #include "../diajava/proto.h" static FIELD_RADIO *first; /* #Specification: dialog / radio field A radio field is like a check box, but many fields are semanticly related. When you select one, the others are unselected. radio field are used to present a set of mutually exclusive option. It is possible to have a all radio fields unselected. Each radio field "edit" the save variable. Each one, when selected will set the variable to its own instance value. When all fields are unselected, the value 0xff is set. Here is an example # The checkbox is presented like this Enable PPP ( ) at boot time (o) on demand ( ) never # */ # PUBLIC FIELD_RADIO::FIELD_RADIO( const char *_prompt, char &_var, char _instance_val, const char *_title) : FIELD_CHECK_RADIO (_prompt,_var,_title) { instance_val = _instance_val; next = first; first = this; } PUBLIC FIELD_RADIO::~FIELD_RADIO() { // We remove ourself from the table FIELD_RADIO **ptpt = &first; while (*ptpt != NULL){ if (*ptpt == this){ *ptpt = next; break; } ptpt = &(*ptpt)->next; } } /* Draw only the input part of a field */ PUBLIC void FIELD_RADIO::drawtxt (WINDOW *dialog, int, int, int) { drawtxt_check (dialog,'(',')',val==instance_val ? 'o' : ' '); } PRIVATE FIELD_RADIO *FIELD_RADIO::locate_key(char *key) { FIELD_RADIO *found = NULL; FIELD_RADIO *pt = first; // Make sure we find the first (so we always find the same button) while (pt != NULL){ if (pt->var == var) found = pt; pt = pt->next; } found->format_htmlkey (key,found->nof); return found; } PUBLIC void FIELD_RADIO::html_draw (int, SSTRINGS & ) { char key[100]; FIELD_RADIO *original = locate_key (key); char opt[20]; snprintf (opt,sizeof(opt)-1,"item=\"%d\"",instance_val); html_defvar (prompt,title,"radio",key,val,opt); if (original == this){ html_defvarcur (key,backup); } } PUBLIC void FIELD_RADIO::reload(const char *dianame, int nof) { char key[100]; if (locate_key (key)==this && val != *var){ val = *var; if (dianame != NULL){ char tmp1[1000]; diagui_sendcmd (P_Setval,"%s R%s %d\n",formatpath(tmp1,dianame) ,key ,val); } } } PUBLIC void FIELD_RADIO::gui_draw (int _nof, SSTRINGS &) { nof = _nof; char key[100]; locate_key (key); guisendprompt(); char tmp[1000]; diagui_sendcmd (P_Radio,"R%s %d %d %s\n",key,instance_val,instance_val==val ,diagui_quote(title,tmp)); } PUBLIC MENU_STATUS FIELD_RADIO::gui_get(int, const char *, const char *) { char key[100]; locate_key (key); val = atoi (diagui_getval ('R',key)); return MENU_NULL; } /* Get the letter use to define the ID of a field in GUI mode. */ PUBLIC char FIELD_RADIO::getidprefix () { return 'R'; } PUBLIC int FIELD_RADIO::html_validate(int ) { int ret = -1; char key[100]; locate_key (key); int oldval_bool = atoi(html_getoldval(key)) == instance_val; int val_bool = backup == instance_val; int newval = atoi(html_getval(key)); // fprintf (stderr,"validate radio oldval_bool %d val_bool %d newval %d\n",oldval_bool,val_bool,newval); if (val_bool == oldval_bool){ ret = 0; val = newval; } return ret; } PUBLIC MENU_STATUS FIELD_RADIO::dokey ( WINDOW *, int key, FIELD_MSG &msg, bool &) { /* #Specification: dialog / FIELD_MSG / strategy The FIELD_MSG object was created to achieve the radio button widget. When a radio button is selected all other radio button operating on the same variable should unset themselves. To achive this, the radio button dokey() function loaded the address of the edition variable into the msg and loaded the instance value into the msg.int_val. It set msg.is_loaded to 1. This tells the main dialog edit loop to call processmsg for each field, passing to it the msg structure. Each field will compare msg.key to whatever it decide uniquely identify itself. If there is a match, it will process msg.int_val and decide whatever should be done. All radio buttons will redraw themselves if needed. This mecanism achieve a form of simple broadcast to all fields of a dialog. */ switch (key){ case ' ': msg.is_loaded = 1; msg.key = (void*)var; msg.int_val = instance_val; break; } return MENU_NULL; } PROTECTED void FIELD_RADIO::processmsg( WINDOW *dialog, FIELD_MSG &msg, int drawok) { if (msg.key == (void*)var){ int was_on = instance_val == val; val = msg.int_val; int is_on = instance_val == val; if (drawok && was_on != is_on) drawtxt(dialog,0,0,0); } } /* Add a check box field to the dialog. */ PUBLIC FIELD_RADIO *DIALOG::newf_radio( const char *prompt, char &var, char instance_val, const char *title) { FIELD_RADIO *s = new FIELD_RADIO(prompt,var,instance_val,title); add (s); return s; } PUBLIC FIELD_RADIO *DIALOG::newf_radio( const char *prompt, unsigned char &var, unsigned char instance_val, const char *title) { FIELD_RADIO *s = new FIELD_RADIO(prompt,(char&)var,instance_val,title); add (s); return s; }