#include "diadef.h" #include "dialog.h" #include "internal.h" #include "../diajava/proto.h" #include class FIELD_TEXTBOX: public FIELD_STRING{ /*~PROTOBEG~ FIELD_TEXTBOX */ public: FIELD_TEXTBOX (const char *_prompt, const char *_buf); void drawtxt (WINDOW *dialog, int hoffset, int , int); void gui_draw (int , SSTRINGS&); void html_draw (int); int html_validate (int); /*~PROTOEND~ FIELD_TEXTBOX */ }; PUBLIC FIELD_TEXTBOX::FIELD_TEXTBOX( const char *_prompt, const char *_buf) : FIELD_STRING (_prompt,(char*)_buf,strlen(_buf),false) { // There is a hack here. // Normally FIELD_STRING is an editor and expect a writable buffer. // Given that this field is readonly, it is convenient for the caller // to pass temporary data. We know that FIELD_STRING will take a // copy into its edit buffer. When a field is readonly, FIELD_STRING // is smart enough not to write in the original buffer. // This is why we accept "const" buffer and cast it later readonly = 1; box.width = strlen(buf); if (box.width > 73) box.width = 73; } /* Draw one text string if its len > 0 */ static void textbox_drawif( char *start, char *instr, WINDOW *dialog, unsigned long attr) { if (start != instr){ char tmp = *instr; *instr = '\0'; wattrset(dialog, attr); waddstr (dialog,start); *instr = tmp; } } /* Draw only the input part of a field */ PUBLIC void FIELD_TEXTBOX::drawtxt (WINDOW *dialog, int hoffset, int, int) { int blank_start = 0; wmove(dialog, box.y,box.x); const int box_width = box.width; if (hoffset < size){ /* #Specification: textbox / underlining and highlit Text may contain underlining commands and highliting commands built using the backspace character. # Highlit : X^HX Underline: X^H_ # Also two escape commands are supported for highliting # escape [ 1 m escape [ 0 m # */ char *instr = buf; int offset = 0; while (*instr != '\0' && offset < hoffset){ if (*instr == 27 && instr[1] == '[' && (instr[2] == '0' || instr[2] == '1') && instr[3] == 'm'){ instr+= 3; offset -= 4; }else if (*instr == 8){ offset -= 2; instr++; } offset++; instr++; } char *start = instr; unsigned long attr = inputbox_attr; while (*instr != '\0' && blank_start < box_width){ if (*instr == 27 && instr[1] == '[' && (instr[2] == '0' || instr[2] == '1') && instr[3] == 'm'){ textbox_drawif (start,instr,dialog,attr); if (instr[2] == '1'){ attr = button_active_attr; }else{ attr = inputbox_attr; } instr += 3; start = instr+1; } if (instr[1] == 8){ textbox_drawif (start,instr,dialog,attr); if (instr[0] == '_'){ // Underline ... does not work wattrset(dialog, A_UNDERLINE); waddch (dialog,instr[2]); }else{ // Highlit wattrset(dialog, button_active_attr); waddch (dialog,instr[0]); } instr += 2; start = instr+1; } blank_start++; instr++; } textbox_drawif (start,instr,dialog,attr); } wattrset(dialog, inputbox_attr); for (int i=blank_start; i%s
%s
\n",prompt,buf); } PUBLIC int FIELD_TEXTBOX::html_validate (int ) { return 0; } PUBLIC void FIELD_TEXTBOX::gui_draw (int, SSTRINGS &) { char tmp[1000]; // Convert escape sequence for highliting to old mode with backspaces const char *instr = buf; bool overstrike = false; char *dst = tmp; while (*instr != '\0' && dst < tmp+sizeof(tmp)-3){ if (*instr == 27 && instr[1] == '[' && (instr[2] == '0' || instr[2] == '1') && instr[3] == 'm'){ overstrike = instr[2] == '1'; instr += 4; }else if (overstrike){ char carac = *instr++; *dst++ = carac; *dst++ = 8; *dst++ = carac; }else{ *dst++ = *instr++; } } *dst = '\0'; char tmp2[1000]; diagui_sendcmd (P_Richtext,"%s%s%s\n",diagui_quote(tmp,tmp2) ,guiparms.is_empty() ? "" : " $" ,guiparms.get()); } /* Expand tab character (8) and translate some others */ void textbox_expandtab( const char *src, char *dst, int maxsiz) { int pos = 0; while (*src != '\0' && pos < maxsiz){ char carac = *src++; if (carac == '\t'){ if (pos % 8 == 0){ pos++; *dst++ = ' '; } while (pos % 8){ pos++; *dst++ = ' '; } }else if (carac == 7){ // Some bullets placed by linuxdoc-sgml *dst++ = '-'; }else{ *dst++ = carac; pos++; } } *dst = '\0'; } PUBLIC DIALOG_TEXTBOX::DIALOG_TEXTBOX() { internal->hoffset = 0; } /* Interpret key for horizontally scrollable dialog return -1 if the key was not processed. */ PROTECTED int DIALOG::keymove_scroll (WINDOW *dialog, int key, int &nof) { int ret = 0; switch (key){ case 1: // ^A like emacs case KEY_HOME: if (internal->hoffset > 0){ internal->hoffset = 0; drawf (dialog); } break; case 2: // ^B like emacs case KEY_LEFT: if (internal->hoffset > 0){ internal->hoffset--; drawf (dialog); } break; case 6: // ^F like emacs case KEY_RIGHT: internal->hoffset++; drawf (dialog); break; default: ret = -1; } return ret; } PROTECTED int DIALOG_TEXTBOX::keymove (WINDOW *dialog, int key, int &nof) { int ret = keymove_scroll(dialog,key,nof); if (ret == -1){ ret = 0; switch (key){ case KEY_DOWN: // Force a scroll nof = internal->offset + internal->nbvisible-1; ret = DIALOG::keymove (dialog,key,nof); nof = internal->offset; break; case KEY_UP: // Force a scroll nof = internal->offset; default: ret = DIALOG::keymove (dialog,key,nof); } } return ret; } /* Add a non editable field to a dialog Normally a dialog will contain only fields of this type. This is used to display helps and textual reports. */ PUBLIC void DIALOG_TEXTBOX::newf_text (const char *prompt,const char *buftab) { add (new FIELD_TEXTBOX(prompt,buftab)); } /* Add many non editable field to a textbox Normally a dialog will contain only fields of this type. This is used to display helps and textual reports. */ PUBLIC void DIALOG_TEXTBOX::newf_text ( const char *, // prompt const SSTRINGS &strs) { for (int i=0; icopy (buf); str_strip (buf,buf); char buftab[600]; textbox_expandtab (buf,buftab,sizeof(buftab)-1); newf_text("",buftab); } // Add an empty line because the last line is always truncated // using linuxconf-gui. Don't know why newf_text("",""); } /* Display text from a file in a dialog box. */ EXPORT MENU_STATUS dialog_textbox( const char *title, const char *file, HELP_FILE &help) { FILE *fin = xconf_fopen (file,"r"); MENU_STATUS ret = MENU_ESCAPE; if (fin != NULL){ DIALOG_TEXTBOX dia; dia.set_formparms ("vtrigger=400"); dia.setcontext (""); char buf[300]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ str_strip (buf,buf); char buftab[600]; textbox_expandtab (buf,buftab,sizeof(buftab)-1); dia.newf_text("",buftab); } fclose (fin); int nof = 0; ret = dia.edit (title,NULL,help,nof,MENUBUT_QUIT); } return ret; } EXPORT MENU_STATUS dialog_textbox( const char *title, const char *file) { return dialog_textbox (title,file,help_nil); } /* Display text from a table of strings. */ EXPORT MENU_STATUS dialog_textbox( const char *title, const char *intro, HELP_FILE &help, const SSTRINGS &strs) { DIALOG_TEXTBOX dia; dia.set_formparms ("vtrigger=400"); dia.setcontext (""); dia.newf_text ("",strs); dia.settype (DIATYPE_POPUP); int nof = 0; return dia.edit (title,intro,help,nof,MENUBUT_QUIT); } /* Display text from a table of strings. */ EXPORT MENU_STATUS dialog_textbox( const char *title, const SSTRINGS &strs) { return dialog_textbox (title,NULL,help_nil,strs); } #ifdef TEST int main (int argc, char *argv[]) { int ret; init_dialog(); ret = dialog_textbox("file /tmp/toto.c" ,"/tmp/toto.c" ,15,50); endwin(); printf ("ret = %d\n",ret); return 0; } #endif