/** \file * \brief IupMatrix Expansion Library. * * See Copyright Notice in "iup.h" */ #include #include #include #include #include "iup.h" #include "iupcbs.h" #include "iup_array.h" #include "iup_object.h" #include "iup_attrib.h" #include "iup_str.h" #include "iup_matrixex.h" static void iMatrixExFindDialogUpdateResult(ImatExData* matex_data, Ihandle* ih_button) { char* last_found = IupGetAttribute(matex_data->ih, "_IUP_LAST_FOUND"); if (!last_found) IupSetStrAttribute(IupGetDialogChild(ih_button, "RESULT"), "TITLE", "_@IUP_NOT_FOUND"); else { char *lin_title, *col_title; int lin, col; iupStrToIntInt(last_found, &lin, &col, ':'); lin_title = IupGetAttributeId2(matex_data->ih, "", lin, 0); col_title = IupGetAttributeId2(matex_data->ih, "", 0, col); if (lin_title && col_title) IupSetfAttribute(IupGetDialogChild(ih_button, "RESULT"), "TITLE", "%s %s (%s, %s)", IupGetLanguageString("IUP_FOUND_AT"), last_found, lin_title, col_title); else if (lin_title) IupSetfAttribute(IupGetDialogChild(ih_button, "RESULT"), "TITLE", "%s %s (%s, %d)", IupGetLanguageString("IUP_FOUND_AT"), last_found, lin_title, col); else if (col_title) IupSetfAttribute(IupGetDialogChild(ih_button, "RESULT"), "TITLE", "%s %s (%d, %s)", IupGetLanguageString("IUP_FOUND_AT"), last_found, lin, col_title); else IupSetfAttribute(IupGetDialogChild(ih_button, "RESULT"), "TITLE", "%s %s", IupGetLanguageString("IUP_FOUND_AT"), last_found); } } static int iMatrixExFindDialogFindNext_CB(Ihandle* ih_button) { Ihandle* text = IupGetDialogChild(ih_button, "FINDTEXT"); char* find = IupGetAttribute(text, "VALUE"); if (find && find[0]!=0) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_button, "MATRIX_EX_DATA"); int matchcase = IupGetInt(IupGetDialogChild(ih_button, "MATCHCASE"), "VALUE"); int matchwholecell = IupGetInt(IupGetDialogChild(ih_button, "MATCHWHOLECELL"), "VALUE"); int searchbyrow = IupGetInt(IupGetDialogChild(ih_button, "SEARCHBYROW"), "VALUE"); iupAttribSet(matex_data->ih, "FINDMATCHCASE", matchcase? "Yes": "No"); iupAttribSet(matex_data->ih, "FINDMATCHWHOLECELL", matchwholecell? "Yes": "No"); iupAttribSet(matex_data->ih, "FINDDIRECTION", searchbyrow? "RIGHTBOTTOM": "BOTTOMRIGHT"); /* Forward */ IupSetAttribute(IupGetDialogChild(ih_button, "RESULT"), "TITLE", ""); IupSetStrAttribute(matex_data->ih, "FIND", find); iMatrixExFindDialogUpdateResult(matex_data, ih_button); } return IUP_DEFAULT; } static int iMatrixExFindDialogFindPrevious_CB(Ihandle* ih_button) { Ihandle* text = IupGetDialogChild(ih_button, "FINDTEXT"); char* find = IupGetAttribute(text, "VALUE"); if (find && find[0]!=0) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_button, "MATRIX_EX_DATA"); int matchcase = IupGetInt(IupGetDialogChild(ih_button, "MATCHCASE"), "VALUE"); int matchwholecell = IupGetInt(IupGetDialogChild(ih_button, "MATCHWHOLECELL"), "VALUE"); int searchbyrow = IupGetInt(IupGetDialogChild(ih_button, "SEARCHBYROW"), "VALUE"); iupAttribSet(matex_data->ih, "FINDMATCHCASE", matchcase? "Yes": "No"); iupAttribSet(matex_data->ih, "FINDMATCHWHOLECELL", matchwholecell? "Yes": "No"); iupAttribSet(matex_data->ih, "FINDDIRECTION", searchbyrow? "LEFTTOP": "TOPLEFT"); /* Backward */ IupSetAttribute(IupGetDialogChild(ih_button, "RESULT"), "TITLE", ""); IupSetStrAttribute(matex_data->ih, "FIND", find); iMatrixExFindDialogUpdateResult(matex_data, ih_button); } return IUP_DEFAULT; } static int iMatrixExFindDialogClose_CB(Ihandle* ih_button) { IupHide(IupGetDialog(ih_button)); return IUP_DEFAULT; } static void iMatrixExFindCreateDialog(ImatExData* matex_data) { Ihandle *text_box, *options_box, *find_next, *find_prev, *result_box, *dlg, *close, *dlg_box, *button_box, *parent; text_box = IupSetAttributes(IupHbox( IupLabel("_@IUP_FIND_WHAT"), IupSetAttributes(IupText(NULL), "EXPAND=HORIZONTAL, NAME=FINDTEXT"), NULL), "ALIGNMENT=ACENTER"); IupSetAttribute(text_box,"MARGIN","0x0"); options_box = IupHbox( IupVbox( IupSetAttributes(IupToggle("_@IUP_MATCH_CASE", NULL), "NAME=MATCHCASE"), IupSetAttributes(IupToggle("_@IUP_MATCH_WHOLE_CELL", NULL), "NAME=MATCHWHOLECELL"), NULL), IupSetAttributes(IupFrame(IupRadio(IupHbox( IupSetAttributes(IupToggle("_@IUP_BY_ROW", NULL), "NAME=SEARCHBYROW"), IupSetAttributes(IupToggle("_@IUP_BY_COL", NULL), "NAME=SEARCHBYCOL"), NULL))), "TITLE=_@IUP_SEARCH, MARGIN=5x5"), NULL); IupSetAttribute(options_box,"MARGIN","0x5"); find_prev = IupButton("_@IUP_FIND_PREVIOUS", NULL); IupSetStrAttribute(find_prev, "PADDING", IupGetGlobal("DEFAULTBUTTONPADDING")); IupSetCallback(find_prev, "ACTION", (Icallback)iMatrixExFindDialogFindPrevious_CB); find_next = IupButton("_@IUP_FIND_NEXT", NULL); IupSetStrAttribute(find_next, "PADDING", IupGetGlobal("DEFAULTBUTTONPADDING")); IupSetCallback(find_next, "ACTION", (Icallback)iMatrixExFindDialogFindNext_CB); close = IupButton("_@IUP_CLOSE", NULL); IupSetStrAttribute(close, "PADDING", IupGetGlobal("DEFAULTBUTTONPADDING")); IupSetCallback(close, "ACTION", (Icallback)iMatrixExFindDialogClose_CB); button_box = IupHbox( IupFill(), find_prev, find_next, close, NULL); IupSetAttribute(button_box,"MARGIN","0x0"); IupSetAttribute(button_box, "NORMALIZESIZE", "HORIZONTAL"); result_box = IupHbox( IupSetAttributes(IupLabel(""), "EXPAND=HORIZONTAL, NAME=RESULT"), NULL); IupSetAttribute(result_box,"MARGIN","0x0"); dlg_box = IupVbox( text_box, options_box, button_box, result_box, NULL); IupSetAttribute(dlg_box,"MARGIN","10x10"); IupSetAttribute(dlg_box,"GAP","5"); dlg = IupDialog(dlg_box); parent = IupGetDialog(matex_data->ih); IupSetStrAttribute(dlg,"TITLE","_@IUP_FIND"); IupSetAttribute(dlg,"MINBOX","NO"); IupSetAttribute(dlg,"MAXBOX","NO"); IupSetAttribute(dlg, "TOOLBOX","YES"); IupSetAttributeHandle(dlg,"DEFAULTENTER", find_next); IupSetAttributeHandle(dlg,"DEFAULTESC", close); IupSetAttributeHandle(dlg,"PARENTDIALOG", parent); IupSetAttribute(dlg, "MATRIX_EX_DATA", (char*)matex_data); /* do not use "_IUP_MATEX_DATA" to enable inheritance */ if (IupGetAttribute(parent, "ICON")) IupSetStrAttribute(dlg,"ICON", IupGetAttribute(parent, "ICON")); else IupSetStrAttribute(dlg,"ICON", IupGetGlobal("ICON")); matex_data->find_dlg = dlg; } static void iMatrixExFindInitDialog(ImatExData* matex_data) { char* direction; if (!(matex_data->find_dlg)) iMatrixExFindCreateDialog(matex_data); IupSetStrAttribute(IupGetDialogChild(matex_data->find_dlg, "MATCHCASE"), "VALUE", iupAttribGetStr(matex_data->ih, "FINDMATCHCASE")); IupSetStrAttribute(IupGetDialogChild(matex_data->find_dlg, "MATCHWHOLECELL"), "VALUE", iupAttribGetStr(matex_data->ih, "FINDMATCHWHOLECELL")); IupSetAttribute(IupGetDialogChild(matex_data->find_dlg, "RESULT"), "TITLE", ""); direction = iupAttribGetStr(matex_data->ih, "FINDDIRECTION"); if (iupStrEqualNoCase(direction, "LEFTTOP") || iupStrEqualNoCase(direction, "RIGHTBOTTOM")) IupSetAttribute(IupGetDialogChild(matex_data->find_dlg, "SEARCHBYROW"), "VALUE", "Yes"); else IupSetAttribute(IupGetDialogChild(matex_data->find_dlg, "SEARCHBYCOL"), "VALUE", "Yes"); } void iupMatrixExFindShowDialog(ImatExData* matex_data) { iMatrixExFindInitDialog(matex_data); /* Only position the dialog at the first time, then let the user choose the dialog position on screen */ if (!(matex_data->find_dlg->handle)) { int x, y; iupMatrixExGetDialogPosition(matex_data, &x, &y); IupShowXY(matex_data->find_dlg, x, y); } else IupShow(matex_data->find_dlg); } static int iMatrixMatch(Ihandle *ih, const char* findvalue, int lin, int col, int matchcase, int matchwholecell, int utf8) { char* value = iupMatrixExGetCellValue(ih, lin, col, 1); /* get displayed value */ if (!value || value[0] == 0) return 0; if (matchwholecell) return iupStrCompareEqual(value, findvalue, matchcase, utf8, 0); else return iupStrCompareFind(value, findvalue, matchcase, utf8); /* search only for the first occurrence */ } static int iMatrixExSetFind(Ihandle *ih, const char* value, int inc, int flip, int matchcase, int matchwholecell, int *lin, int *col, int search_cur_cell) { int utf8 = IupGetInt(NULL, "UTF8MODE"); int num_lin = IupGetInt(ih, "NUMLIN"); int num_col = IupGetInt(ih, "NUMCOL"); int count = (num_lin+1)*(num_col+1); int pos, start_pos; char* find_value; find_value = iupStrDup(value); if (search_cur_cell) /* search the current cell */ { /* the FOCUSCELL is always visible and not a title */ if (iMatrixMatch(ih, find_value, *lin, *col, matchcase, matchwholecell, utf8)) { free(find_value); return 1; } } if (flip) pos = (*col)*(num_lin+1) + *lin; else pos = (*lin)*(num_col+1) + *col; start_pos = pos; do { pos += inc; if (pos < 0) pos = count-1; /* if less than first cell, go to last */ if (pos > count-1) pos = 0; /* if more than last cell, go to first */ if (flip) { *lin = pos % (num_lin+1); *col = pos / (num_lin+1); } else { *lin = pos / (num_col+1); *col = pos % (num_col+1); } if (*lin == 0 || *col == 0) /* don't search on titles */ continue; if (pos == start_pos) { if (!search_cur_cell) { if (iMatrixMatch(ih, find_value, *lin, *col, matchcase, matchwholecell, utf8)) { free(find_value); return 1; } } free(find_value); return 0; } if (!iupMatrixExIsLineVisible(ih, *lin) || !iupMatrixExIsColumnVisible(ih, *col)) continue; } while (!iMatrixMatch(ih, find_value, *lin, *col, matchcase, matchwholecell, utf8)); free(find_value); return 1; } static int iMatrixExSetFindAttrib(Ihandle *ih, const char* value) { int lin=1, col=1, search_cur_cell = 0; int inc, flip, matchcase, matchwholecell; char* direction; if (!value || value[0]==0) return 0; IupGetIntInt(ih, "FOCUSCELL", &lin, &col); direction = iupAttribGetStr(ih, "FINDDIRECTION"); if (iupStrEqualNoCase(direction, "LEFTTOP")) { flip = 0; inc = -1; } else if (iupStrEqualNoCase(direction, "TOPLEFT")) { flip = 1; inc = -1; } else if (iupStrEqualNoCase(direction, "BOTTOMRIGHT")) { flip = 1; inc = +1; } else /* RIGHTBOTTOM */ { flip = 0; inc = +1; } matchcase = iupAttribGetInt(ih, "FINDMATCHCASE"); matchwholecell = iupAttribGetInt(ih, "FINDMATCHWHOLECELL"); { int last_lin=0, last_col=0; IupGetIntInt(ih, "_IUP_LAST_FOUND", &last_lin, &last_col); if (last_lin!=lin || last_col!=col) search_cur_cell = 1; /* search in the current cell */ } if (iMatrixExSetFind(ih, value, inc, flip, matchcase, matchwholecell, &lin, &col, search_cur_cell)) { IupSetfAttribute(ih,"FOCUSCELL", "%d:%d", lin, col); IupSetfAttribute(ih,"SHOW", "%d:%d", lin, col); IupSetAttribute(ih,"MARKED",NULL); IupSetAttributeId2(ih,"MARK",lin,col,"1"); IupSetfAttribute(ih,"REDRAW","L%d", lin); IupSetfAttribute(ih,"_IUP_LAST_FOUND", "%d:%d", lin, col); IupSetFocus(ih); } else IupSetAttribute(ih,"_IUP_LAST_FOUND", NULL); return 1; } void iupMatrixExRegisterFind(Iclass* ic) { iupClassRegisterAttribute(ic, "FIND", NULL, iMatrixExSetFindAttrib, NULL, NULL, IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FINDDIRECTION", NULL, NULL, IUPAF_SAMEASSYSTEM, "RIGHTBOTTOM", IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FINDMATCHCASE", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FINDMATCHWHOLECELL", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NO_INHERIT); }