#include #include "internal.h" #include "dialog.h" #include "dialog.m" /* #Specification: DIALOG_LISTE / principles A DIALOG_LISTE is used to present long list such as user accounts. The list generally have a header and each line is organised into cells, generally showing some records. Long list are not that fun to deal with for users. Some mecanism should be provided to help the user browse through it. Unfortunatly not all user interface (HTML, GUI, ncurses) may support the same abilities. For example, in html, transfering long list is really annoying, especially on slow links. This may very well apply to the GUI since it is client server based and the client (written in java) may be remote, over a slow link also. The idea of the DIALOG_LISTE is to give the application a single simple interface and let this object decide what trick is best for which user interface. Currently, the object implement the same trick for all user interface. If there are more than 60 entries (configurable) in the list, a POPUP is created asking for a prefix. This prefix is then used to pick only the item of the large list which match this prefix. */ # PUBLIC DIALOG_RECORDS::DIALOG_RECORDS() { internal->autonewline = false; internal->key_type = HTML_KEY_TAG; } PROTECTED int DIALOG_RECORDS::keymove (WINDOW *dialog, int key, int &nof) { int ret = keymove_scroll(dialog,key,nof); if (ret == -1){ ret = DIALOG::keymove (dialog,key,nof); } return ret; } PUBLIC DIALOG_LISTE::DIALOG_LISTE() { internal->subdia = NULL; internal->lookup = NULL; internal->nblookup = 0; } PUBLIC DIALOG_LISTE::~DIALOG_LISTE() { delete internal->subdia; delete internal->lookup; } /* Record the way the html key (href) are built. The default is to use only the tag (the first argument of the DIALOG::new_menuitem() function). With setkeyformat, you can force usage of the complete line (the two argument). For some dialog, this is the only way to create a unique key. Check out the comment in menubox.cc to understand the implication. */ PUBLIC void DIALOG_RECORDS::setkeyformat (HTML_KEY_TYPE key_type) { internal->key_type = key_type; } PUBLIC MENU_STATUS DIALOG_RECORDS::editmenu( const char *title, const char *prompt, HELP_FILE &helpfile, int &sel, // Will hold the selection or -1 if escape // It must already contains the initial selection int options) // MENUBUT_ADD | MENUBUT_INS | MENUBUT_DEL | MENUBUT_SAVE { MENU_STATUS ret = MENU_ESCAPE; if (dialog_mode == DIALOG_TREE){ // dialog_endlevel(); }else{ int n = getnb(); FIELD *first = getitem(0); int start = first != NULL && first->is_head ? 1 : 0; for (int i=start; ikey_type = internal->key_type; } while(1){ ret = DIALOG::editmenu (title,prompt,helpfile,sel,options); if(ret != MENU_OK || sel != -1) break; } } return ret; } PUBLIC MENU_STATUS DIALOG_LISTE::editmenu( const char *title, const char *prompt, HELP_FILE &helpfile, int &sel, // Will hold the selection or -1 if escape // It must already contains the initial selection int options) // MENUBUT_ADD | MENUBUT_INS | MENUBUT_DEL | MENUBUT_SAVE { MENU_STATUS ret = MENU_ESCAPE; int n = getnb(); int prefix_trig = linuxconf_getprefixtrig(); if (internal->subdia != NULL){ for (int i=0; inblookup; i++){ if (internal->lookup[i] == sel){ sel = i; break; } } ret = internal->subdia->editmenu (title,prompt,helpfile,sel,options); if (sel >= 0 && sel < internal->nblookup){ sel = internal->lookup[sel]; }else{ sel = -1; } }else if (prefix_trig == 0 || n < prefix_trig){ ret = DIALOG_RECORDS::editmenu (title,prompt,helpfile,sel,options); }else{ SSTRING prefix; { DIALOG dia; dia.newf_str (MSG_U(F_PREFIX,"Item's prefix"),prefix); int buts = MENUBUT_ACCEPT|MENUBUT_CANCEL; int nof = 0; if (!internal->what.add.is_empty()) buts |= MENUBUT_ADD; ret = dia.edit(MSG_U(T_PREFIX,"Filter prefix") ,MSG_U(I_PREFIX ,"The list of records is long, so you\n" "may want to filter it a bit by providing\n" "a prefix to search. An empty prefix means to show\n" "all records.") ,help_nil ,nof,buts); if (ret == MENU_CANCEL) ret = MENU_QUIT; } if (ret == MENU_ACCEPT){ int len = prefix.getlen(); const char *str = prefix.get(); internal->subdia = new DIALOG_RECORDS; internal->subdia->neverdelete(); internal->subdia->setkeyformat (internal->key_type); FIELD *first = getitem(0); int start = 0; if (first != NULL && first->is_head){ internal->subdia->add (first); start = 1; } internal->lookup = new int[n]; internal->nblookup = 0; for (int i=start; itag,str,len)==0){ internal->subdia->add (f); internal->lookup[internal->nblookup++] = i-start; } } internal->what.add.setfrom (internal->subdia->internal->what.add); internal->what.ins.setfrom (internal->subdia->internal->what.ins); internal->what.del.setfrom (internal->subdia->internal->what.del); internal->what.save.setfrom (internal->subdia->internal->what.save); sel = 0; ret = internal->subdia->editmenu (title,prompt,helpfile,sel,options); if (sel >= 0 && sel < internal->nblookup){ sel = internal->lookup[sel]; }else{ sel = -1; } } } return ret; } PUBLIC void DIALOG_LISTE::set_menuitem ( int no, const char *prompt1, const char *prompt2) { if (internal->subdia != NULL){ int i; for (i=0; inblookup; i++){ if (internal->lookup[i] == no){ internal->subdia->set_menuitem (i,prompt1,prompt2); break; } } if (i == internal->nblookup){ DIALOG::set_menuitem (no,prompt1,prompt2); } }else{ DIALOG::set_menuitem (no,prompt1,prompt2); } }