#include "diawxxt.h" PRIVATE void FORMBASE::init(FORMBASE *_parent, const char *_id) { tbc = (MFORM_C**) malloc (400 * sizeof(MFORM_C*)); maxtbc = 400; nbc = 0; f_parent = _parent; id = strdup(_id); modified = true; stretch_mode = STRETCH_NONE; //setFont(new Font("Helvetica", Font.PLAIN, 14)); pref_width = pref_height = -1; logicaltop = false; fixed.x = rem_getvarval("x"); fixed.y = rem_getvarval("y"); fixed.w = rem_getvarval("w"); fixed.h = rem_getvarval("h"); max_width = 10000; max_height = 10000; doc_height = -1; doc_width = -1; voffset = 0; hoffset = 0; layout_once = false; vscroll = NULL; hscroll = NULL; background.brush = brush_back; background.pen = pen_back; } PUBLIC FORMBASE::FORMBASE(FORMBASE *_parent, const char *_id) : wxPanel (_parent) { init (_parent,_id); } PUBLIC FORMBASE::FORMBASE(const char *_id) { init (NULL,_id); } PUBLIC void FORMBASE::delall() { pref_width = pref_height = -1; for (int i=0; itype == T_FORM && (MFORM*)c->c == fl){ delete fl; delete c; }else{ tbc[pos] = tbc[i]; pos++; } } nbc = pos; } PUBLIC FORMBASE::~FORMBASE() { delall(); free (tbc); free (id); delete hscroll; delete vscroll; } // Compute the path of a form, by appending the IDs of the parents void formbase_getabspath(FORMBASE *p, char *path) { if (!p->logicaltop && p->f_parent != NULL){ formbase_getabspath(p->f_parent,path); if (p->id[0] != '\0'){ strcat (path,"."); strcat (path,p->id); } }else{ strcpy (path,p->id); } } PUBLIC VIRTUAL bool FORMBASE::may_stretch() { return stretch_mode != STRETCH_NONE; } PUBLIC VIRTUAL void FORMBASE::stretch ( int, // new_width int) // new_height { } PUBLIC bool FORMBASE::was_modified() { return modified; } PUBLIC VIRTUAL void FORMBASE::set_modified() { modified = true; if (f_parent != NULL) f_parent->set_modified(); } // Display the current value of each field of the dialog PUBLIC VIRTUAL void FORMBASE::dump() { for (int i=0; itype; if (type == T_FORM || type == T_SHEET || type == T_BOOK){ MFORM *m = (MFORM*)c->c; m->dump(); }else if (type == T_TEXT){ wxMultiText *w = (wxMultiText*)c->c; char path[300]; formbase_getabspath(this,path); const char *pt = w->GetValue(); while (*pt != '\0'){ char line[1000]; char *dst = line; while (*pt != '\n' && *pt != '\0' && (unsigned)(dst-line)id,line); if (*pt == '\n') pt++; } }else if (type != T_UNKNOWN && type != T_BUTTON && type != T_BUTTONXPM && type != T_SKIP && type != T_ICON && type != T_NEWLINE && type != T_HLINE && type != T_VLINE && type != T_FILL && type != T_LABEL && type != T_RICHTEXT && type != T_CLIST && type != T_GAUGE && type != T_BUTTONFILL){ const char *val = ""; char tmp[100]; if (type == T_STRING){ val = ((wxText*)c->c)->GetValue(); }else if (type == T_CHECKBOX){ val = ((wxCheckBox*)c->c)->GetValue() ? "1" : "0"; }else if (type == T_SLIDER){ int numval = ((wxSlider*)c->c)->GetValue(); sprintf (tmp,"%d",numval); val = tmp; }else if (type == T_RADIO){ CHECKBOX_RADIO *radio = c->radio; if (radio->state){ sprintf (tmp,"%d",radio->instance); val = tmp; }else{ continue; } }else if (type == T_COMBO){ val = ((COMBO*)c->c)->getText(); }else if (type == T_LIST){ int sel = ((wxListBox*)c->c)->GetSelection(); val = ((wxListBox*)c->c)->GetString(sel); }else{ fprintf (stderr,"code dump %d\n",c->type); } char path[300]; formbase_getabspath(this,path); fprintf (mform_fout,"dump %s %s %s\n",path,c->id,val); } } } // Set the value of a field from its ID PUBLIC VIRTUAL void FORMBASE::setval( const char *id, const char *vals[], SETVAL_INFO &info) { for (int i=0; itype; if (type == T_FORM || type == T_SHEET || type == T_BOOK){ FORMBASE *m = (FORMBASE*)c->c; m->setval(id,vals,info); }else if (strcmp(c->id,id)==0){ const char *val = vals[0]; if (type == T_CLIST){ CLIST *l = (CLIST*)c->c; l->Set_item (val,vals+1); }else if (type == T_TEXT){ info.tarea = (wxMultiText*)c->c; if (strcmp(val,"reset")==0){ info.tarea->SetValue(""); } info.initbuf(); }else if (type == T_COMBO){ ((COMBO*)c->c)->setText ((char*)val); }else if (type == T_STRING){ ((wxText*)c->c)->SetValue((char*)val); }else if (type == T_CHECKBOX){ ((wxCheckBox*)c->c)->SetValue(strcmp(val,"1")==0 ? 1 : 0); }else if (type == T_SLIDER){ ((wxSlider*)c->c)->SetValue(atoi(val)); }else if (type == T_GAUGE){ ((wxGauge*)c->c)->SetValue(atoi(val)); }else if (type == T_RADIO){ CHECKBOX_RADIO *radio = c->radio; radio->state = radio->instance == atoi(val); drawitems (i,i+1,false); }else if (type == T_COMBO){ ((COMBO*)c->c)->setText(val); }else if (type == T_LABEL){ c->sets (val); DCNAME *dcn = defs_getvardc (); if (dcn != NULL) c->dcn = dcn; drawitems (i,i+1,true); }else if (type == T_LIST){ wxListBox *l = (wxListBox*)c->c; for (int j=0; jNumber(); j++){ const char *s = l->GetString(j); if (strcmp(s,val)==0){ l->SetSelection(j); break; } } }else if (type == T_BUTTON){ wxButton *b = (wxButton*)c->c; b->SetLabel ((char*)val); }else if (type == T_BUTTONXPM){ wxButton *b = (wxButton*)c->c; wxBitmap *bitmap = icon_xpm_locate(val); if (bitmap != NULL){ b->SetLabel (bitmap); } }else{ fprintf (stderr,"setval unknown type %d\n",type); } } } } PUBLIC wxFrame *FORMBASE::getframe() { return gettop()->getframe(); } /* Return the parent of a form */ PUBLIC FORMBASE *FORMBASE::getparent() { return f_parent; } /* Return the TOP MAINFORM owning this FORM */ PUBLIC MAINFORM *FORMBASE::gettop() { MAINFORM *ret = NULL; if (istop()){ ret = (MAINFORM*)this; }else{ ret = f_parent->gettop(); } return ret; } /* Return true if this form is the top level (is a MAINFORM in fact) */ PUBLIC bool FORMBASE::istop() { return f_parent == NULL; } /* Return the logical TOP FORM owning this FORM */ PUBLIC FORMBASE *FORMBASE::getlogicaltop() { FORMBASE *ret = NULL; if (f_parent == NULL || logicaltop){ ret = this; }else{ ret = f_parent->getlogicaltop(); } return ret; } PUBLIC VIRTUAL void FORMBASE::dolayout(int, int,bool) { } PUBLIC VIRTUAL void FORMBASE::resizeitems (int, int) { } PUBLIC VIRTUAL void FORMBASE::getweight (int &w, int &h) { w = 0; h = 0; } PUBLIC VIRTUAL bool FORMBASE::doalllayout() { bool ret = false; int nb = nbc; if (max_height == 10000 && max_width == 10000){ // Figure out auto-scroll triggers bool autolimit = true; for (int i=0; itype == T_FORM || c->type == T_TEXT || c->type == T_CLIST || c->type == T_SHEET || c->type == T_BOOK){ autolimit = false; break; } } if (autolimit){ max_height = 200; max_width = 600; } } for (int i=0; itype == T_FORM || c->type == T_COMBO || c->type == T_CLIST || c->type == T_SHEET || c->type == T_BOOK){ FORMBASE *b = (FORMBASE*)c->c; if (b->doalllayout()) ret = true; if (c->weightx ==0 && c->weighty == 0){ b->getweight(c->weightx,c->weighty); } } } if (!gettop()->was_resized() || !layout_once || ret){ dolayout(max_width,max_height,false); } if (pref_width == -1) GetSize (&pref_width,&pref_height); return ret; } PUBLIC void FORMBASE::resetlayout() { pref_width = -1; } /* Locate a sub-form or notebook object in a form using its ID Return -1 if not found */ PUBLIC int FORMBASE::locate(const char *id, MFORM *&form, BOOK *&book) { int ret = -1; int nb = nbc; form = NULL; book = NULL; for (int i=0; itype; if (type == T_FORM || type == T_BOOK || type == T_CLIST){ FORMBASE *b = (FORMBASE*)c->c; if (strcmp(b->id,id)==0){ if (type == T_FORM || type == T_CLIST){ form = (MFORM*)b; }else{ book = (BOOK*)b; } ret = 0; break; } } } return ret; } PUBLIC MFORM_C *FORMBASE::alloc_mf(const char *_id) { set_modified(); MFORM_C *m = new MFORM_C(_id); if (nbc == maxtbc){ maxtbc += 400; tbc = (MFORM_C**)realloc(tbc,maxtbc*sizeof(MFORM_C*)); } tbc[nbc++] = m; return m; } PUBLIC MFORM_C *FORMBASE::alloc_mf() { return alloc_mf(""); } /* Give focus to a specific field of this form. Return -1 if the form did not contain the proper field */ PUBLIC VIRTUAL int FORMBASE::setcurfield ( const char *, wxWindow *[], int &) { return -1; } /* Give focus to a specific field of this form. Return -1 if the form did not contain the proper field */ PUBLIC int MFORM::setcurfield ( const char *id_suffix, wxWindow *tbfocus[], int &nbfocus) { /* #Specification: setcurfield / strategy The setcurfield assume that the ID of field which may accept focus has this form # A single letter following by a suffix. Generally the suffix is the internal field number used by Linuxconf. For a text field (New_string()), this is S20 for example. When remadmin receive a Curfield command, it identify the proper MAINFORM and then lookup the proper ID in the various fields and sub-form. One the field is identify, proper action is done to make it visible if needed. */ int ret = -1; #if 0 fprintf (stderr,"MFORM %s curfield %d :%s:\n",id,nbc,id_suffix); #endif for (int i=0; ic; const char *id = c->id; // fprintf (stderr,"cmp id :%s: %d %p\n",id,c->type,cc); if ((c->type == T_BUTTONFILL || cc != NULL) && c->type != T_BUTTON && c->type != T_BUTTONXPM && id != NULL && id[0] != '\0' && strcmp(id,id_suffix)==0){ #if 0 fprintf (stderr,"%s %s\n",id,id_suffix); #endif if (cc != NULL) tbfocus[nbfocus++] = cc; ret = 0; }else if (c->type == T_FORM || c->type == T_BOOK || c->type == T_CLIST){ FORMBASE *b = (FORMBASE*)cc; ret = b->setcurfield (id_suffix,tbfocus,nbfocus); } if (ret == 0){ int ww,wh; GetSize (&ww,&wh); int fx,fy,fw,fh; if (cc != NULL){ cc->GetPosition (&fx,&fy); cc->GetSize (&fw,&fh); }else{ fx = c->x; fy = c->y; fw = c->pref_width; fh = c->pref_height; } if (fy < 0 || fy + fh > wh){ vmoveitems(voffset + fy); } break; } } if (ret == 0) tbfocus[nbfocus++] = this; return ret; } /* Give focus to a specific field of this form. Return -1 if the form did not contain the proper field */ PUBLIC int BOOK::setcurfield ( const char *id_suffix, wxWindow *tbfocus[], int &nbfocus) { int ret = -1; #if 0 extern FILE *ftty; fprintf (ftty,"BOOK %s curfield %d %s\n",id,nbc,id_suffix); fflush (ftty); #endif for (int i=0; ic; #if 0 fprintf (ftty,"book %d m=%p\n",i,m); fflush (ftty); #endif ret = m->setcurfield (id_suffix,tbfocus,nbfocus); #if 0 fprintf (ftty,"book %d m=%p ret=%d\n",i,m,ret); fflush (ftty); #endif if (ret == 0){ selpage (i,NULL); break; } } if (ret == 0) tbfocus[nbfocus++] = this; return ret; } /* We walk recursivly to change the state of all CHECKBOX_RADIO sharing the same id. Only one will be left "on". */ PUBLIC void FORMBASE::processradio (MFORM_C *csel) { for (int i=0; itype == T_FORM || c->type == T_BOOK){ FORMBASE *b = (FORMBASE*)c->c; b->processradio (csel); }else if (c->type == T_RADIO){ if (strcmp(csel->id,c->id)==0){ bool newstate = csel == c; #if 0 c->c->SetValue (newstate); #else c->radio->state = newstate; drawradio_but (c); #endif } } } } /* Draw only the button part of the radio button */ PUBLIC void FORMBASE::drawradio_but (MFORM_C *c) { int x= c->x; int y= c->y; bool state = c->radio->state; const int nbpix=5; int x0 = x+1; int x1 = x+1+nbpix; int x2 = x+1+2*nbpix; int y0 = y+4; int y1 = y+4+nbpix; int y2 = y+4+2*nbpix; dc->SetPen (state ? pen_black : pen_white); dc->DrawLine (x0,y1,x1,y0); dc->DrawLine (x0+1,y1,x1,y0+1); dc->DrawLine (x1,y0,x2,y1); dc->DrawLine (x1,y0+1,x2-1,y1); dc->SetPen (state ? pen_white : pen_black); y1++; dc->DrawLine (x0,y1,x1,y2); dc->DrawLine (x0+1,y1,x1,y2-1); dc->DrawLine (x1,y2,x2,y1); dc->DrawLine (x1,y2-1,x2-1,y1); } /* Delete all the childs of this form */ PUBLIC void FORMBASE::delchild() { for (int i=0; itype == T_FORM || c->type == T_BOOK){ FORMBASE *b = (FORMBASE*)c->c; delete b; } delete c; } nbc = 0; } PUBLIC void FORMBASE::SetSize (int x, int y, int new_width, int new_height) { int w,h; GetSize (&w,&h); if (new_height == -1) new_height = h; if (new_width == -1) new_width = w; if (x != -1 || y != -1 || new_width != w || new_height != h){ // fprintf (stderr,"FORMBASE::SetSize :%s: %d %d %d %d <> %d %d\n" // ,id,x,y,new_width,new_height,w,h); wxPanel::SetSize (x,y,new_width,new_height); } } PUBLIC void FORMBASE::SetSize (int new_width, int new_height) { SetSize (-1,-1,new_width,new_height); }