Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

ndk++.cc

Go to the documentation of this file.
00001 // * This makes emacs happy -*-Mode: C++;-*-
00002 /****************************************************************************
00003  * Copyright (c) 2002 Fabrica de Software XXI SRL - info@lafabrica.com.ar   *
00004  * Copyright (c) 2002 RaqLink SA - info@raqlink.com                         *
00005  *                                                                          *
00006  * Permission is hereby granted, free of charge, to any person obtaining a  *
00007  * copy of this software and associated documentation files (the            *
00008  * "Software"), to deal in the Software without restriction, including      *
00009  * without limitation the rights to use, copy, modify, merge, publish,      *
00010  * distribute, distribute with modifications, sublicense, and/or sell       *
00011  * copies of the Software, and to permit persons to whom the Software is    *
00012  * furnished to do so, subject to the following conditions:                 *
00013  *                                                                          *
00014  * The above copyright notice and this permission notice shall be included  *
00015  * in all copies or substantial portions of the Software.                   *
00016  *                                                                          *
00017  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
00018  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
00020  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
00021  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
00022  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
00023  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
00024  *                                                                          *
00025  * Except as contained in this notice, the name(s) of the above copyright   *
00026  * holders shall not be used in advertising or otherwise to promote the     *
00027  * sale, use or other dealings in this Software without prior written       *
00028  * authorization.                                                           *
00029  ****************************************************************************/
00030 
00031 /****************************************************************************
00032  *  Author Miguel Pinkas <miguel@lafabrica.com.ar>                          *
00033  ****************************************************************************/
00034 #include "ndk++.h"
00035 
00036 using namespace std;
00037 
00038 namespace NDK_XX{
00039 
00040 ofstream logfile("NDK_debug");
00041 ofstream &get_logfile(){return logfile;}
00042 //-----------------------------------------------------------------------
00043 string NDKDialogBox::lblOk="  OK  ";
00044 string NDKDialogBox::lblCancel="Cancel";
00045 string NDKDialogBox::lblYes="  Yes ";   
00046 string NDKDialogBox::lblNo="  No  ";
00047 string NDKDialogBox::titDataChgd="Data changed!";
00048 string NDKDialogBox::msgAskToSave="Save before we exit?";
00049 
00050 
00051 
00052 //-----------------------------------------------------------------------
00053 NDKMenu::NDKMenu (  ListOfItems &items, 
00054                     int  lines,     int  cols, 
00055                     int  begin_y, int  begin_x,
00056                     bool framed,        // Reserve space for a frame?
00057                     bool own_items)  // Autocleanup of Items?
00058     : NCursesMenu(items.begin()
00059         ,lines,cols
00060         ,begin_y,begin_x
00061         ,framed,own_items),have_frame(framed) 
00062 {
00063     link_items(items);
00064 }
00065 
00066 
00067 //-----------------------------------------------------------------------
00068 NDKMenu::NDKMenu( int  lines, int  cols, int  begin_y, int  begin_x
00069                     ,bool framed)
00070     : NCursesMenu(lines,cols,begin_y,begin_x),have_frame(framed) 
00071 {
00072 }
00073 
00074 
00075 //-----------------------------------------------------------------------
00076 void NDKMenu::link_items(ListOfItems &items)
00077 {
00078     ListOfItems::const_iterator it;
00079     for(it = items.begin(); it !=items.end();it++){
00080         NDKMenuItem *pItem = dynamic_cast<NDKMenuItem *>(*it);
00081         if(!pItem)
00082             throw NDKDlgException<NDKMenu>(this,"No item or wrong item type"
00083                                     " in NDKMenu::link_items");
00084         pItem->pMenu = this;
00085     }
00086 }
00087 
00088 
00089 //-----------------------------------------------------------------------
00090 void NDKMenu::lefttext(int row,const char *label) {
00091   if (label) {
00092     OnError(addstr(row, 0, label, width()));
00093   }
00094 }
00095 
00096 
00097 //-----------------------------------------------------------------------
00098 void NDKMenu::righttext(int row,const char *label) {
00099   if (label) {
00100     int x = maxx() - strlen(label);
00101     if (x<0)
00102       x=0;
00103     OnError(addstr(row, x, label, width()));
00104   }
00105 }
00106 
00107 
00108 /************************************************************************
00109 *   class NDKMenuBar                                                    *
00110 ************************************************************************/
00111 //-----------------------------------------------------------------------
00112 void NDKMenuBar::show_text(const string &t,char where){
00113     if (!t.empty()){
00114         switch(where){
00115             case 'l': lefttext(0,t.c_str()); break;
00116             case 'c': centertext(0,t.c_str()); break;
00117             case 'r': righttext(0,t.c_str()); break;
00118             default: centertext(0,t.c_str()); break;
00119         }
00120     }
00121 }
00122 
00123 
00124 //-----------------------------------------------------------------------
00125 NDKMenuBar::NDKMenuBar (int rows, int cols,int y, int x
00126                     ,ListOfItems &items
00127                     ,const char *ttitle, const char *btitle
00128                     ,const char *title_pos
00129                     ,char orient,bool framed)
00130     :   NDKMenu(rows, cols, y, x,framed)
00131         ,orientation(orient)
00132         ,title(ttitle),bTitle(btitle),titlePos(title_pos)
00133         ,itemList(items)
00134 {
00135     
00136     short count = items.size()-1;
00137     
00138     if(orientation=='v')  set_format(count,1);
00139     else set_format(1,count);
00140 
00141     InitMenu(items);
00142     
00143     link_items(items);
00144     
00145     if(framed)
00146         frame();
00147 
00148     //by default it's 2, but user may be clever enough to pass in "" ...
00149     while(titlePos.size()< 2)
00150         titlePos+='c';
00151 
00152     setTitle();
00153 }
00154 
00155 
00156 /************************************************************************
00157 *   class NDKSubMenu                                                *
00158 ************************************************************************/
00159 //-----------------------------------------------------------------------
00160 void NDKSubMenu::setItems(ListOfItems &items) 
00161 {
00162     NDKMenuItem *pItem = dynamic_cast<NDKMenuItem *>(items[0]);
00163     ListOfItems::iterator it;
00164     if(pItem->get_menu())
00165         NDKMenu::setItems(items);
00166     else 
00167         InitMenu(items);
00168     refresh();
00169 }
00170     
00171 
00172 /************************************************************************
00173 *   class NDKPopUpMenu                                              *
00174 ************************************************************************/
00175 //-----------------------------------------------------------------------
00176 NDKPopUpMenu::~NDKPopUpMenu(){ 
00177     //logfile << "Pop up\t" << name() << endl;
00178     ListOfItems::iterator it;
00179     for(it=items.begin();it!=items.end();it++){
00180         delete *it;
00181     }
00182     
00183 }  
00184     
00185 
00186 //-----------------------------------------------------------------------
00187 bool NDKPopUpMenu::action() {
00188     NDKSubMenu S(items.size()-1,largest_name_len()
00189                     ,submenuy(),submenux(),items,sub_menu_label.c_str());
00190     S();
00191     return FALSE; 
00192 }
00193     
00194 
00195 //-----------------------------------------------------------------------
00196 short NDKPopUpMenu::submenux() const{
00197     // default x position: right where the itemīs label is shown 
00198     // (this works wether we have a normal curses menu 
00199     // or a menu bar with h layout
00200     short x = pMenu->begx()
00201             + pMenu->get_itemmarklen() 
00202             + pMenu->is_framed();
00203     
00204     NDKMenuBar *pParent = dynamic_cast<NDKMenuBar *>(pMenu);
00205     if(pParent && pParent->get_orientation() == 'h')
00206         x += (index() * pMenu->get_itemwidth());
00207 
00208     return x;
00209 }
00210 
00211 
00212 //-----------------------------------------------------------------------
00213 short NDKPopUpMenu::submenuy()const{
00214     short y = pMenu->begy() + pMenu->is_framed();
00215 
00216     NDKMenuBar *pParent = dynamic_cast<NDKMenuBar *>(pMenu);
00217     if(pParent && pParent->get_orientation() == 'v'){
00218         y += index();
00219     }
00220     return y;
00221 }
00222 
00223         
00224 //-----------------------------------------------------------------------
00225 int NDKPopUpMenu::largest_name_len()const{
00226     unsigned MaximumNameLength = 0;
00227     ListOfItems::const_iterator it;
00228     for(it = items.begin(); it !=items.end();it++){
00229         NDKMenuItem *pItem = dynamic_cast<NDKMenuItem *>(*it);
00230         ITEM *item = pItem->get_curses_item();
00231         if (item && item->name.length > MaximumNameLength ){
00232             MaximumNameLength  = item->name.length;
00233         }
00234     }
00235     if(sub_menu_label.size() > MaximumNameLength)
00236         MaximumNameLength = sub_menu_label.size();
00237     return MaximumNameLength;
00238 }
00239 
00240 
00241 /************************************************************************
00242 *   class NDKDlgControl                                             *
00243 ************************************************************************/
00244 //-----------------------------------------------------------------------
00245 BEGIN_FIRST_BINDINGS(NDKDlgControl)
00246 //  ON_NOTIFY_RANGE(LI_SEL_CHANGE,0,0xffff,NDKDlgControl::on_sel_change)
00247 END_BINDINGS()
00248 
00249 
00250 ofstream &NDKDlgControl::send_to_log(const string &what)
00251 {
00252     logfile << what;
00253     return logfile;
00254 }
00255 
00256 
00257 //-----------------------------------------------------------------------
00258 bool NDKDlgControl::process_message(NDKDlgControl *pTarget,int what
00259                                             , int ctrl_id, void* pExtra)
00260 {
00261     const BINDING_MAP* binding_map;
00262     const BINDING* pEntry;
00263 
00264     for (binding_map = pTarget->get_binding_map(); binding_map != 0;
00265       binding_map = binding_map->base_map)
00266     {
00267         assert(bindings_map != binding_map->base_map);
00268 
00269         pEntry = get_binding(binding_map->pEntries, what, ctrl_id);
00270         if (pEntry)
00271         {   
00272             if(what==0)
00273             (pTarget->*pEntry->p_cmd_fn)(); 
00274             else// found it
00275             (pTarget->*pEntry->p_notif_fn)(ctrl_id); 
00276             return true;
00277         }
00278     }
00279     return false;   // not handled
00280 }
00281 
00282 
00283 //-----------------------------------------------------------------------
00284 const BINDING* NDKDlgControl::get_binding(const BINDING* pEntry,int what, int ctrl_id)
00285 {
00286     // C version of search routine
00287     while (pEntry->pfn())
00288     {
00289         if (pEntry->what == what &&
00290             ctrl_id >= pEntry->ctrl_id && ctrl_id <= pEntry->last_ctrl_id){
00291             return pEntry;
00292         }
00293         pEntry++;
00294     }
00295     return 0;    // not found
00296 }
00297 
00298 
00299 //-----------------------------------------------------------------------
00300 NDKDlgControl::styles 
00301 NDKDlgControl::set_styles(NDKDlgControl::styles s)
00302 { 
00303     int old_style=field_style;
00304     field_style=s;
00305     return styles(old_style);
00306 }
00307     
00308 
00309 //-----------------------------------------------------------------------
00310 NDKDlgControl::styles 
00311 NDKDlgControl::set_style(NDKDlgControl::styles s,bool on)
00312 { 
00313     int old_style=field_style;
00314     if (on) field_style|=s;
00315     else    field_style&=~s;
00316     return styles(old_style);
00317 }  
00318 
00319 
00320 //-----------------------------------------------------------------------
00321 NDKDlgControl::states 
00322 NDKDlgControl::set_states(NDKDlgControl::states s)
00323 { 
00324     int old_state=field_state;
00325     field_state=s;
00326     return states(old_state);
00327 }
00328     
00329 
00330 //-----------------------------------------------------------------------
00331 NDKDlgControl::states 
00332 NDKDlgControl::set_state(NDKDlgControl::states s,bool on)
00333 { 
00334     int old_state=field_state;
00335     if (on) field_state|=s;
00336     else    field_state&=~s;
00337     return states(old_state);
00338 }  
00339 
00340 
00341 //-----------------------------------------------------------------------
00342 int NDKDlgControl::mvwin(int y, int x)
00343 {
00344     if(!is_moveable())
00345         return E_REQUEST_DENIED;
00346         
00347     int result=0;
00348     int new_x=begx()+x;
00349     int new_y=begy()+y;
00350     
00351     if( new_x > pParent->begx() 
00352         && new_x+ width() <= pParent->begx()+pParent->maxx() 
00353         && new_y > pParent->begy() 
00354         && new_y+ height() <= pParent->begy()+pParent->maxy()
00355     ){
00356         result = NCursesPanel::mvwin(new_y,new_x);
00357         if(result==OK){
00358             w->_begx = new_x;
00359             w->_begy = new_y;
00360             refresh();
00361         }
00362     }
00363     return result;
00364 }
00365 
00366         
00367 //-----------------------------------------------------------------------
00368 void NDKDlgControl::activate()
00369 {
00370     top();
00371     set_state(active);
00372     if(has_frame()){
00373         attron(A_BOLD);
00374         box();
00375         attroff(A_BOLD);
00376         refresh();
00377     }
00378 }
00379 
00380 
00381 //-----------------------------------------------------------------------
00382 void NDKDlgControl::deactivate()
00383 {
00384     set_state(active,false);
00385     if(has_frame()){
00386         attroff(A_BOLD);
00387         box();
00388         refresh();
00389     }
00390 }
00391 
00392 
00393 /************************************************************************
00394 *   class NDKDlgLabel                                               *
00395 ************************************************************************/
00396 //-----------------------------------------------------------------------
00397 NDKDlgLabel::NDKDlgLabel( NDKDlgControl *parent
00398                                 ,int id, const string &title
00399                                 ,int lines,int cols,int y, int x
00400                                 ,int style)
00401     : NDKDlgControl(parent,id,lines,cols,y,x,style)
00402         ,text(title)
00403         ,pos_x(0),pos_y(0)
00404         ,viewport(this)
00405         ,cur_x(0),cur_y(0),x_start(0)
00406 {
00407     on_initial_update=true;
00408     if(has_frame()){
00409         viewport = new NCursesWindow(*this);
00410         pos_x++; 
00411         pos_y++; 
00412     }
00413     set_text(title);
00414     on_initial_update=false;
00415 }
00416 
00417 
00418 //-----------------------------------------------------------------------
00419 NDKDlgLabel::NDKDlgLabel( int id, const string &title
00420                                 ,int lines,int cols,int y, int x
00421                                 ,int style)
00422     : NDKDlgControl(id,lines,cols,y,x,style)
00423         ,text(title)
00424         ,pos_x(0),pos_y(0)
00425         ,viewport(this)
00426         ,cur_x(0),cur_y(0)
00427 {
00428     on_initial_update=true;
00429     if(has_frame()){
00430         viewport = new NCursesWindow(*this);
00431         pos_x++; 
00432         pos_y++; 
00433     }
00434     set_text(title);
00435     on_initial_update=false;
00436 }
00437 
00438 
00439 //-----------------------------------------------------------------------
00440 void NDKDlgLabel::set_text(const string &v)
00441 {
00442     string old_text= text;
00443     text = v;
00444 
00445     clear_text();
00446     viewport->addstr(cur_y,cur_x, text.c_str(), max_len());
00447     viewport->move(cur_y,cur_x);
00448     viewport->cursyncup();
00449     viewport->refresh();
00450     
00451     if(old_text!=text && notify_enabled()){
00452         process_message(pParent,TXT_CHANGED,get_ctrl_id(),0);
00453     }
00454 }
00455     
00456     
00457 //-----------------------------------------------------------------------
00458 int NDKDlgLabel::driver(int key)
00459 {
00460     switch(key) {
00461         case KEY_UP:    mvwin(-1,0);    return TRUE;
00462         case KEY_DOWN:  mvwin(1,0);     return TRUE;
00463         case KEY_LEFT:  mvwin(0,-1);    return TRUE;
00464         case KEY_RIGHT: mvwin(0,1);     return TRUE;
00465         default:                    break;
00466     }
00467     return FALSE;
00468 }
00469 
00470 
00471 //-----------------------------------------------------------------------
00472 void NDKDlgLabel::activate()
00473 {
00474     NDKDlgControl::activate();
00475     if(!has_frame()){
00476         viewport->addch(cur_y,cur_x,text[0]|A_BOLD|A_UNDERLINE);
00477         viewport->move(cur_y,cur_x);
00478         viewport->cursyncup();
00479         viewport->refresh();
00480     }
00481 }
00482 
00483 
00484 //-----------------------------------------------------------------------
00485 void NDKDlgLabel::deactivate()
00486 {
00487     NDKDlgControl::deactivate();
00488     if(!has_frame()){
00489         viewport->addch(cur_y,cur_x,text[0]);
00490         viewport->move(cur_y,cur_x);
00491         viewport->cursyncup();
00492         viewport->refresh();
00493     }
00494 }
00495 
00496 
00497 //-----------------------------------------------------------------------
00498 void NDKDlgLabel::clear_text(bool ref=false)
00499 {
00500     for(cur_x=viewport->maxx();cur_x; cur_x--){
00501         viewport->addch(cur_y,cur_x,getbkgd());
00502     }
00503     viewport->addch(cur_y,cur_x,getbkgd());
00504 }
00505 
00506 
00507 /************************************************************************
00508 *   class NDKDlgButton                                              *
00509 ************************************************************************/
00510 //-----------------------------------------------------------------------
00511 NDKDlgButton::NDKDlgButton( NDKDlgControl *parent
00512                                 ,int id,const string &title
00513                                 ,int lines,int cols,int y, int x
00514                                 ,int style)
00515         :NDKDlgLabel(parent,id,title,lines,cols,y,x,style)
00516 {
00517 }
00518 
00519 
00520 //-----------------------------------------------------------------------
00521 int NDKDlgButton::driver(int key)
00522 {
00523     int result= FALSE;
00524     switch(key) {
00525         case 10:    result = action();  break;
00526         default:    result = NDKDlgLabel::driver(key); break; 
00527     }
00528     return result;
00529 }
00530 
00531 
00532 //-----------------------------------------------------------------------
00533 void NDKDlgButton::activate()
00534 {
00535     NDKDlgControl::activate();
00536     attron(A_BOLD);
00537     set_text(text);
00538     
00539 }
00540 
00541 
00542 //-----------------------------------------------------------------------
00543 void NDKDlgButton::deactivate()
00544 {
00545     NDKDlgControl::activate();
00546     attroff(A_BOLD);
00547     set_text(text);
00548 }
00549 
00550 
00551 /************************************************************************
00552 *   class NDKDlgPushButton                                              *
00553 ************************************************************************/
00554 //-----------------------------------------------------------------------
00555 NDKDlgPushButton::NDKDlgPushButton( NDKDlgControl *parent
00556                                 ,int id, const string &title
00557                                 ,int lines,int cols,int y, int x
00558                                 ,int style)
00559         :NDKDlgButton(parent,id, title,lines,cols,y,x,(style&=~framed))
00560 {
00561     on_initial_update=true;
00562     set_style(framed,true);
00563     set_text(text);
00564     on_initial_update=false;
00565 }
00566 
00567 
00568 //-----------------------------------------------------------------------
00569 NDKDlgPushButton::NDKDlgPushButton( NDKDlgControl *parent
00570                                 ,int id, const string &title
00571                                 ,int y, int x)
00572         :NDKDlgButton(parent,id,title,1,title.size()+3,y,x,tabstop|notify)
00573 {
00574     on_initial_update=true;
00575     set_style(framed,true);
00576     set_text(text);
00577     on_initial_update=false; 
00578 }
00579 
00580 
00581 //-----------------------------------------------------------------------
00582 void NDKDlgPushButton::set_text(const string &v)
00583 {
00584     int max_len = width()-pos_x-has_frame();
00585     string new_text= v.substr(0, max_len); 
00586     text = new_text;
00587     clrtoeol(); 
00588     centertext(0,text.c_str());
00589     if(has_frame()){
00590         addch(0,0, '[');
00591         addch(0,maxx(), ']');
00592     }
00593     move(0,0);
00594     refresh();
00595 }
00596     
00597     
00598 
00599 /************************************************************************
00600 *   class NDKDlgListItemData                                            *
00601 ************************************************************************/
00602 //----------------------------------------------------------------------//
00603 //      NDKDlgListItemData::operator=                                   //
00604 //                                                                      //
00605 //      copy from the visible item to the data buffer only gets         //
00606 //      the style and the state of the visible item, since we don't     //
00607 //      allow text or framing changes.                                  //
00608 //                                                                      //
00609 //----------------------------------------------------------------------//
00610 NDKDlgListItemData &
00611 NDKDlgListItemData::operator=(const NDKDlgListItem &rha)
00612 {
00613     set_styles(rha.get_style());
00614     set_states(rha.get_state());
00615     set_default(rha.is_default());
00616     return *this;
00617 }
00618 
00619 
00620 //-----------------------------------------------------------------------
00621 NDKDlgListItemData &
00622 NDKDlgListItemData::operator=(const NDKDlgListItemData &rha)
00623 {
00624     set_text(rha.get_text());
00625     set_ctrl_id(rha.get_ctrl_id());
00626     set_styles(rha.get_style());
00627     set_states(rha.get_state());
00628     set_default(rha.is_default());
00629     set_user_data(rha.get_user_data());
00630     return *this;
00631 }
00632 
00633 
00634 //-----------------------------------------------------------------------
00635 int
00636 NDKDlgListItemData::set_state(int s,bool on)
00637 { 
00638     int old_state=field_state;
00639     if (on) field_state|=s;
00640     else    field_state&=~s;
00641     return old_state;
00642 }  
00643 
00644 
00645 /************************************************************************
00646 *   class NDKDlgListItem                                                *
00647 ************************************************************************/
00648 //-----------------------------------------------------------------------
00649 NDKDlgListItem::NDKDlgListItem( NDKDlgControl *parent
00650                                 ,int id, const string &title
00651                                 ,int lines,int cols,int y, int x
00652                                 ,int style)
00653         :NDKDlgButton(parent,id, title,lines,cols,y,x,style),user_data(0)
00654 {
00655 }
00656 
00657 
00658 //-----------------------------------------------------------------------
00659 int NDKDlgListItem::driver(int key)
00660 {
00661     int result= FALSE;
00662     switch(key) {
00663         case KEY_ENTER: 
00664         case ' ': 
00665             set_check(!is_checked());  
00666             result=TRUE;
00667             break;
00668         default:
00669             break;
00670     }
00671     return result;
00672 }
00673 
00674 
00675 //-----------------------------------------------------------------------
00676 void NDKDlgListItem::set_text(const string &v)
00677 {
00678     string new_text= v; //.substr(0,width()); 
00679     text = new_text;
00680     clear_text();
00681     show_state();
00682     addstr(pos_y,state_size(),text.c_str(),width()-state_size());
00683     move(0,0);
00684     refresh();
00685 }
00686 
00687 
00688 //-----------------------------------------------------------------------
00689 NDKDlgListItem &NDKDlgListItem::operator=(const NDKDlgListItemData &rha)
00690 {
00691     set_text(rha.get_text());
00692     set_ctrl_id(rha.get_ctrl_id());
00693     set_styles(styles(rha.get_style()));
00694     set_states(states(rha.get_state()));
00695     set_default(rha.is_default());
00696     set_user_data(rha.get_user_data());
00697     return *this;
00698 }
00699 
00700 
00701 /************************************************************************
00702 *   class NDKDlgRadioButton                                             *
00703 ************************************************************************/
00704 //-----------------------------------------------------------------------
00705 NDKDlgRadioButton::NDKDlgRadioButton( NDKDlgControl *parent
00706                                 ,int id,const string &title
00707                                 ,int lines,int cols
00708                                 ,int y, int x,int style)
00709     :NDKDlgListItem(parent,id,title,lines,cols,y,x,style)
00710 {   
00711     on_initial_update=true;
00712     set_text(text);
00713     on_initial_update=false;
00714 }
00715 
00716 
00717 //-----------------------------------------------------------------------
00718 NDKDlgRadioButton::NDKDlgRadioButton( NDKDlgControl *parent
00719                                 ,int id, const string &title
00720                                 ,int y, int x)
00721     :NDKDlgListItem(parent,id,title,1,title.size()+4,y,x,tabstop|notify)
00722 {
00723     on_initial_update=true;
00724     set_text(text);
00725     on_initial_update=false;
00726 }
00727 
00728 
00729 /************************************************************************
00730 *   class NDKDlgCheckButton                                         *
00731 ************************************************************************/
00732 //-----------------------------------------------------------------------
00733 NDKDlgCheckButton::NDKDlgCheckButton( NDKDlgControl *parent
00734                                 ,int id,const string &title
00735                                 ,int lines,int cols
00736                                 ,int y, int x,int style)
00737         :NDKDlgListItem(parent,id,title,lines,cols,y,x,style)
00738 {
00739     on_initial_update=true;
00740     set_text(text);
00741     on_initial_update=false;
00742 }
00743 
00744 
00745 //-----------------------------------------------------------------------
00746 NDKDlgCheckButton::NDKDlgCheckButton( NDKDlgControl *parent
00747                                 ,int id,const string &title
00748                                 ,int y, int x)
00749     :NDKDlgListItem(parent,id,title,1,title.size()+4,y,x,tabstop|notify)
00750 {
00751     on_initial_update=true;
00752     set_text(text);
00753     on_initial_update=false;
00754 }
00755 
00756 
00757 /************************************************************************
00758 *   class NDKDlgEdit                                                *
00759 ************************************************************************/
00760 //-----------------------------------------------------------------------
00761 NDKDlgEdit::NDKDlgEdit( NDKDlgControl *parent
00762                                 ,int id,const string &title
00763                                 ,int lines,int cols,int y, int x
00764                                 ,int style)
00765         :NDKDlgLabel(parent,id,title,lines,cols,y,x,style)
00766 {
00767 }
00768 
00769 
00770 NDKDlgEdit::~NDKDlgEdit()
00771 {
00772     if(has_frame())
00773         delete viewport;
00774 }
00775 
00776 
00777 //-----------------------------------------------------------------------
00778 int NDKDlgEdit::driver(int key)
00779 {
00780     if(edit(key))
00781         return TRUE;
00782     return NDKDlgLabel::driver(key);
00783 }
00784 
00785 
00786 //-----------------------------------------------------------------------
00787 void NDKDlgEdit::add_char(int key)
00788 {
00789     text+=key;
00790     viewport->addch(cur_y,cur_x,key);
00791 }
00792 
00793 
00794 //-----------------------------------------------------------------------
00795 void NDKDlgEdit::insert_char(int key)
00796 {
00797     if(text.size()+1 < max_len()){
00798         text.insert(cur_x,1,(char)key);
00799         viewport->insch(cur_y,cur_x,key);
00800     }
00801 }
00802 
00803 
00804 //-----------------------------------------------------------------------
00805 int NDKDlgEdit::add_or_insert_char(int key)
00806 {
00807     if(!isprint(key))
00808         return FALSE;
00809         
00810     if(cur_x > -1 && cur_x < viewport->width()){
00811         if(overwrite())add_char(key);
00812         else insert_char(key);
00813         viewport->move(cur_y,++cur_x);
00814         viewport->cursyncup();
00815         viewport->refresh();
00816         if(notify_enabled())
00817             process_message(pParent,TXT_CHANGED,get_ctrl_id(),0);
00818     }
00819     return TRUE;
00820 }
00821 
00822 
00823 //-----------------------------------------------------------------------
00824 int NDKDlgEdit::edit(int key)
00825 {
00826 //  getyx(cur_y,cur_x);
00827 
00828     switch(key) {
00829         case KEY_BACKSPACE:
00830         case KEY_DC:
00831             if(cur_x){
00832                 text.erase(--cur_x,1);
00833                 viewport->delch(cur_y,cur_x);
00834                 viewport->move(cur_y,cur_x);
00835                 viewport->cursyncup();
00836                 viewport->refresh();
00837             }
00838             return TRUE;
00839         case KEY_LEFT:
00840             if(cur_x){
00841                 viewport->move(cur_y,--cur_x);
00842                 viewport->cursyncup();
00843                 viewport->refresh();
00844             }
00845             return TRUE;
00846         case KEY_RIGHT:
00847             if(cur_x < visible_size()){
00848                 viewport->move(cur_y,++cur_x);
00849                 viewport->cursyncup();
00850                 viewport->refresh();
00851             }
00852             return TRUE;
00853         default:
00854             if(add_or_insert_char(key)) 
00855                 return TRUE;
00856     }
00857     return FALSE;
00858 }
00859 
00860 
00861 /************************************************************************
00862 *   class NDKDlgListBox                                                 *
00863 ************************************************************************/
00864 //-----------------------------------------------------------------------
00865 
00866 NDKDlgListBox::NDKDlgListBox( NDKDlgControl *parent
00867                     ,int id,const string &title
00868                     ,int lines,int cols,int y, int x
00869                     ,int style)
00870         :NDKDlgControl( parent,id,lines,cols,y,x,style)
00871             ,pos_x(0), pos_y(0)
00872             ,curr_item(-1)
00873             ,top_item(-1)
00874             ,bottom_item(-1)
00875             ,cur_sel(-1)
00876 {
00877     on_initial_update=true;
00878     if(has_frame()){
00879         pos_x++; 
00880         pos_y++; 
00881     }
00882     set_text(title);
00883     draw_scrollbar();
00884     on_initial_update=false;
00885 }
00886 
00887 
00888 //-----------------------------------------------------------------------
00889 BEGIN_BINDINGS(NDKDlgListBox,NDKDlgControl)
00890     ON_NOTIFY_RANGE(LI_SEL_CHANGE,0,0xffff,NDKDlgListBox::on_sel_change)
00891 END_BINDINGS()
00892 
00893 
00894 //-----------------------------------------------------------------------
00895 
00896 NDKDlgListBox::~NDKDlgListBox()
00897 { 
00898     hide();
00899     VisibleItems::iterator it;
00900     for(it=items.begin();it!=items.end();it++){
00901 //      logfile << "Deleted Visible item " << (*(it))->get_text() << endl;
00902         delete *it;
00903     }
00904     
00905     delete_data();
00906 }
00907 
00908 
00909 //-----------------------------------------------------------------------
00910 void NDKDlgListBox::delete_data()
00911 {
00912     ListItems::iterator d;
00913     for(d=data.begin();d!=data.end();d++){
00914 //      logfile << "Deleted data item " << (*(d))->get_text() << endl;
00915         delete *d;
00916     }
00917 }
00918 
00919 
00920 //-----------------------------------------------------------------------
00921 void NDKDlgListBox::clear()
00922 {
00923     delete_data();
00924     data.clear();
00925     curr_item=top_item=bottom_item=0;
00926     refresh_items();
00927     show_empty();
00928     draw_scrollbar();
00929     refresh();
00930 }
00931 
00932 
00933 //-----------------------------------------------------------------------
00934 void NDKDlgListBox::show_empty()
00935 {
00936     if(data.empty()){
00937         cur_sel=-1;
00938         items[0]->set_text("Empty");
00939         items[0]->enable(false);
00940     }
00941 
00942 }
00943 
00944 
00945 //-----------------------------------------------------------------------
00946 void NDKDlgListBox::draw_scrollbar()
00947 {
00948     if(!has_vscrollbar())
00949         return;
00950     int i, row, col, h_len, v_len;
00951     int winheight=items.size();
00952     int dataheight = data.size();
00953     int top = ((top_item==-1)? 0:top_item);
00954 
00955     if(dataheight==0)
00956         dataheight = 1;
00957         
00958     v_len = (winheight*winheight + dataheight - 1)/dataheight;
00959     if (v_len==0)
00960       v_len = 1;
00961     if (v_len > winheight)
00962       v_len = winheight;
00963 
00964 
00965     row  = (top * winheight + dataheight - 1) / dataheight;
00966     if (row + v_len > winheight)
00967       row = winheight - v_len;
00968 
00969     vline(1,maxx(),winheight);
00970     attron(A_REVERSE);
00971     if (v_len>=2) {
00972       addch(row+1,maxx(),ACS_UARROW);
00973       for(i=2;i<v_len;i++)
00974         addch(row+i,maxx(),' ');
00975       addch(row+v_len,maxx(),ACS_DARROW);
00976     }
00977     else {
00978       for(i=1;i<=v_len;i++)
00979         addch(row+i,maxx(),' ');
00980     }
00981     attroff(A_REVERSE);
00982 }
00983 //-----------------------------------------------------------------------
00984 
00985 int NDKDlgListBox::add_item(const string &new_item,int pos
00986                                 ,bool is_default= false,bool make_visible)
00987 {
00988     NDKDlgListItemData *item=new NDKDlgListItemData(new_item,data.size());
00989     item->set_default(is_default);
00990     add_item(item,pos,make_visible);
00991 }
00992 
00993 
00994 //-----------------------------------------------------------------------
00995 
00996 int NDKDlgListBox::add_item(NDKDlgListItemData *new_item,int pos
00997                                                     ,bool make_visible)
00998 {
00999     int old_current = curr_item;
01000     ///by default, we insert at the end
01001     ListItems::iterator where=data.end();
01002     
01003     if(pos!=-1 ){
01004         if(pos >-1 && pos < data.size()){
01005             where=data.begin()+pos;
01006             if(make_visible){
01007                 curr_item=pos;
01008             }
01009         }
01010         else 
01011             throw 
01012                 NDKDlgException<NDKDlgListBox>(this
01013                                     ,"Position out of range in add_item");
01014     }
01015     else{
01016         if(data.empty()==false){/// if no data, curr_item already is 0
01017             if(make_visible){
01018                 curr_item++;
01019             }
01020         }
01021     }
01022     data.insert(where,new_item);
01023     adjust_top_and_bottom();
01024     draw_scrollbar();
01025     refresh();
01026 }
01027 
01028 
01029 //-----------------------------------------------------------------------
01030 
01031 int NDKDlgListBox::remove_item(int pos)
01032 {
01033     if(pos>=0 && pos < data.size()){
01034         data.erase(data.begin()+pos);
01035         if(pos<= curr_item && curr_item)
01036             curr_item--;
01037         if(cur_sel == pos)
01038             cur_sel = -1;
01039             
01040             
01041         logfile << "remove_item: cursel=" << cur_sel << endl;
01042         adjust_top_and_bottom();
01043         draw_scrollbar();
01044         show_empty();
01045         refresh();
01046     }
01047 };
01048 
01049 
01050 //-----------------------------------------------------------------------
01051 
01052 int NDKDlgListBox::refresh()
01053 {
01054     for( int idx=top_item;idx <= bottom_item; idx++){
01055         if(idx!=curr_item)
01056             deactivate_item(idx);
01057     }
01058     activate_item(curr_item);
01059 }
01060 
01061 
01062 //-----------------------------------------------------------------------
01063 
01064 void NDKDlgListBox::refresh_items()
01065 {
01066     for( int idx=top_item;idx <= bottom_item; idx++){
01067         update_item(idx);
01068     }
01069     clear_items();
01070 
01071 }
01072 
01073 
01074 //-----------------------------------------------------------------------
01075 void NDKDlgListBox::clear_items()
01076 {
01077     for( int idx=data.size()-top_item;idx <items.size(); idx++){
01078         items[idx]->set_text("");
01079     }
01080 }
01081 
01082 
01083 //-----------------------------------------------------------------------
01084 
01085 int NDKDlgListBox::driver (int key) 
01086 {
01087     if( data.size() 
01088         && curr_item!=-1 
01089         && visible_item(curr_item)->driver(key)==TRUE)
01090         return TRUE;
01091     switch(key) {
01092         case KEY_UP:    move_up();  return TRUE;
01093         case KEY_DOWN:  move_down();return TRUE;
01094         case KEY_LEFT:  move_left();return TRUE;
01095         case KEY_RIGHT: move_right();return TRUE;
01096         default: break;
01097     }
01098     return FALSE;
01099 }
01100 
01101 
01102 //-----------------------------------------------------------------------
01103 
01104 void NDKDlgListBox::adjust_top_and_bottom()
01105 {
01106     
01107     if(curr_item < top_item){
01108         top_item = curr_item;
01109         bottom_item = top_item + (items.size()-1);
01110     }
01111     if(curr_item > bottom_item){
01112         bottom_item = curr_item;
01113         top_item = bottom_item - (items.size()-1);
01114         if(top_item < 0) 
01115             top_item =0;
01116     }
01117     
01118     if(top_item > data.size()) top_item = (data.size()-1);
01119     if(bottom_item > data.size()) bottom_item = (data.size()-1);
01120         
01121     if(top_item < 0) top_item =0;
01122     if(bottom_item < 0) bottom_item =0;
01123     
01124     refresh_items();
01125 }
01126 
01127 
01128 //-----------------------------------------------------------------------
01129 
01130 void NDKDlgListBox::activate()
01131 {
01132     NDKDlgControl::activate();
01133     attron(A_BOLD);
01134     set_text(_title);
01135     attroff(A_BOLD);
01136     draw_scrollbar();
01137     refresh();
01138 }
01139 
01140 
01141 //-----------------------------------------------------------------------
01142 
01143 void NDKDlgListBox::deactivate()
01144 {
01145     NDKDlgControl::deactivate();
01146     attron(A_BOLD);
01147     set_text(_title);
01148     attroff(A_BOLD);
01149     deactivate_item(curr_item);
01150     draw_scrollbar();
01151     refresh();
01152 }
01153 
01154 
01155 //-----------------------------------------------------------------------
01156 
01157 void NDKDlgListBox::show_text(const string &t,char where)
01158 {
01159     if (!t.empty()){
01160         switch(where){
01161             case 'l': lefttext(0,t.c_str()); break;
01162             case 'c': centertext(0,t.c_str()); break;
01163             case 'r': righttext(0,t.c_str()); break;
01164             default: centertext(0,t.c_str()); break;
01165         }
01166     }
01167 }
01168 
01169 
01170 //-----------------------------------------------------------------------
01171 
01172 void NDKDlgListBox::lefttext(int row,const char *label) {
01173   if (label) {
01174     OnError(addstr(row, 1, label, width()));
01175   }
01176 }
01177 
01178 
01179 //-----------------------------------------------------------------------
01180 
01181 void NDKDlgListBox::righttext(int row,const char *label) {
01182   if (label) {
01183     int x = maxx() - strlen(label)-1;
01184     if (x<0)
01185       x=0;
01186     OnError(addstr(row, x, label, width()));
01187   }
01188 }
01189 
01190 
01191 //-----------------------------------------------------------------------
01192 
01193 void NDKDlgListBox::activate_item(int item_idx)
01194 {
01195     update_item(item_idx);
01196     visible_item(item_idx)->activate();
01197 }
01198 
01199 
01200 //-----------------------------------------------------------------------
01201 
01202 void NDKDlgListBox::deactivate_item(int item_idx)
01203 {
01204     visible_item(item_idx)->deactivate();
01205     update_data(item_idx);
01206 }
01207 
01208 
01209 //-----------------------------------------------------------------------
01210 
01211 void NDKDlgListBox::update_data(int item_idx)
01212 {
01213     if(data.empty()||item_idx<0||item_idx >= data.size() )
01214         return;
01215     NDKDlgListItem &itm= *(visible_item(item_idx)); 
01216     NDKDlgListItemData &dat = *(data[item_idx]);
01217     dat = itm;
01218     
01219 }
01220 
01221 
01222 //-----------------------------------------------------------------------
01223 
01224 void NDKDlgListBox::update_item(int item_idx)
01225 {
01226     if(data.empty()||item_idx<0||item_idx >= data.size() )
01227         return;
01228     NDKDlgListItem &itm= *(visible_item(item_idx));
01229     NDKDlgListItemData &dat = *(data[item_idx]);
01230     itm = dat;
01231 }
01232 
01233 
01234 //-----------------------------------------------------------------------
01235 
01236 void NDKDlgListBox::move_up()
01237 {
01238     if(curr_item){
01239         curr_item--;
01240         adjust_top_and_bottom();
01241         draw_scrollbar();
01242         refresh();
01243         if(notify_enabled()){
01244             process_message(pParent,LI_POS_CHANGE,get_ctrl_id(),0);
01245         }
01246     }
01247 }
01248 
01249 
01250 //-----------------------------------------------------------------------
01251 
01252 void NDKDlgListBox::move_down()
01253 {
01254     if(data.size() && curr_item < data.size()-1){
01255         curr_item++;
01256         adjust_top_and_bottom();
01257         draw_scrollbar();
01258         refresh();
01259         if(notify_enabled()){
01260             process_message(pParent,LI_POS_CHANGE,get_ctrl_id(),0);
01261         }
01262     }
01263 }
01264 
01265 
01266 //-----------------------------------------------------------------------
01267 
01268 void NDKDlgListBox::move_left()
01269 {
01270 }
01271 
01272 
01273 //-----------------------------------------------------------------------
01274 
01275 void NDKDlgListBox::move_right()
01276 {
01277 }
01278 
01279 
01280 //-----------------------------------------------------------------------
01281 string NDKDlgListBox::get_item_text(int pos)
01282 {
01283     string result;
01284     if(pos>-1 && pos < data.size())
01285         result = data[pos]->get_text();
01286 
01287     return result;
01288 }
01289 
01290 
01291 //-----------------------------------------------------------------------
01292 void NDKDlgListBox::set_item_text(int pos,const string &txt)
01293 {
01294     if(pos>-1 && pos < data.size())
01295         data[pos]->set_text(txt);
01296 }
01297 
01298 
01299 //-----------------------------------------------------------------------
01300 void *NDKDlgListBox::get_item_data(int pos)
01301 {
01302     void *result=0;
01303     if(pos>-1 && pos < data.size())
01304         result = data[pos]->get_user_data();
01305 
01306     return result;
01307 }
01308 
01309 
01310 //-----------------------------------------------------------------------
01311 void NDKDlgListBox::set_item_data(int pos,void *usr_data)
01312 {
01313     if(pos>-1 && pos < data.size())
01314         data[pos]->set_user_data(usr_data);
01315 }
01316 
01317 
01318 //-----------------------------------------------------------------------
01319 NDKDlgListItemData *NDKDlgListBox::get_item(int pos)
01320 {
01321     NDKDlgListItemData *result=0;
01322     if(pos>-1 && pos < data.size())
01323         result = data[pos];
01324 
01325     return result;
01326 }
01327 
01328 
01329 //-----------------------------------------------------------------------
01330 void NDKDlgListBox::set_item(int pos,NDKDlgListItemData *item)
01331 {
01332     if(pos>-1 && pos < data.size()){
01333         delete data[pos];
01334         data[pos]=item;
01335         refresh_items();
01336         refresh();
01337     } 
01338 }
01339 
01340 
01341 //-----------------------------------------------------------------------
01342 int NDKDlgListBox::get_cur_pos()
01343 {
01344     return curr_item;   
01345 }
01346 
01347 
01348 //-----------------------------------------------------------------------
01349 void NDKDlgListBox::set_cur_pos(int pos)
01350 {
01351     if(pos>-1 && pos < data.size()){
01352         curr_item = pos;
01353         adjust_top_and_bottom();
01354         draw_scrollbar();
01355         refresh();
01356     }
01357 }
01358 
01359 
01360 //-----------------------------------------------------------------------
01361 void NDKDlgListBox::set_cur_sel(int pos)
01362 {
01363     if(pos>-1 && pos < data.size()){
01364         curr_item = pos;
01365         adjust_top_and_bottom();
01366         draw_scrollbar();
01367         visible_item(pos)->set_check(true);
01368         check_multisel(pos, true);
01369         refresh();
01370     }
01371 }
01372 
01373 
01374 //-----------------------------------------------------------------------
01375 int NDKDlgListBox::get_cur_sel()
01376 {
01377 //  if(is_multisel())
01378 //      throw NDKDlgException<NDKDlgListBox>(this,"Calling get_selected and is_multisel==true");
01379         
01380     return cur_sel; 
01381 }
01382 
01383 
01384 //-----------------------------------------------------------------------
01385 void NDKDlgListBox::get_sel_items(IndexList &list)
01386 {
01387     list.clear();
01388     if(is_multisel()){
01389         for(int i=0;i<data.size();i++){
01390             if(data[i]->is_checked())
01391                 list.push_back(i);
01392         }
01393     }
01394     else
01395         list.push_back(cur_sel);
01396     
01397 }
01398 
01399 
01400 //-----------------------------------------------------------------------
01401 void NDKDlgListBox::set_sel_items(const IndexList &list, bool t_or_f)
01402 {
01403     if(is_multisel()){
01404         for(int i=0;i<list.size();i++){
01405             data[list[i]]->set_check(t_or_f);
01406         }
01407     }
01408     refresh_items();
01409     refresh();
01410 }
01411 
01412 
01413 //-----------------------------------------------------------------------
01414 void NDKDlgListBox::check_multisel(int pos, bool t_or_f)
01415 {
01416     if(!is_multisel()){
01417         if(t_or_f==true){
01418             cur_sel = pos;
01419             for(int i=0;i<data.size();i++){
01420                 if(i != pos){
01421                     data[i]->set_check(false);
01422                     if(i>=top_item && i<=bottom_item){
01423                         update_item(i);
01424                     }
01425                 }
01426             }
01427         }
01428         else //t_or_f == false
01429             cur_sel=-1;
01430     }
01431 }
01432 
01433 
01434 //-----------------------------------------------------------------------
01435 void NDKDlgListBox::on_sel_change(int id)
01436 {
01437     update_data(curr_item);
01438     check_multisel(curr_item,data[curr_item]->is_checked());
01439     refresh();
01440     if(notify_enabled())
01441         process_message(pParent,LI_SEL_CHANGE,get_ctrl_id(),0);
01442 }   
01443 
01444 
01445 /************************************************************************
01446 *   class NDKDlgSelectionBox                                            *
01447 ************************************************************************/
01448 //-----------------------------------------------------------------------
01449 void NDKDlgSelectionBox::initialize_items()
01450 {
01451     curr_item=top_item=bottom_item=0;
01452     for(int i=pos_y;i<maxy();i++){
01453         items.push_back(new NDKDlgListItem(this,-1,"",1,width()-pos_x-has_frame() ,i,pos_x));
01454     }
01455     show_empty();
01456 }
01457 
01458 
01459 /************************************************************************
01460 *   class NDKDlgCheckListBox                                            *
01461 ************************************************************************/
01462 //-----------------------------------------------------------------------
01463 void NDKDlgCheckListBox::initialize_items()
01464 {
01465     curr_item=top_item=bottom_item=0;
01466     for(int i=pos_y;i<maxy();i++){
01467         items.push_back(new NDKDlgCheckButton(this,-1,"",1,width()-pos_x-has_frame() ,i,pos_x));
01468     }
01469     show_empty();
01470 }
01471 
01472 
01473 /************************************************************************
01474 *   class NDKDlgChoiceBox                                               *
01475 ************************************************************************/
01476 //-----------------------------------------------------------------------
01477 void NDKDlgChoiceBox::initialize_items()
01478 {
01479     curr_item=top_item=bottom_item=0;
01480     for(int i=pos_y;i<maxy();i++){
01481         items.push_back(new NDKDlgRadioButton(this,-1,"",1,width()-pos_x-has_frame() ,i,pos_x));
01482     }
01483     show_empty();
01484 }
01485 
01486 
01487 /************************************************************************
01488 *   class NDKDialogBox                                                  *
01489 ************************************************************************/
01490 //-----------------------------------------------------------------------
01491 NDKDialogBox::NDKDialogBox(int id,const string &title
01492                         ,int lines, int cols,int y, int x,int style)
01493     : NDKDlgControl(id,lines,cols,y,x)
01494         ,_title(title)
01495         ,curr_child(0),
01496         dlg_style(style),
01497         changed(false),
01498         pBtnYes(0),
01499         pBtnNo(0),
01500         pBtnCancel(0),
01501         pBtnOk(0)
01502 {
01503     leaveok(FALSE); 
01504     frame();
01505     show_text(_title,'c');
01506 }
01507 
01508 BEGIN_BINDINGS(NDKDialogBox,NDKDlgControl)
01509     ON_COMMAND(IDOK,NDKDialogBox::on_dlg_ok)
01510     ON_COMMAND(IDYES,NDKDialogBox::on_dlg_yes)
01511     ON_COMMAND(IDNO,NDKDialogBox::on_dlg_no)
01512     ON_COMMAND(IDCANCEL,NDKDialogBox::on_dlg_cancel)
01513 END_BINDINGS()
01514 
01515 //-----------------------------------------------------------------------
01516 NDKDialogBox::~NDKDialogBox()
01517 { 
01518     hide();
01519     ListOfChildren::iterator it;
01520     for(it=children.begin();it!=children.end();it++){
01521         delete *it;
01522     }
01523 }
01524 
01525         
01526 //-----------------------------------------------------------------------
01527 int NDKDialogBox::do_modal()
01528 {
01529     on_dlg_init();
01530     bContinueModal=true;
01531     int req=REQ_DLG_EXIT;
01532     do{
01533         req=driver(getch());
01534         switch(req){
01535             case REQ_DLG_EXIT:  on_dlg_cancel();break;
01536             case REQ_DLG_NEXT:  next_control(); break;
01537 
01538             default:            on_cmd(req);    break;
01539         }   
01540     } while( bContinueModal);
01541     
01542     return user_request;
01543 }
01544 
01545 
01546 //-----------------------------------------------------------------------
01547 void NDKDialogBox::show_text(const string &t,char where)
01548 {
01549     if (!t.empty()){
01550         switch(where){
01551             case 'l': lefttext(0,t.c_str()); break;
01552             case 'c': centertext(0,t.c_str()); break;
01553             case 'r': righttext(0,t.c_str()); break;
01554             default: centertext(0,t.c_str()); break;
01555         }
01556     }
01557 }
01558 
01559 
01560 //-----------------------------------------------------------------------
01561 int NDKDialogBox::driver (int key) 
01562 {
01563     if(children[curr_child]->driver(key)==TRUE)
01564         return REQ_DLG_PROCESSED;
01565     switch(key) {
01566         case KEY_UP:    return REQ_DLG_UP;
01567         case KEY_DOWN:  return REQ_DLG_DOWN;
01568         case KEY_LEFT:  return REQ_DLG_LEFT;
01569         case KEY_RIGHT: return REQ_DLG_RIGHT;
01570         case KEY_EXIT:
01571         case CTRL('X'):
01572         case KEY_ESC:
01573                         ///same as if user press Cancel button
01574                         user_request=IDCANCEL; 
01575                         return REQ_DLG_EXIT;
01576         case KEY_TAB:   return REQ_DLG_NEXT;
01577         default: return(key);
01578     }
01579 }
01580 
01581 
01582 //-----------------------------------------------------------------------
01583 void NDKDialogBox::next_control()
01584 {
01585     int start_point=curr_child;
01586     if(children.size()>1){
01587         for(;;){
01588             if(++curr_child==children.size())
01589                 curr_child=0;
01590             if(curr_child==start_point)
01591                 return;// We're back to the start_point.
01592             if(children[curr_child]->is_enabled())
01593                 break; //We found the next selectable child
01594         }
01595         on_ctrl_term(*(children[start_point]));
01596         on_ctrl_init(*(children[curr_child]));
01597     }
01598 }
01599 
01600 
01601 //-----------------------------------------------------------------------
01602 void NDKDialogBox::set_focus_to(int child_idx)
01603 {
01604     on_ctrl_term(*(children[curr_child]));
01605     curr_child = child_idx;
01606     on_ctrl_init(*(children[curr_child]));
01607 }
01608 
01609 
01610 //-----------------------------------------------------------------------
01611 void NDKDialogBox::set_focus_to(NDKDlgControl *p_child)
01612 {
01613     for(int i=0;i<children.size();i++){
01614         if(children[i] == p_child){
01615             set_focus_to(i);
01616             break;
01617         }
01618     }
01619 }
01620 
01621 
01622 ////-----------------------------------------------------------------------
01623 //void NDKDialogBox::on_child_action(const NDKDlgControl *ctrl)
01624 //{
01625 //  user_request= ctrl->get_ctrl_id();
01626 //  switch(user_request){
01627 //      case IDOK:  on_dlg_ok(); break; 
01628 //      case IDCANCEL: on_dlg_cancel(); break;  
01629 //      case IDYES: on_dlg_yes(); break;
01630 //      case IDNO: on_dlg_no(); break;
01631 //      default:break;
01632 //  }
01633 //  
01634 //}
01635 
01636 
01637 //-----------------------------------------------------------------------
01638 bool NDKDialogBox::can_close()
01639 { 
01640     int result = true;
01641     if(changed){
01642         YesNoCancelBox dlg(titDataChgd,msgAskToSave);
01643         int usr_choice = dlg.do_modal();
01644         switch(usr_choice){
01645             case IDCANCEL: result = false;
01646             case IDYES: 
01647             case IDNO:
01648             default:
01649                 break;
01650         }
01651     }
01652     refresh();
01653     return result;
01654 }
01655 
01656 
01657 //-----------------------------------------------------------------------
01658 void NDKDialogBox::lefttext(int row,const char *label) {
01659   if (label) {
01660     OnError(addstr(row, 0, label, width()));
01661   }
01662 }
01663 
01664 
01665 //-----------------------------------------------------------------------
01666 void NDKDialogBox::righttext(int row,const char *label) {
01667   if (label) {
01668     int x = maxx() - strlen(label);
01669     if (x<0)
01670       x=0;
01671     OnError(addstr(row, x, label, width()));
01672   }
01673 }
01674 
01675 
01676 //-----------------------------------------------------------------------
01677 int NDKDialogBox::my_w = 0;     ///useable width
01678 int NDKDialogBox::btn_w= 0;     ///each button width
01679 int NDKDialogBox::btns=0;           ///number of buttons
01680 int NDKDialogBox::used_width=0; ///total buttons width          
01681 int NDKDialogBox::spc=0;            ///space between buttons
01682 int NDKDialogBox::X_POS(int pos) 
01683 {
01684     return (((my_w-used_width)/btns)+((btn_w+spc)*pos));
01685 }
01686 
01687 
01688 //-----------------------------------------------------------------------
01689 void NDKDialogBox::create_buttons()
01690 {
01691     switch((dlg_style & 0x00ff)){
01692         case okCancel:  add_ok_cancel();        break;
01693         case yesNo:     add_yes_no();           break;
01694         case yesNoCancel:add_yes_no_cancel();   break;
01695         default:        add_ok();               break;
01696     }
01697 }
01698 
01699 //-----------------------------------------------------------------------
01700 void NDKDialogBox::add_ok()
01701 {
01702     pBtnOk=new NDKDlgPushButton(this,IDOK,lblOk, maxy()-1,(maxx()-9)/2);
01703     add_child(pBtnOk);
01704 
01705     if(!children.empty())
01706         set_focus_to(children.size()-1);
01707 }
01708 
01709 //-----------------------------------------------------------------------
01710 void NDKDialogBox::add_ok_cancel()
01711 {
01712     NDKDlgControl *pCtrl=0;
01713     my_w = width()-2;   ///useable width
01714     btn_w= 9;           ///each button width
01715     btns=2;             ///number of buttons
01716     used_width=btn_w*btns;  ///total buttons width          
01717     spc=2;              ///space between buttons
01718     pBtnOk=new NDKDlgPushButton(this,IDOK,lblOk,maxy()-1,X_POS(0));
01719     add_child(pBtnOk);
01720     pBtnOk->enable(false);
01721     pBtnCancel=new NDKDlgPushButton(this,IDCANCEL,lblCancel,maxy()-1,X_POS(1));
01722     add_child(pBtnCancel);
01723 }
01724 
01725 
01726 //-----------------------------------------------------------------------
01727 void NDKDialogBox::add_yes_no_cancel()
01728 {
01729     my_w = width()-2;   ///useable width
01730     btn_w= 9;           ///each button width
01731     btns=3;             ///number of buttons
01732     used_width=btn_w*btns;  ///total buttons width          
01733     spc=2;              ///space between buttons
01734     pBtnYes=new NDKDlgPushButton(this,IDYES,lblYes,maxy()-1,X_POS(0));
01735     add_child(pBtnYes);
01736     pBtnNo=new NDKDlgPushButton(this,IDNO,lblNo,maxy()-1,X_POS(1));
01737     add_child(pBtnNo);
01738     pBtnCancel=new NDKDlgPushButton(this,IDCANCEL,lblCancel,maxy()-1,X_POS(2));
01739     add_child(pBtnCancel);
01740 }
01741 
01742 
01743 //-----------------------------------------------------------------------
01744 void NDKDialogBox::add_yes_no()
01745 {
01746     NDKDlgControl *pCtrl=0;
01747     my_w = width()-2;   ///useable width
01748     btn_w= 9;           ///each button width
01749     btns=2;             ///number of buttons
01750     used_width=btn_w*btns;  ///total buttons width          
01751     spc=2;              ///space between buttons
01752     pBtnYes=new NDKDlgPushButton(this,IDYES,lblYes,maxy()-1,X_POS(0));
01753     add_child(pBtnYes);
01754     pBtnNo=new NDKDlgPushButton(this,IDNO,lblNo,maxy()-1,X_POS(1));
01755     add_child(pBtnNo);
01756 }
01757 
01758 
01759 /************************************************************************
01760 *   class NDKMessageBox                                                 *
01761 ************************************************************************/
01762 //-----------------------------------------------------------------------
01763 NDKMessageBox::NDKMessageBox(   const string &title,const string &message,int style)
01764     : NDKDialogBox(10000,title,LINES-15,COLS-30,7,15,style),msg(message)
01765 {
01766 }
01767 
01768 
01769 //-----------------------------------------------------------------------
01770 void NDKMessageBox::on_dlg_init()
01771 {   
01772     show_message();
01773     create_buttons(); 
01774     set_focus_to(pBtnCancel);
01775 }
01776 
01777 
01778 //-----------------------------------------------------------------------
01779 void NDKMessageBox::show_message()
01780 {
01781     int max_row_size = width()-4;
01782     int rows = msg.size()/max_row_size;
01783     if(msg.size()%max_row_size)
01784         rows++;
01785     
01786     for(int i=0;i<rows && i< maxy()-3;i++){
01787         string what(msg.substr(max_row_size*i,max_row_size));
01788         centertext(i+2,what.c_str());
01789     }
01790 }
01791 
01792 
01793 /************************************************************************
01794 *   class NDKApplication                                            *
01795 ************************************************************************/
01796 //-----------------------------------------------------------------------
01797 void NDKApplication::activateStatusBar()
01798 {
01799     pStatusBar = new NDKStatusBar(1,COLS,LINES-1,0);
01800     
01801 }
01802 
01803 
01804 //-----------------------------------------------------------------------
01805 bool NDKApplication::section_exists(ifstream &param_file,const string &section_name)
01806 {
01807     string tag("[" + section_name + "]");
01808     string line;
01809     char line_read[255]={0};
01810     for(    param_file.getline(line_read,sizeof(line_read));
01811             param_file.good();
01812             param_file.getline(line_read,sizeof(line_read))){
01813         if(line_read[0] == '['){
01814             line = line_read;
01815             if(line.find(tag)!= string::npos){
01816                 return true;
01817             }
01818         }
01819     }
01820     return false;
01821 }
01822 
01823 
01824 //-----------------------------------------------------------------------
01825 long NDKApplication::find_key(ifstream &param_file,const string &section_name,
01826                                 const string &key_name,string &value)
01827 {
01828     long line_beg =0;
01829     if(section_exists(param_file,section_name)){
01830         string line;
01831         string found_key;
01832         char line_read[255]={0};
01833         for(    param_file.getline(line_read,sizeof(line_read));
01834                 param_file.good();
01835                 param_file.getline(line_read,sizeof(line_read))){
01836             line = line_read;
01837             line_beg = param_file.tellg();
01838             line_beg -= line.size();
01839             if(line.empty() || line[0]=='#')///Skip empty and comment lines
01840                 continue;
01841             if(line_read[0] == '[')///Reached the next section
01842                 break;
01843             int from= line.find_first_not_of(" \t");
01844             if(from == string::npos)//Non-empty, but all spaces...
01845                 continue;
01846             int to= line.rfind("#");///allow inline comments
01847             if(to!=string::npos){
01848                 line = line.substr(from,to-from);
01849             }
01850             to= line.find_last_not_of(" \t");
01851             line = line.substr(from,to-from+1);
01852             int eq_sign = line.find('=');
01853             found_key= line.substr(0,eq_sign);
01854             if(found_key == key_name){
01855                 if(to!=eq_sign && eq_sign!=string::npos){//no value...
01856                     value= line.substr(eq_sign+1);
01857                 }
01858                 break;
01859             }
01860         }
01861     }
01862     return line_beg;
01863 }
01864 
01865 
01866 //-----------------------------------------------------------------------
01867 string NDKApplication::get_param(const string &section_name,
01868                                 const string &key_name,const string &val)
01869 {
01870     long pos=0;
01871     string value=val;
01872     if(!param_file_name.empty()){
01873         ifstream param_file(param_file_name.c_str());
01874         pos = find_key(param_file,section_name,key_name,value);
01875         if(pos && value.empty())
01876             value=val;
01877     }
01878         
01879     return value;   
01880 }
01881 
01882 
01883 //-----------------------------------------------------------------------
01884 long NDKApplication::get_param(const string &section_name,
01885                                 const string &key_name,long val)
01886 {
01887     char txt[255]={0};
01888     ostrstream str_val(txt,sizeof(txt));
01889     str_val << val << ends;
01890     string result = get_param(section_name,key_name, str_val.str());
01891     return atol(result.c_str());
01892 ;
01893 }
01894 
01895 } //namespace NDK_XX

Generated on Tue Aug 27 10:49:45 2002 by doxygen1.2.17