#include #include #include #include "diadef.h" #include "dialog.h" #include #include "internal.h" #include "dialog.m" #include "../diajava/proto.h" /* Evaluate the horizontal space needed to draw the buttons */ PUBLIC int BUTTONS_INFO::evalwidth() { int ret = 2; for (int i=0; i on each side */ /* add 2 for some space around the buttons */ ret += strlen(tb_title[i]) + 2; } // if (!helpfile.is_empty()) ret += strlen(MSG_U(B_HELP,"Help")) + 2; return ret; } PUBLIC BUTTONS_INFO::BUTTONS_INFO() { nb = 0; nbusr = 0; nbhelp = 0; maxhelp = 0; tbhelp = NULL; ismainmenu = false; } PUBLIC BUTTONS_INFO::~BUTTONS_INFO() { free (tbhelp); } PUBLIC void BUTTONS_INFO::setbutinfo ( int id, // MENU_xxxx (Not MENUBUT_xxxx) const char *title, // Name that goes in the button const char *icon) // Icon to use in html mode { assert (nbusr < 10); tbusr[nbusr].id = id; tbusr[nbusr].title.setfrom (title); tbusr[nbusr].icon.setfrom (icon); nbusr++; } PUBLIC void BUTTONS_INFO::delbutinfo() { nbusr = 0; } static bool first_quit = true; /* Tell the dialog system that MENU_QUIT should always be mapped to Dismiss. This function is called by program having a pulldown menu and a quit entry. */ EXPORT void dialog_noquitbutton() { first_quit = false; } PUBLIC void BUTTONS_INFO::set( int _but_options, // MENUBUT_xxxx | MENUBUT_xxxx | ... HELP_FILE &_helpfile) { nb = 0; but_options = _but_options; /* Not all buttons combination are meaningful. This explain why several buttons may share the same but_ret value. */ static struct BUTTON_ALL{ int but_id; MENU_STATUS but_ret; // Returned value when this button // is picked const char *str; const char *icon; } tbl[]={ { MENUBUT_YES, MENU_YES, MSG_U(B_YES,"Yes"), MSG_U(X_YES,"Yes") }, { MENUBUT_NO, MENU_NO, MSG_U(B_NO,"No"), MSG_U(X_NO,"No") }, { MENUBUT_OK, MENU_OK, MSG_U(B_OK,"Ok"), MSG_U(X_OKEY,"Ok") }, { MENUBUT_ACCEPT, MENU_ACCEPT, MSG_U(B_ACCEPT,"Accept"), MSG_U(X_ACCEPT,"Accept")}, { MENUBUT_CANCEL, MENU_CANCEL, MSG_U(B_CANCEL,"Cancel"), MSG_U(X_CANCEL,"Cancel")}, { MENUBUT_QUIT, MENU_QUIT, MSG_U(B_QUIT,"Quit"), MSG_U(X_QUIT,"Quit") }, { MENUBUT_SAVE, MENU_SAVE, MSG_U(B_SAVE,"Save"), MSG_U(X_SAVE,"Save") }, { MENUBUT_ADD, MENU_ADD, MSG_U(B_ADD,"Add"), MSG_U(X_ADD,"Add") }, { MENUBUT_DEL, MENU_DEL, MSG_U(B_DEL,"Del"), MSG_U(X_DEL,"Del") }, { MENUBUT_INS, MENU_INS, MSG_U(B_INS,"Ins"), MSG_U(X_INS,"Ins") }, { MENUBUT_EDIT, MENU_EDIT, MSG_U(B_EDIT,"Edit"), MSG_U(X_EDIT,"Edit") }, { MENUBUT_RESET, MENU_RESET, MSG_U(B_RESET,"Reset"), MSG_U(X_RESET,"Reset") }, { MENUBUT_MORE, MENU_MORE, MSG_U(B_MORE,"More"), MSG_U(X_MORE,"More") }, { MENUBUT_USR1, MENU_USR1, MSG_U(B_USR1,"Usr1"), "Usr1" }, { MENUBUT_USR2, MENU_USR2, MSG_U(B_USR2,"Usr2"), "Usr2" }, { MENUBUT_USR3, MENU_USR3, MSG_U(B_USR3,"Usr3"), "Usr3" }, { MENUBUT_USR4, MENU_USR4, MSG_U(B_USR4,"Usr4"), "Usr4" }, { MENUBUT_USR5, MENU_USR5, MSG_U(B_USR5,"Usr5"), "Usr5" }, { MENUBUT_USR6, MENU_USR6, MSG_U(B_USR6,"Usr6"), "Usr6" }, { MENUBUT_USR7, MENU_USR7, MSG_U(B_USR7,"Usr7"), "Usr7" }, }; BUTTON_ALL *ptl = tbl; for (unsigned i=0; ibut_id & _but_options) != 0 && (ptl->but_id != MENUBUT_OK || _but_options == MENUBUT_OK)){ /* #Specification: dialog / MENUBUT_OK / never displayed The button "Ok" is never shown except if it is the only button of the dialog. It is implied by an on a menu item. Initially it was shown but soon user have started complaining that it was useless. From the outside, it looks like a normal buttons, but deep in dialog/buttons.c, it is simply not shown. */ int but_ret = tbret[nb] = ptl->but_ret; tb_title[nb] = ptl->str; tb_icon[nb] = ptl->icon; /* #Specification: dialog / MENUBUT_CANCEL / cancel or dismiss The button MENU_CANCEL is either present as "Cancel" or "Dismiss". If there is no other buttons (beside help) in the dialog, having Cancel is not needed. A Dismiss is more appropriate. So we compare the list of buttons for the dialog. If there is only Cancel, then we show Dismiss. During this process, the buttons Ins, Del and Add are ignored. This means a dialog with Cancel, Del, and Help will be presented as Dismiss, Del, and Help. */ int but_dismiss = _but_options & (~(MENUBUT_DEL|MENUBUT_INS|MENUBUT_ADD)); if (but_dismiss == ptl->but_id && but_dismiss == MENUBUT_CANCEL){ tb_title[nb] = MSG_U(B_DISMISS,"Dismiss"); tb_icon[nb] = MSG_U(X_DISMISS,"Dismiss"); }else if (ptl->but_id == MENUBUT_QUIT){ /* #Specification: button quit / dismiss or quit / hack The first dialog requesting the QUIT button will get it. It is assumed to be the main menu of the application. All other dialog will get dismiss. */ if (!first_quit){ if (!ismainmenu){ tb_title[nb] = MSG_R(B_DISMISS); tb_icon[nb] = MSG_R(X_DISMISS); } }else{ ismainmenu = true; first_quit = false; } }else{ for (int u=0; u 0){ tb_title[nb] = MSG_R(B_HELP); tb_icon[nb] = MSG_U(X_HELP,"Help"); tbret[nb] = MENU_HELP; nb++; } } } PUBLIC void BUTTONS_INFO::addhelp (HELP_FILE &help, const char *title) { if (nbhelp == maxhelp){ maxhelp += 20; tbhelp = (HELP_FILE**)realloc(tbhelp,maxhelp*sizeof(HELP_FILE*)); } tbhelp[nbhelp++] = &help; tbhelpt.add (new SSTRING(title)); } PUBLIC void BUTTONS_INFO::delhelps () { nbhelp = 0; tbhelpt.remove_all(); } /* Setup the coordinate of each button in the dialog */ PUBLIC void BUTTONS_INFO::setup( int _y, // Line where the buttons will be drawn int width) // Width of the window { if (nb > 0){ int total_width=1; // Total size required by all buttons for (int i=0; i= width){ pos = 1; _y += 3; }else{ pos += space; } tbcoor[i].x = pos; tbcoor[i].y = _y; pos += lenbut + 2; } } } /* Set the screen cursor on the active button */ PUBLIC void BUTTONS_INFO::setcursor ( WINDOW *dialog, int button) // Which buttons is currently selected // or -1 if none { if (button != -1 && button < nb){ int x = tbcoor[button].x; int y = tbcoor[button].y; const char *but = tb_title[button]; while (*but == ' '){ but++; x++; } wmove (dialog,y,x+1); } } /* Draw all buttons */ PUBLIC void BUTTONS_INFO::draw( WINDOW *dialog, int button) // Which buttons is currently selected // or -1 if none { for (int i=0; i 0){ diagui_sendcmd (onside ? P_Form : P_Formbutton,"button $hexpand=0\n"); for (int i=0; i0); } init_dialog(); }else if (html_locatefile (relpath,".help",path,PATH_MAX)!=-1){ dialog_textbox (path,path,help_none); }else{ xconf_error (MSG_U(E_NOHELPFILE,"Help file %s not yet written"),relpath); } dialog_restart(); } } /* Present a help file */ EXPORT void dialog_showhelp (HELP_FILE &help) { char rpath[PATH_MAX]; help.getrpath(rpath); buttons_help (rpath); } PUBLIC void BUTTONS_INFO::help (WINDOW *win) { if (nbhelp == 0){ buttons_help (helpfile.get()); }else{ DIALOG_RECORDS dia; //dia.delhelps(); // No HELP_CONTEXT on this dialog dia.settype (DIATYPE_POPUP); dia.newf_head ("",MSG_U(H_HELPFILES,"Help file\tTitle")); bool hasmain = !helpfile.is_empty(); if (hasmain){ dia.new_menuitem (helpfile.get(),MSG_U(T_MAINHELP,"Main topic")); } for (int i=0; igetrpath(rpath); dia.new_menuitem (rpath,tbhelpt.getitem(i)->get()); } int nof = 0; while (1){ MENU_STATUS code = dia.editmenu ( MSG_U(T_PICKHELP,"Pick a help file") ,"",help_none,nof,0); if (code == MENU_QUIT || code == MENU_ESCAPE){ break; }else if (nof == 0 && hasmain){ buttons_help (helpfile.get()); }else{ int sel = hasmain ? nof -1 : nof; char rpath[PATH_MAX]; tbhelp[sel]->getrpath(rpath); buttons_help (rpath); } } dialog_restart(); } } /* Process one key. This function is called when the focus is in the button section. It will process the help button by itself. It return -1 is nothing special happened. It return the number of the selected button otherwise. The called generally terminate then. */ PUBLIC MENU_STATUS BUTTONS_INFO::dokey( WINDOW *dialog, int key, int &selected, int other_focus) // Is there something other that buttons // or something that require specific focus { MENU_STATUS ret = MENU_NULL; int button = selected; key = toupper(key); bool has_help = helpfile.is_filled() || nbhelp > 0; if (key == TAB){ button++; if (button == nb) button = -1; }else if (key == KEY_RIGHT){ button++; if (button == nb) button = 0; }else if (key == KEY_LEFT){ button--; if (button == -1) button = nb-1; }else if (key == '\n'){ if (has_help && button == nb -1){ help (dialog); button = -1; }else{ ret = tbret[button]; } }else if (key == KEY_F(1) && has_help){ help (dialog); button = -1; }else if (key == 'Y' && (but_options & MENUBUT_YES)){ ret = MENU_YES; }else if (key == 'N' && (but_options & MENUBUT_NO)){ ret = MENU_NO; } if (!other_focus && button == -1) button = 0; draw(dialog,button); selected = button; return ret; } PUBLIC MENU_STATUS BUTTONS_INFO::bid2status(int id) { MENU_STATUS ret = MENU_ESCAPE; if (id == BUTSPC_ENTER){ ret = MENU_ACCEPT; }else if (id == BUTSPC_DUMP){ ret = MENU_DUMP; }else if (id != BUTSPC_XQUIT){ ret = tbret[id]; } return ret; }