#include #include #include #include #include "diadef.h" #include "dialog.h" #include "dialog.m" #include "../diajava/proto.h" PUBLIC FIELD::FIELD(const char *_prompt) { readonly = false; if (_prompt == NULL) _prompt = "\n"; // See diagui_send_label prompt = strdup(_prompt); box.width = 30; // Default visible width maybeempty = true; may_select = false; is_head = false; vsize = 1; donotcheckold = false; msg = NULL; original_prompt = _prompt; //We want the pointer regkey = NULL; } /* Record the extra GUI parameters for field. See ../doc/guiapi.sgml to learn which parameter are available. In general, you have dc=drawing_context */ PUBLIC void FIELD::set_guiparms(const char *_parms) { guiparms.setfrom (_parms); } PUBLIC void FIELD::set_guipath(const char *_path) { int path_len = (_path != NULL)?strlen(_path):0; int sufix_len = guipath_sufix.getlen(); int buf_size = path_len + sufix_len + 2; char *buf = (char*) malloc(buf_size); if (path_len > 0 && sufix_len > 0){ sprintf(buf,"%s.%s",_path,guipath_sufix.get()); }else if (path_len > 0){ strcpy(buf,_path); }else if (sufix_len > 0){ strcpy(buf,guipath_sufix.get()); }else{ *buf = 0; } guipath.setfrom(buf); } PUBLIC VIRTUAL FIELD::~FIELD() { free (prompt); } PUBLIC void FIELD::set_helpdia(PRIVATE_MESSAGE &_msg) { msg = &_msg; } /* Draw a component of a popup menu in GUI mode By default, does nothing. */ PUBLIC VIRTUAL void FIELD::popup_draw( int, // ID int &) // level { } /* Return the notepad level. 0 for no notepad. Normal edit field return 0. FIELD_TITLE return their level. This allows DIALOG::editgui() to tell where are the FIELD_TITLE field and create a special form at the beginning of the dialog. */ PUBLIC VIRTUAL int FIELD::getnotepadlevel() const { return 0; } /* Indicate that this field may not be empty. This does not apply to all field. For checkbox, it is meaningless. */ PUBLIC VIRTUAL void FIELD::set_noempty() { maybeempty = false; } /* Indicate that this field may be selected or not. */ PUBLIC VIRTUAL void FIELD::set_selectable(bool _may_select) { may_select = _may_select; } /* Return true if this field is selectable */ PUBLIC VIRTUAL bool FIELD::is_selectable() { return may_select; } /* Return true if this field is a passthrough */ PUBLIC VIRTUAL bool FIELD::is_passthrough() { return false; } /* This function is called when the user quits the dialog (with accept) each field may return -1 if something is not appropriate. The field is responsible to signal the error and it will become the current field immediatly. */ PUBLIC VIRTUAL int FIELD::post_validate() { return 0; } /* Is the field editable or is it write protect. Title field do use this feature. */ PUBLIC bool FIELD::is_readonly() { return readonly; } /* Set the readonly status of a field. */ PUBLIC void FIELD::set_readonly() { readonly = true; } /* Process conditionnally a message and conditionnally redraw yourself if needed. See radio.c for the intended application. */ PROTECTED VIRTUAL void FIELD::processmsg(WINDOW *, FIELD_MSG &, int) { } /* Get the width of the columns of a field. This is generally used by menu item and title field. */ PROTECTED VIRTUAL int FIELD::getwidths ( int [], // Will contain the width int &) // Will contain the 1 if this field is starting // a new disposition set // It already contain 0 so no need to touch it { return 0; } /* Set the width of the first column of a field. This is only meaningful for a Menu item. */ PROTECTED VIRTUAL void FIELD::setwidths (int, int []) { } /* Return the second string of a menu item */ PUBLIC VIRTUAL const char *FIELD::getmenustr() const { return NULL; } PUBLIC VIRTUAL const char *FIELD::getmenuicon() const { return NULL; } /* Build a key that uniquely identify this field in the dialog */ PUBLIC VIRTUAL void FIELD::format_htmlkey(char *key, int nof) { html_formatkey (key,"%s-%d",prompt,nof); } PRIVATE void FIELD_STRING_BASE::init (int maxsiz) { x.input = x.scroll = 0; password_mode = 0; size = maxsiz; buf = (char*)malloc_err (size+1); maybeempty = 1; fwidth = 30; } PROTECTED FIELD_STRING_BASE::FIELD_STRING_BASE( const char *_prompt, const char *_str, int maxsiz) : FIELD (_prompt) { init(maxsiz); strncpy (buf,_str,maxsiz); buf[maxsiz] = '\0'; backup = _str; } PROTECTED FIELD_STRING_BASE::FIELD_STRING_BASE( const char *_prompt, int maxsiz) : FIELD (_prompt) { init(maxsiz); buf[0] = '\0'; } PUBLIC FIELD_STRING_BASE::~FIELD_STRING_BASE() { free (buf); } /* Return true if the field is empty */ PUBLIC bool FIELD_STRING_BASE::is_empty() { bool ret = true; char *pt = buf; while (*pt != '\0'){ if (*pt != ' '){ ret = false; break; } pt++; } return ret; } PUBLIC int FIELD_STRING_BASE::post_validate() { int ret = 0; if (!maybeempty && is_empty()){ if (prompt[0] != '\0'){ xconf_error (MSG_U(E_NOEMPTYNAME ,"The field `%s`\nmay not be empty") ,prompt); }else{ xconf_error (MSG_U(E_NOEMPTY,"This field may not be empty")); } ret = -1; } return ret; } PUBLIC FIELD_STRING::FIELD_STRING( const char *_prompt, char *_str, int _maxsiz, bool _mayreload) : FIELD_STRING_BASE (_prompt, _str, _maxsiz) { mayreload = _mayreload; str = _str; } PUBLIC FIELD_STRING::~FIELD_STRING() { } PUBLIC FIELD_PASSWORD::FIELD_PASSWORD( const char *_prompt, SSTRING &_str) : FIELD_SSTRING (_prompt,_str,30) { buf[0] = '\0'; password_mode = 1; } PUBLIC void FIELD_STRING::save() { if (mayreload){ strcpy (str,buf); strip_end (str); } } /* Restore the original value of the field from the backup */ PUBLIC void FIELD_STRING::restore() { if (mayreload) backup.copy (str); } const char *field_formatpath ( char tmp[1000], const char *diapath, const char *fldpath) { if (diapath[0] == '\0' && fldpath[0] == '\0'){ strcpy (tmp,"\"\""); }else if (diapath[0] != '\0' && fldpath[0] != '\0'){ snprintf (tmp,999,"%s.%s",diapath,fldpath); }else{ snprintf (tmp,999,"%s%s",diapath,fldpath); } return tmp; } PROTECTED const char *FIELD::formatpath ( char tmp[1000], const char *diapath) { return field_formatpath (tmp,diapath,guipath.get()); } /* Send the value to the front end if needed */ PROTECTED void FIELD::sendval( const char *dianame, int nof, char type, const char *val) { if (dianame != NULL){ char tmp[1000],tmp1[1000]; diagui_sendcmd (P_Setval,"%s %c%d %s\n",formatpath(tmp1,dianame) ,type,nof ,diagui_quote(val,tmp)); } } PROTECTED void FIELD::sendval( const char *dianame, int nof, char type, int val) { if (dianame != NULL){ char tmp1[1000]; diagui_sendcmd (P_Setval,"%s %c%d %d\n",formatpath(tmp1,dianame) ,type,nof,val); } } /* Reload the input buffer from the client variable value. */ PUBLIC void FIELD_STRING::reload(const char *dianame, int nof) { if (mayreload){ if (strcmp(buf,str)!=0){ strcpy (buf,str); sendval (dianame,nof,getidprefix(),buf); } } } /* Draw only the input part of a field */ PUBLIC void FIELD_STRING_BASE::drawtxt (WINDOW *dialog, int, int, int) { int blank_start; wattrset(dialog, inputbox_attr); wmove(dialog, box.y,box.x); if (password_mode){ blank_start = 0; }else{ // Make sure the string is not too long char *instr = buf + x.scroll; char *last_visible = instr + box.width; char tmp = *last_visible; *last_visible = '\0'; waddstr (dialog,instr); blank_start = strlen(instr); *last_visible = tmp; } const int box_width = box.width; for (int i=blank_start; i%s",prompt); if (readonly){ html_printf ("%s\n",buf); }else{ char key[100]; format_htmlkey (key,nof); char opt[30]; sprintf (opt,"size=%d maxlength=256",fwidth); html_defvar (password_mode ? "password" : "text",key,buf,opt); html_defvarcur (key,backup.get()); } } /* Transmit the prompt of a field to the GUI front-end */ PROTECTED void FIELD::guisendprompt() { if (prompt[0] != '\0'){ diagui_send_Label (prompt); }else{ diagui_sendcmd (P_Skip,"1\n"); } } PROTECTED void FIELD::xulsendprompt() { if (prompt[0] != '\0'){ xul_send_Label (prompt); }else{ xul_send_skip (1); } } PUBLIC void FIELD_STRING_BASE::gui_draw(int nof, SSTRINGS &) { guisendprompt(); const char *dollar = ""; if (guiparms.is_filled()) dollar=" $"; if (readonly){ char tmp[1000]; diagui_sendcmd (P_Label,"%s $id=S%d look=3d len=%d%s%s\n" ,diagui_quote(buf,tmp),nof ,fwidth ,dollar,guiparms.get()); }else if (password_mode){ char tmp[1000]; diagui_sendcmd (P_Password,"S%d %d %s%s%s\n",nof,fwidth ,diagui_quote(buf,tmp) ,dollar,guiparms.get()); }else{ char tmp[1000]; diagui_sendcmd (P_String,"S%d %d %s%s%s\n",nof,fwidth ,diagui_quote(buf,tmp) ,dollar,guiparms.get()); } } PUBLIC void FIELD_STRING_BASE::xul_draw(int nof, SSTRINGS &) { xulsendprompt(); const char *dollar = ""; if (guiparms.is_filled()) dollar=" $"; if (readonly){ #if 0 char tmp[1000]; diagui_sendcmd (P_Label,"%s $id=S%d look=3d len=%d%s%s\n" ,diagui_quote(buf,tmp),nof ,fwidth ,dollar,guiparms.get()); #endif }else if (password_mode){ #if 0 char tmp[1000]; diagui_sendcmd (P_Password,"S%d %d %s%s%s\n",nof,fwidth ,diagui_quote(buf,tmp) ,dollar,guiparms.get()); #endif }else{ #if 0 char tmp[1000]; diagui_sendcmd (P_String,"S%d %d %s%s%s\n",nof,fwidth ,diagui_quote(buf,tmp) ,dollar,guiparms.get()); #endif } } PUBLIC VIRTUAL void FIELD::draw_helpdia(WINDOW *, int) { } /* Standard function used by all field supporting help dialog */ PUBLIC void FIELD::draw_helpdia_common(WINDOW *dialog, int nof) { if (msg != NULL){ if (dialog_mode == DIALOG_GUI){ char name_sent[PATH_MAX]; diagui_sendxpm ("fhelper",name_sent); char tmp[1000]; diagui_sendcmd (P_Button_xpm,"B%d %s $dump=1\n",200+nof ,diagui_quote(name_sent,tmp)); }else if (dialog_mode == DIALOG_CURSES){ // Add the little button wattrset(dialog, inputbox_attr); wmove(dialog, box.y,box.x+box.width-1); waddch (dialog,ACS_DARROW); } } } PUBLIC void FIELD_STRING_BASE::draw_helpdia(WINDOW *dialog, int nof) { draw_helpdia_common (dialog,nof); } PUBLIC MENU_STATUS FIELD_STRING_BASE::gui_get(int nof, const char *, const char *) { if (!readonly) strcpy_cut (buf,diagui_getval('S',nof),size); return MENU_NULL; } /* Get the letter use to define the ID of a field in GUI mode. */ PUBLIC char FIELD_STRING_BASE::getidprefix () { return 'S'; } /* Grab the user input received from the www browser. Check that the current value of the field matches the hidden (old) value of the field encoded in the HTML form. If there is a mismatch, it means this www form was too old and the input is refused. */ PUBLIC int FIELD_STRING_BASE::html_validate(int nof) { int ret = -1; char key[100]; format_htmlkey (key,nof); const char *old_val = html_getoldval (key); const char *new_val = html_getval (key); fprintf (stderr,"validate %s val :%s: old :%s: buf :%s:\n",key,new_val,old_val,buf); if ((donotcheckold || backup.cmp(old_val)==0) && (int)strlen(new_val)0); FIELD *f = getitem(getnb()-1); f->set_donotcheckold(); } /* Draw the field with the prompt and the surrounding box */ PUBLIC void FIELD::draw ( WINDOW *dialog, int offset, int start_line, // First line of the widget to draw // Normally 0 int end_line) // last line of the widget to draw, normally 0 { for (int i=start_line; i<= end_line; i++){ int posy = box.y + i; wmove(dialog, posy,1); wattrset(dialog, dialog_attr); int len = 0; if (i==0 && prompt[0] != '\n'){ waddstr (dialog,prompt); len = strlen(prompt); } int lastx = box.x-2; for ( ; len < lastx; len++) waddch (dialog,' '); } drawtxt(dialog, offset, start_line, end_line); } /* Position the cursor in the field */ PUBLIC VIRTUAL void FIELD::setcursor(WINDOW *dialog, int) { wmove (dialog,box.y,box.x); } /* Called when the field loose selection. This was done mostly for menu entries which is a very special case. The default behavior does nothing. */ PUBLIC VIRTUAL void FIELD::unselect(WINDOW *, int) { } PUBLIC void FIELD_STRING_BASE::setcursor(WINDOW *dialog, int) { wmove (dialog,box.y,box.x+x.input-x.scroll); } bool field_editline ( WINDOW *dialog, bool password_mode, FIELDEDIT_TYPE char_mode, int key, int box_width, int box_y, int box_x, int size, int &input_x, int &scroll, char *instr) { int curlen = strlen(instr); int last_scroll = scroll; bool mustdraw = false; switch (key){ case 1: // ^A like emacs case KEY_HOME: input_x = 0; scroll = 0; break; case 5: // ^E like Emacs case KEY_END: input_x = curlen; if (input_x > box_width){ scroll = input_x - box_width + 1; }else{ scroll = 0; } break; case 2: // ^B like Emacs case KEY_LEFT: if (input_x > 0) input_x--; break; case 6: // ^F like Emacs case KEY_RIGHT: if (input_x < curlen) input_x++; break; case KEY_BACKSPACE: case DEL: if (input_x > 0) { int i; input_x--; for (i=input_x; iinput_x; i--) instr[i] = instr[i-1]; mustdraw = true; } instr[input_x] = key; int last = curlen + 1; if (last > size) last = size; instr[last] = '\0'; input_x++; if (input_x - scroll == box_width) { scroll++; }else{ wmove(dialog, box_y, input_x-1-scroll + box_x); if (!password_mode) waddch(dialog, key); } } } } if (input_x < scroll){ scroll--; }else if (input_x - scroll == box_width){ scroll++; } return mustdraw || last_scroll != scroll; } PUBLIC MENU_STATUS FIELD_STRING_BASE::dokey ( WINDOW *dialog, int key, FIELD_MSG &, bool &) { MENU_STATUS ret = MENU_NULL; if (readonly) return MENU_NULL; if (key == 24 || key == KEY_F(4)){ if (msg != NULL){ dialog_sendmessage (*msg); ret = MENU_MESSAGE; } }else if (field_editline (dialog,password_mode,FIELDEDIT_ANY ,key,box.width,box.y,box.x,size,x.input,x.scroll,buf)){ drawtxt (dialog,0,0,0); } return ret; } PUBLIC FIELD_SSTRING::FIELD_SSTRING( const char *_prompt, SSTRING &_str, int field_width) : FIELD_STRING_BASE (_prompt, _str.get(), _str.getmaxsiz()), str(_str) { fwidth = field_width; } PUBLIC void FIELD_SSTRING::save() { str.setfrom(buf); } PUBLIC void FIELD_SSTRING::restore () { str.setfrom(backup); } PUBLIC void FIELD_SSTRING::reload (const char *dianame, int nof) { if (str.cmp(buf)!=0){ strcpy (buf,str.get()); sendval (dianame,nof,getidprefix(),buf); } } /* Draw the field with the prompt */ PUBLIC void FIELD_SSTRING::html_draw(int nof) { html_printf ("%s",prompt); if (readonly){ html_printf ("%s\n",buf); }else{ char key[100]; format_htmlkey (key,nof); char opt[30]; sprintf (opt,"size=%d maxlength=256",fwidth); html_defvar (password_mode ? "password" : "text",key,buf,opt); html_defvarcur (key,backup.get()); } } /* Add a string field to the dialog. */ PUBLIC FIELD_STRING *DIALOG::newf_str( const char *prompt, char *str, int maxsiz) { FIELD_STRING *s = new FIELD_STRING(prompt,str,maxsiz,true); add (s); return s; } /* Add an information field (write protect) */ PUBLIC void DIALOG::newf_info( const char *prompt, const char *str) { int len = strlen(str); FIELD_STRING *s = new FIELD_STRING(prompt,(char*)str,len,false); if (s != NULL) s->box.width = len; add (s); set_lastreadonly(); } /* Add a SSTRING field to the dialog. */ PUBLIC FIELD_SSTRING *DIALOG::newf_str( const char *prompt, SSTRING &str) { return newf_str (prompt,str,30); } /* Add a SSTRING field to the dialog. */ PUBLIC FIELD_SSTRING *DIALOG::newf_str( const char *prompt, SSTRING &str, int width) // Suggested field width (in character) { FIELD_SSTRING *s = new FIELD_SSTRING(prompt,str,width); add (s); return s; } /* Add a password field to the dialog. */ PUBLIC FIELD_PASSWORD *DIALOG::newf_pass( const char *prompt, SSTRING &str) { FIELD_PASSWORD *s = new FIELD_PASSWORD(prompt,str); add (s); return s; } PUBLIC VIRTUAL const char* FIELD::return_prompt() { return original_prompt; } PUBLIC VIRTUAL const char* FIELD::get_registry_key() { return regkey; } PUBLIC VIRTUAL void FIELD::set_registry_key(const char* key) { regkey = key; } /* Return the value of the field, usable by the registry */ PUBLIC const char* FIELD_STRING_BASE::get_registry_value() { // printf("FIELD_STRING_BASE\n"); return buf; } /* Record the value of the field from the registry value */ PUBLIC void FIELD_STRING_BASE::set_registry_value(const char* value) { strncpy (buf,value,size); buf[size] = '\0'; }