#include #include #define my_tolower(_c) ((_c >= 'A' && _c <= 'Z')? (_c - 'A') + 'a': _c) /*********************************** Names List ****************************************/ #define MAX_NAMES 80 typedef struct _Name { char name[80]; char surname[80]; int id; } Name; static Name namesList[MAX_NAMES]; static int namesCount = 0; static int crud_create(char *surname, char *name) { static int lastId = 0; if (namesCount == MAX_NAMES) return -1; strcpy(namesList[namesCount].surname, surname); strcpy(namesList[namesCount].name, name); namesList[namesCount].id = lastId; /* each circle has an unique id */ namesCount++; lastId++; return lastId - 1; } static Name crud_read(int index) { return namesList[index]; } static Name crud_find(int id) { int i; for (i = 0; i < namesCount; i++) { if (namesList[i].id == id) break; } return namesList[i]; } static void crud_update(int id, char *surname, char *name) { int i; for (i = 0; i < namesCount; i++) { if (namesList[i].id == id) break; } strcpy(namesList[i].surname, surname); strcpy(namesList[i].name, name); } static void crud_delete(int id) { int i, j; for (i = 0; i < namesCount; i++) { if (namesList[i].id == id) break; } for (j = i; j < namesCount - 1; j++) namesList[j] = namesList[j + 1]; namesCount--; } static int crud_length() { return namesCount; } /************************************* Operation List ************************************************/ void strLower(char* dstr, char* sstr) { if (!sstr || sstr[0] == 0) return; for (; *sstr; sstr++, dstr++) *dstr = (char)my_tolower(*sstr); *dstr = 0; } static char *trim(char *str) { char *last = NULL; while (*str==' ') str++; last = str + strlen(str); while (*--last == ' '); *(last + 1) = '\0'; return str; } static int filterName(char *name, char *filter) { char lname[80], lfilter[80]; strLower(lname, name); strLower(lfilter, filter); int i = strncmp(lname, lfilter, strlen(filter)); return (i==0); } static void loadList(Ihandle *ih) { Ihandle *txtFilter = IupGetDialogChild(ih, "TXT_FILTER"); Ihandle *listNames = IupGetDialogChild(ih, "LST_NAMES"); Name data; int count = crud_length(); char *filterTxt = IupGetAttribute(txtFilter, "VALUE"); int filter = 1; int i, j; filterTxt = trim(filterTxt); if (*filterTxt == '\0') filter = 0; IupSetAttribute(listNames, "1", NULL); j = 1; for (i = 1; i <= count; i++) { Name name = crud_read(i-1); if (!filter || filterName(name.surname, filterTxt)) { IupSetStrfId(listNames, "", j, "%s, %s", name.surname, name.name); IupSetIntId(listNames, "ID", j, name.id); j++; } } IupSetAttribute(listNames, "VALUE", NULL); } static void updateButtonsState(Ihandle *ih) { Ihandle *updateButton = IupGetDialogChild(ih, "BTN_UPDATE"); Ihandle *deleteButton = IupGetDialogChild(ih, "BTN_DELETE"); Ihandle *listNames = IupGetDialogChild(ih, "LST_NAMES"); if (!IupGetInt(listNames, "VALUE")) { IupSetAttribute(updateButton, "ACTIVE", "NO"); IupSetAttribute(deleteButton, "ACTIVE", "NO"); } else { IupSetAttribute(updateButton, "ACTIVE", "YES"); IupSetAttribute(deleteButton, "ACTIVE", "YES"); } } int btn_create_cb(Ihandle *ih) { Ihandle *txtName = IupGetDialogChild(ih, "TXT_NAME"); Ihandle *txtSurname = IupGetDialogChild(ih, "TXT_SURNAME"); char *name = trim(IupGetAttribute(txtName, "VALUE")); char *surname = trim(IupGetAttribute(txtSurname, "VALUE")); crud_create(surname, name); IupSetAttribute(txtName, "VALUE", NULL); IupSetAttribute(txtSurname, "VALUE", NULL); loadList(ih); updateButtonsState(ih); return IUP_DEFAULT; } int btn_update_cb(Ihandle *ih) { Ihandle *txtName = IupGetDialogChild(ih, "TXT_NAME"); Ihandle *txtSurname = IupGetDialogChild(ih, "TXT_SURNAME"); Ihandle *listNames = IupGetDialogChild(ih, "LST_NAMES"); int index = IupGetInt(listNames, "VALUE"); int id = IupGetIntId(listNames, "ID", index); char *name = trim(IupGetAttribute(txtName, "VALUE")); char *surname = trim(IupGetAttribute(txtSurname, "VALUE")); crud_update(id, surname, name); IupSetAttribute(txtName, "VALUE", NULL); IupSetAttribute(txtSurname, "VALUE", NULL); loadList(ih); updateButtonsState(ih); return IUP_DEFAULT; } int btn_delete_cb(Ihandle *ih) { Ihandle *txtName = IupGetDialogChild(ih, "TXT_NAME"); Ihandle *txtSurname = IupGetDialogChild(ih, "TXT_SURNAME"); Ihandle *listNames = IupGetDialogChild(ih, "LST_NAMES"); int index = IupGetAttribute(listNames, "VALUE"); int id = IupGetIntId(listNames, "ID", index); char *name = trim(IupGetAttribute(txtName, "VALUE")); char *surname = trim(IupGetAttribute(txtSurname, "VALUE")); crud_delete(id); IupSetAttribute(txtName, "VALUE", NULL); IupSetAttribute(txtSurname, "VALUE", NULL); loadList(ih); updateButtonsState(ih); return IUP_DEFAULT; } int lst_valuechanged_cb(Ihandle *ih) { Ihandle *txtName = IupGetDialogChild(ih, "TXT_NAME"); Ihandle *txtSurname = IupGetDialogChild(ih, "TXT_SURNAME"); int sel = IupGetInt(ih, "VALUE"); int id = IupGetIntId(ih, "ID", sel); Name name = crud_find(id); IupSetAttribute(txtName, "VALUE", name.name); IupSetAttribute(txtSurname, "VALUE", name.surname); updateButtonsState(ih); return IUP_DEFAULT; } int txt_valuechanged_cb(Ihandle *ih) { loadList(ih); return IUP_DEFAULT; } int main(int argc, char **argv) { Ihandle *dlg, *lbl_filter, *txt_filter, *lst_names, *lbl_name, *txt_name, *lbl_surname, *txt_surname; Ihandle *btn_create, *btn_update, *btn_delete; Ihandle *hbox, *box, *hbx_filter, *hbx_top, *hbx_name, *hbx_surname, *hbx_buttons, *vbx_input; IupOpen(&argc, &argv); lbl_filter = IupLabel("Filter prefix:"); IupSetAttribute(lbl_filter, "NAME", "LBL_FILTER"); txt_filter = IupText(NULL); IupSetAttribute(txt_filter, "NAME", "TXT_FILTER"); IupSetAttribute(txt_filter, "EXPAND", "HORIZONTAL"); IupSetAttribute(txt_filter, "SIZE", "60x"); lst_names = IupList(NULL); IupSetAttribute(lst_names, "NAME", "LST_NAMES"); IupSetAttribute(lst_names, "EXPAND", "YES"); IupSetAttribute(lst_names, "SIZE", "60x"); IupSetAttribute(lst_names, "VISIBLELINES", "6"); lbl_name = IupLabel("Name:"); IupSetAttribute(lbl_name, "NAME", "LBL_NAME"); IupSetAttribute(lbl_name, "SIZE", "35"); txt_name = IupText(NULL); IupSetAttribute(txt_name, "NAME", "TXT_NAME"); IupSetAttribute(txt_name, "SIZE", "60"); IupSetAttribute(txt_name, "NC", "80"); IupSetAttribute(txt_name, "EXPAND", "HORIZONTAL"); lbl_surname = IupLabel("Surname:"); IupSetAttribute(lbl_surname, "NAME", "LBL_SURNAME"); IupSetAttribute(lbl_surname, "SIZE", "35"); txt_surname = IupText(NULL); IupSetAttribute(txt_surname, "NAME", "TXT_SURNAME"); IupSetAttribute(txt_surname, "SIZE", "60"); IupSetAttribute(txt_surname, "NC", "80"); IupSetAttribute(txt_surname, "EXPAND", "HORIZONTAL"); btn_create = IupButton("Create", NULL); IupSetAttribute(btn_create, "NAME", "BTN_CREATE"); IupSetAttribute(btn_create, "SIZE", "30"); btn_update = IupButton("Update", NULL); IupSetAttribute(btn_update, "NAME", "BTN_UPDATE"); IupSetAttribute(btn_update, "SIZE", "30"); IupSetAttribute(btn_update, "ACTIVE", "NO"); btn_delete = IupButton("Delete", NULL); IupSetAttribute(btn_delete, "NAME", "BTN_DELETE"); IupSetAttribute(btn_delete, "SIZE", "30"); IupSetAttribute(btn_delete, "ACTIVE", "NO"); hbx_filter = IupHbox(lbl_filter, txt_filter, NULL); IupSetAttribute(hbx_filter, "ALIGNMENT", "ACENTER"); hbx_top = IupHbox(hbx_filter, IupFill(), NULL); IupSetAttribute(hbx_top, "HOMOGENEOUS", "YES"); hbx_name = IupHbox(lbl_name, txt_name, NULL); IupSetAttribute(hbx_name, "ALIGNMENT", "ACENTER"); hbx_surname = IupHbox(lbl_surname, txt_surname, NULL); IupSetAttribute(hbx_surname, "alignment", "ACENTER"); hbx_buttons = IupHbox(btn_create, btn_update, btn_delete, NULL); vbx_input = IupVbox(hbx_name, hbx_surname, NULL); hbox = IupHbox(lst_names, vbx_input, NULL); IupSetAttribute(hbox, "HOMOGENEOUS", "YES"); box = IupVbox(hbx_top, hbox, hbx_buttons, NULL); IupSetAttribute(box, "NMARGIN", "10x10"); dlg = IupDialog(box); IupSetAttribute(dlg, "TITLE", "CRUD"); IupSetAttribute(dlg, "GAP", "10"); /* Registers callbacks */ IupSetCallback(btn_create, "ACTION", (Icallback)btn_create_cb); IupSetCallback(btn_update, "ACTION", (Icallback)btn_update_cb); IupSetCallback(btn_delete, "ACTION", (Icallback)btn_delete_cb); IupSetCallback(lst_names, "VALUECHANGED_CB", (Icallback)lst_valuechanged_cb); IupSetCallback(txt_filter, "VALUECHANGED_CB", (Icallback)txt_valuechanged_cb); IupShowXY(dlg, IUP_CENTER, IUP_CENTER); IupMainLoop(); IupClose(); return EXIT_SUCCESS; }