/** \file * \brief IupMatrix Expansion Library. * * See Copyright Notice in "iup.h" */ #include #include #include #include #include "iup.h" #include "iupcbs.h" #include "iupcontrols.h" #include "iup_object.h" #include "iup_childtree.h" #include "iup_register.h" #include "iup_attrib.h" #include "iup_str.h" #include "iup_assert.h" #include "iup_predialogs.h" #include "iup_matrixex.h" void iupMatrixExGetDialogPosition(ImatExData* matex_data, int *x, int *y) { /* return a dialog position aligned with the bottom-right corner of the focus cell, and it will make sure that the focus cell is visible */ int cx, cy, cw, ch, lin, col; char attrib[50]; IupGetIntInt(matex_data->ih, "SCREENPOSITION", x, y); IupGetIntInt(matex_data->ih, "FOCUSCELL", &lin, &col); IupSetfAttribute(matex_data->ih,"SHOW", "%d:%d", lin, col); sprintf(attrib, "CELLOFFSET%d:%d", lin, col); IupGetIntInt(matex_data->ih, attrib, &cx, &cy); sprintf(attrib, "CELLSIZE%d:%d", lin, col); IupGetIntInt(matex_data->ih, attrib, &cw, &ch); *x += cx + cw; *y += cy + ch; } static void iMatrixListShowLastError(Ihandle* ih) { char* lasterror = iupAttribGet(ih, "LASTERROR"); if (lasterror) IupMessageError(IupGetDialog(ih), lasterror); } static void iMatrixExSelectAll(Ihandle *ih) { char* markmode = IupGetAttribute(ih, "MARKMODE"); if (iupStrEqualNoCasePartial(markmode, "LIN")) /* matches also "LINCOL" */ { int lin, num_lin = IupGetInt(ih, "NUMLIN"); char* marked = malloc(num_lin+2); marked[0] = 'L'; for(lin = 1; lin <= num_lin; ++lin) marked[lin] = '1'; marked[lin] = 0; IupSetStrAttribute(ih, "MARKED", marked); free(marked); } else if (iupStrEqualNoCase(markmode, "COL")) { int col, num_col = IupGetInt(ih, "NUMCOL"); char* marked = malloc(num_col+2); marked[0] = 'C'; for(col = 1; col <= num_col; ++col) marked[col] = '1'; marked[col] = 0; IupSetStrAttribute(ih, "MARKED", marked); free(marked); } else if (iupStrEqualNoCase(markmode, "CELL")) { int num_col = IupGetInt(ih, "NUMCOL"); int num_lin = IupGetInt(ih, "NUMLIN"); int pos, count = num_lin*num_col; char* marked = malloc(count+1); for(pos = 0; pos < count; pos++) marked[pos] = '1'; marked[pos] = 0; IupSetStrAttribute(ih, "MARKED", marked); free(marked); } } void iupMatrixExCheckLimitsOrder(int *v1, int *v2, int min, int max) { if (*v1max) *v1 = max; if (*v2>max) *v2 = max; if (*v1>*v2) {int v=*v1; *v1=*v2; *v2=v;} } static int iMatrixExSetFreezeAttrib(Ihandle *ih, const char* value) { int freeze, lin, col; int flin, fcol; if (iupStrBoolean(value)) { IupGetIntInt(ih, "FOCUSCELL", &lin, &col); freeze = 1; } else { if (iupStrToIntInt(value, &lin, &col, ':')==2) freeze = 1; else freeze = 0; } /* clear the previous freeze first */ flin = IupGetInt(ih,"NUMLIN_NOSCROLL"); fcol = IupGetInt(ih,"NUMCOL_NOSCROLL"); if (flin) IupSetAttributeId2(ih,"FRAMEHORIZCOLOR", flin, IUP_INVALID_ID, NULL); if (fcol) IupSetAttributeId2(ih,"FRAMEVERTCOLOR", IUP_INVALID_ID, fcol, NULL); if (!freeze) { IupSetAttribute(ih,"NUMLIN_NOSCROLL","0"); IupSetAttribute(ih,"NUMCOL_NOSCROLL","0"); IupSetAttribute(ih,"SHOW","1:1"); } else { char* fzcolor = IupGetAttribute(ih, "FREEZECOLOR"); IupSetInt(ih,"NUMLIN_NOSCROLL",lin); IupSetInt(ih,"NUMCOL_NOSCROLL",col); IupSetStrAttributeId2(ih,"FRAMEHORIZCOLOR", lin, IUP_INVALID_ID, fzcolor); IupSetStrAttributeId2(ih,"FRAMEVERTCOLOR",IUP_INVALID_ID, col, fzcolor); } IupSetAttribute(ih, "REDRAW", "ALL"); return 1; /* store freeze state */ } static char* iMatrixExFileDlg(ImatExData* matex_data, int save, const char* title, const char* filter, const char* info, const char* extfilter) { Ihandle* dlg = IupFileDlg(); char* last_filename = IupGetAttribute(matex_data->ih, "LASTFILENAME"); if (last_filename) IupSetStrAttribute(dlg, "FILE", last_filename); IupSetAttribute(dlg,"DIALOGTYPE", save? "SAVE": "OPEN"); IupSetStrAttribute(dlg, "TITLE", title); IupSetStrAttribute(dlg,"FILTER", filter); IupSetStrAttribute(dlg,"FILTERINFO", info); IupSetStrAttribute(dlg,"EXTFILTER", extfilter); /* Windows and GTK only, but more flexible */ IupSetStrAttribute(dlg, "DIRECTORY", iupAttribGet(matex_data->ih, "FILEDIRECTORY")); IupSetAttributeHandle(dlg, "PARENTDIALOG", IupGetDialog(matex_data->ih)); IupPopup(dlg, IUP_CENTERPARENT, IUP_CENTERPARENT); if (IupGetInt(dlg,"STATUS")!=-1) { char* value = IupGetAttribute(dlg, "VALUE"); value = iupStrReturnStr(value); IupDestroy(dlg); return value; } IupDestroy(dlg); return NULL; } static int iMatrixExItemExport_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); char *filter, *info, *extfilter, *filename; if (iupStrEqual(IupGetAttribute(ih_item, "FILEFORMAT"), "LaTeX")) { filter = "*.tex"; /* Motif does not support EXTFILTER, so define both */ info = "LaTeX file (table format)"; extfilter = "LaTeX file (table format)|*.tex|All Files|*.*|"; } else if (iupStrEqual(IupGetAttribute(ih_item, "FILEFORMAT"), "HTML")) { filter = "*.html;*.htm"; info = "HTML file (table format)"; extfilter = "HTML file (table format)|*.html;*.htm|All Files|*.*|"; } else { filter = "*.txt"; info = "Text file"; extfilter = "Text file|*.txt;*.csv|All Files|*.*|"; } filename = iMatrixExFileDlg(matex_data, 1, "_@IUP_EXPORT", filter, info, extfilter); if (filename) { IupSetStrAttribute(matex_data->ih, "FILEFORMAT", IupGetAttribute(ih_item, "FILEFORMAT")); IupSetStrAttribute(matex_data->ih, "COPYFILE", filename); IupSetStrAttribute(matex_data->ih, "LASTFILENAME", filename); iMatrixListShowLastError(matex_data->ih); } else IupSetAttribute(matex_data->ih, "LASTFILENAME", NULL); return IUP_DEFAULT; } static int iMatrixExItemImport_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); char *filter, *info, *extfilter, *filename; filter = "*.txt"; info = "Text file"; extfilter = "Text file|*.txt|All Files|*.*|"; filename = iMatrixExFileDlg(matex_data, 0, "_@IUP_IMPORT", filter, info, extfilter); if (filename) { IupSetStrAttribute(matex_data->ih, "PASTEFILE", filename); IupSetStrAttribute(matex_data->ih, "LASTFILENAME", filename); iMatrixListShowLastError(matex_data->ih); } else IupSetAttribute(matex_data->ih, "LASTFILENAME", NULL); return IUP_DEFAULT; } static int setparent_param_cb(Ihandle* param_dialog, int param_index, void* user_data) { if (param_index == IUP_GETPARAM_MAP) { Ihandle* ih = (Ihandle*)user_data; IupSetAttributeHandle(param_dialog, "PARENTDIALOG", ih); } return 1; } static int iMatrixExItemSettings_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); int sep_index = 0, decimal_sep_index = 0, decimal_sep_old, decimals, decimals_old; char sep_other[5] = "", *decimal_symbol; char sep = *(IupGetAttribute(matex_data->ih, "TEXTSEPARATOR")); if (sep == ';') sep_index = 1; else if (sep == ' ') sep_index = 2; decimal_symbol = IupGetAttribute(matex_data->ih, "NUMERICDECIMALSYMBOL"); /* this will also check for global "DEFAULTDECIMALSYMBOL" */ if (decimal_symbol) { if (decimal_symbol[0] == ',') /* else is '.' */ decimal_sep_index = 1; } else /* if not defined get from system */ { struct lconv * locale_info = localeconv(); if (locale_info->decimal_point[0] == ',') /* else is '.' */ decimal_sep_index = 1; } decimal_sep_old = decimal_sep_index; decimals = IupGetInt(matex_data->ih, "NUMERICFORMATPRECISION"); /* get the value for the whole matrix */ decimals_old = decimals; if (IupGetParam("_@IUP_SETTINGSDLG", setparent_param_cb, IupGetDialog(matex_data->ih), "_@IUP_TEXTSEPARATOR%l|Tab|\";\"|\" \"|\n" "_@IUP_OTHERTEXTSEPARATOR%s[^0-9]\n" "_@IUP_DECIMALS%i[0]\n" "_@IUP_DECIMALSYMBOL%l|.|,|\n", &sep_index, sep_other, &decimals, &decimal_sep_index, NULL)) { if (sep_other[0] != 0) IupSetStrAttribute(matex_data->ih, "TEXTSEPARATOR", sep_other); else { const char* sep_str[] = { "\t", ";", " " }; IupSetStrAttribute(matex_data->ih, "TEXTSEPARATOR", sep_str[sep_index]); } /* avoid changing the application defined locale if not changed */ if (decimal_sep_old != decimal_sep_index) { const char* decimal_str[] = { ".", "," }; IupSetAttribute(matex_data->ih, "NUMERICDECIMALSYMBOL", decimal_str[decimal_sep_index]); } if (decimals_old != decimals) IupSetInt(matex_data->ih, "NUMERICFORMATPRECISION", decimals); IupSetAttribute(matex_data->ih, "REDRAW", "ALL"); } return IUP_DEFAULT; } static int iMatrixExItemCut_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); IupSetAttribute(matex_data->ih, "COPY", "MARKED"); IupSetAttribute(matex_data->ih, "CLEARVALUE", "MARKED"); iMatrixListShowLastError(matex_data->ih); return IUP_DEFAULT; } static int iMatrixExItemCopy_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); IupSetAttribute(matex_data->ih, "COPY", "MARKED"); iMatrixListShowLastError(matex_data->ih); return IUP_DEFAULT; } static int iMatrixExItemPaste_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); if (IupGetAttribute(matex_data->ih, "MARKED")) IupSetAttribute(matex_data->ih, "PASTE", "MARKED"); else IupSetAttribute(matex_data->ih, "PASTE", "FOCUS"); iMatrixListShowLastError(matex_data->ih); return IUP_DEFAULT; } static int iMatrixExItemDel_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); IupSetAttribute(matex_data->ih, "CLEARVALUE", "MARKED"); iMatrixListShowLastError(matex_data->ih); return IUP_DEFAULT; } static int iMatrixExItemSelectAll_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); iMatrixExSelectAll(matex_data->ih); return IUP_DEFAULT; } static int iMatrixExFindLin(Ihandle* ih, const char* line); static int iMatrixExItemCopyColTo_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); char* value = IupGetAttribute(ih_item, "COPYCOLTO"); int lin, col; IupGetIntInt(ih_item, "MENUCONTEXT_CELL", &lin, &col); IupSetfAttribute(matex_data->ih, "FOCUSCELL", "%d:%d", lin, col); if (iupStrEqual(value, "INTERVAL")) { if (iupAttribGetInt(matex_data->ih, "CELLBYTITLE")) { char line1[50] = ""; char line2[50] = ""; char* last_lin1 = iupAttribGet(matex_data->ih, "_IUP_LAST_COPYTO_LIN1"); char* last_lin2 = iupAttribGet(matex_data->ih, "_IUP_LAST_COPYTO_LIN2"); iupStrCopyN(line1, 50, last_lin1); iupStrCopyN(line2, 50, last_lin2); if (IupGetParam("_@IUP_COPYTOINTERVAL", setparent_param_cb, IupGetDialog(matex_data->ih), "_@IUP_LINESTART%s\n_@IUP_LINEEND%s\n", line1, line2, NULL)) { int lin1 = iMatrixExFindLin(matex_data->ih, line1); int lin2 = iMatrixExFindLin(matex_data->ih, line2); IupSetStrfId2(matex_data->ih, "COPYCOLTO", lin, col, "%d-%d", lin1, lin2); iupAttribSetStr(matex_data->ih, "_IUP_LAST_COPYTO_LIN1", line1); iupAttribSetStr(matex_data->ih, "_IUP_LAST_COPYTO_LIN2", line2); } } else { int lin1 = iupAttribGetInt(matex_data->ih, "_IUP_LAST_COPYTO_LIN1"); int lin2 = iupAttribGetInt(matex_data->ih, "_IUP_LAST_COPYTO_LIN2"); if (IupGetParam("_@IUP_COPYTOINTERVAL", setparent_param_cb, IupGetDialog(matex_data->ih), "_@IUP_LINESTART%i[1,,]\n_@IUP_LINEEND%i[1,,]\n", &lin1, &lin2, NULL)) { IupSetStrfId2(matex_data->ih, "COPYCOLTO", lin, col, "%d-%d", lin1, lin2); iupAttribSetInt(matex_data->ih, "_IUP_LAST_COPYTO_LIN1", lin1); iupAttribSetInt(matex_data->ih, "_IUP_LAST_COPYTO_LIN2", lin2); } } } else IupSetStrAttributeId2(matex_data->ih, "COPYCOLTO", lin, col, value); return IUP_DEFAULT; } static int iMatrixExItemUndo_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); IupSetAttribute(matex_data->ih, "UNDO", NULL); /* 1 level */ iMatrixListShowLastError(matex_data->ih); return IUP_DEFAULT; } static int iMatrixExItemRedo_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); IupSetAttribute(matex_data->ih, "REDO", NULL); /* 1 level */ iMatrixListShowLastError(matex_data->ih); return IUP_DEFAULT; } static int iMatrixExItemUndoList_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); if (!matex_data) /* will be called also by the shortcut key */ matex_data = (ImatExData*)iupAttribGet(ih_item, "_IUP_MATEX_DATA"); iupMatrixExUndoShowDialog(matex_data); return IUP_DEFAULT; } static int iMatrixExItemFind_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); IupSetStrAttribute(matex_data->ih, "FOCUSCELL", IupGetAttribute(ih_item, "MENUCONTEXT_CELL")); iupMatrixExFindShowDialog(matex_data); return IUP_DEFAULT; } static int iMatrixExFindLin(Ihandle* ih, const char* line) { int lin, num_lin = IupGetInt(ih, "NUMLIN"); for (lin = 1; lin <= num_lin; lin++) { char* value = iupMatrixExGetCellValue(ih, lin, 0, 1); /* get displayed value */ if (value && value[0] != 0) { if (iupStrEqual(value, line)) return lin; } } return 1; } static int iMatrixExFindCol(Ihandle* ih, const char* column) { int col, num_col = IupGetInt(ih, "NUMCOL"); for (col = 1; col <= num_col; col++) { char* value = iupMatrixExGetCellValue(ih, 0, col, 1); /* get displayed value */ if (value && value[0] != 0) { if (iupStrEqual(value, column)) return col; } } return 1; } static int iMatrixExItemGoTo_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); if (!matex_data) /* will be called also by the shortcut key */ matex_data = (ImatExData*)iupAttribGet(ih_item, "_IUP_MATEX_DATA"); if (iupAttribGetInt(matex_data->ih, "CELLBYTITLE")) { char line[50] = ""; char column[50] = ""; char* last_lin = iupAttribGet(matex_data->ih, "_IUP_LAST_GOTO_LIN"); char* last_col = iupAttribGet(matex_data->ih, "_IUP_LAST_GOTO_COL"); iupStrCopyN(line, 50, last_lin); iupStrCopyN(column, 50, last_col); if (IupGetParam("_@IUP_GOTO", setparent_param_cb, IupGetDialog(matex_data->ih), "_@IUP_LINE%s\n_@IUP_COLUMN%s\n", line, column, NULL)) { int lin = iMatrixExFindLin(matex_data->ih, line); int col = iMatrixExFindCol(matex_data->ih, column); IupSetfAttribute(matex_data->ih, "SHOW", "%d:%d", lin, col); IupSetfAttribute(matex_data->ih, "FOCUSCELL", "%d:%d", lin, col); iupAttribSetStr(matex_data->ih, "_IUP_LAST_GOTO_LIN", line); iupAttribSetStr(matex_data->ih, "_IUP_LAST_GOTO_COL", column); } } else { int lin = iupAttribGetInt(matex_data->ih, "_IUP_LAST_GOTO_LIN"); int col = iupAttribGetInt(matex_data->ih, "_IUP_LAST_GOTO_COL"); if (IupGetParam("_@IUP_GOTO", setparent_param_cb, IupGetDialog(matex_data->ih), "_@IUP_LINE%i[1,,]\n_@IUP_COLUMN%i[1,,]\n", &lin, &col, NULL)) { IupSetStrf(matex_data->ih, "SHOW", "%d:%d", lin, col); IupSetStrf(matex_data->ih, "FOCUSCELL", "%d:%d", lin, col); iupAttribSetInt(matex_data->ih, "_IUP_LAST_GOTO_LIN", lin); iupAttribSetInt(matex_data->ih, "_IUP_LAST_GOTO_COL", col); } } return IUP_DEFAULT; } static int iMatrixExItemSort_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); IupSetStrAttribute(matex_data->ih, "FOCUSCELL", IupGetAttribute(ih_item, "MENUCONTEXT_CELL")); iupMatrixExSortShowDialog(matex_data); return IUP_DEFAULT; } static int iMatrixExItemFreeze_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); int lin, col, flin, fcol, ret; IupGetIntInt(ih_item, "MENUCONTEXT_CELL", &lin, &col); ret = IupGetIntInt(matex_data->ih, "FREEZE", &flin, &fcol); if (ret!=2 || lin!=flin || col!=fcol) IupSetfAttribute(matex_data->ih, "FREEZE", "%d:%d", lin, col); else IupSetAttribute(matex_data->ih, "FREEZE", NULL); return IUP_DEFAULT; } static int iMatrixExItemHideCol_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); int lin, col; IupGetIntInt(ih_item, "MENUCONTEXT_CELL", &lin, &col); IupSetAttributeId(matex_data->ih, "VISIBLECOL", col, "No"); return IUP_DEFAULT; } static int iMatrixExItemShowCol_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); int col, num_col = IupGetInt(matex_data->ih, "NUMCOL"); for(col = 1; col <= num_col; ++col) { if (!IupGetIntId(matex_data->ih, "VISIBLECOL", col)) IupSetAttributeId(matex_data->ih, "VISIBLECOL", col, "Yes"); } return IUP_DEFAULT; } static int iMatrixExItemHideLin_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); int lin, col; IupGetIntInt(ih_item, "MENUCONTEXT_CELL", &lin, &col); IupSetAttributeId(matex_data->ih, "VISIBLELIN", lin, "No"); return IUP_DEFAULT; } static int iMatrixExItemShowLin_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); int lin, num_lin = IupGetInt(matex_data->ih, "NUMLIN"); for(lin = 1; lin <= num_lin; ++lin) { if (!IupGetIntId(matex_data->ih, "VISIBLELIN", lin)) IupSetAttributeId(matex_data->ih, "VISIBLELIN", lin, "Yes"); } return IUP_DEFAULT; } static void iMatrixExInitUnitList(ImatExData* matex_data, int col, char* list_str, int old_unit) { int i, count, len = 0; char* unit_name; count = IupGetIntId(matex_data->ih, "NUMERICUNITCOUNT", col); for (i=0; iih, "NUMERICUNITSHOWNINDEX", col, i); unit_name = IupGetAttributeId(matex_data->ih, "NUMERICUNITSYMBOLSHOWN", col); len += sprintf(list_str+len, "%s|", unit_name); } IupSetIntId(matex_data->ih, "NUMERICUNITSHOWNINDEX", col, old_unit); } static int iMatrixExItemNumericUnits_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); int unit, decimals; int lin, col; char format[200], list_str[200] = "|"; IupGetIntInt(ih_item, "MENUCONTEXT_CELL", &lin, &col); decimals = IupGetIntId(matex_data->ih, "NUMERICFORMATPRECISION", col); unit = IupGetIntId(matex_data->ih, "NUMERICUNITSHOWNINDEX", col); iMatrixExInitUnitList(matex_data, col, list_str+1, unit); sprintf(format, "_@IUP_UNITS%%l%s\n_@IUP_DECIMALS%%i[0]\n", list_str); if (IupGetParam("_@IUP_COLUMNUNITS", setparent_param_cb, IupGetDialog(matex_data->ih), format, &unit, &decimals, NULL)) { IupSetIntId(matex_data->ih, "NUMERICUNITSHOWNINDEX", col, unit); IupSetIntId(matex_data->ih, "NUMERICFORMATPRECISION", col, decimals); IupSetfAttribute(matex_data->ih, "REDRAW", "C%d", col); } return IUP_DEFAULT; } static int iMatrixExItemNumericDecimals_CB(Ihandle* ih_item) { ImatExData* matex_data = (ImatExData*)IupGetAttribute(ih_item, "MATRIX_EX_DATA"); int decimals; int lin, col; IupGetIntInt(ih_item, "MENUCONTEXT_CELL", &lin, &col); decimals = IupGetIntId(matex_data->ih, "NUMERICFORMATPRECISION", col); if (IupGetParam("_@IUP_COLUMNDECIMALS", setparent_param_cb, IupGetDialog(matex_data->ih), "_@IUP_DECIMALS%i[0]\n", &decimals, NULL)) { IupSetIntId(matex_data->ih, "NUMERICFORMATPRECISION", col, decimals); IupSetfAttribute(matex_data->ih, "REDRAW", "C%d", col); } return IUP_DEFAULT; } static Ihandle* iMatrixExCreateMenuContext(Ihandle* ih, int lin, int col) { int readonly = IupGetInt(ih, "READONLY"); Ihandle* menu = IupMenu(NULL); /************************** General ****************************/ IupAppend(menu, IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_SETTINGSDLG", NULL), "IMAGE=IUP_ToolsSettings"), "ACTION", iMatrixExItemSettings_CB, NULL)); IupAppend(menu, IupSeparator()); /************************** File ****************************/ IupAppend(menu, IupSetAttributes(IupSubmenu("_@IUP_EXPORT", IupMenu( IupSetCallbacks(IupSetAttributes(IupItem("Txt..." , NULL), "FILEFORMAT=TXT"), "ACTION", iMatrixExItemExport_CB, NULL), IupSetCallbacks(IupSetAttributes(IupItem("LaTeX...", NULL), "FILEFORMAT=LaTeX"), "ACTION", iMatrixExItemExport_CB, NULL), IupSetCallbacks(IupSetAttributes(IupItem("Html..." , NULL), "FILEFORMAT=HTML"), "ACTION", iMatrixExItemExport_CB, NULL), NULL)), "IMAGE=IUP_FileOpen")); if (!readonly) { IupAppend(menu, IupSetAttributes(IupSubmenu("_@IUP_IMPORT", IupMenu( IupSetCallbacks(IupItem("Txt...", NULL), "ACTION", iMatrixExItemImport_CB, NULL), NULL)), "IMAGE=IUP_FileSave")); } IupAppend(menu, IupSeparator()); /************************** Edit - Undo ****************************/ if (!readonly) { Ihandle *undo, *redo, *undolist; IupAppend(menu, undo = IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_UNDOAC", NULL), "IMAGE=IUP_EditUndo"), "ACTION", iMatrixExItemUndo_CB, NULL)); IupAppend(menu, redo = IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_REDOAC", NULL), "IMAGE=IUP_EditRedo"), "ACTION", iMatrixExItemRedo_CB, NULL)); IupAppend(menu, undolist = IupSetCallbacks(IupItem("_@IUP_UNDOLISTDLG", NULL), "ACTION", iMatrixExItemUndoList_CB, NULL)); if (!IupGetInt(ih, "UNDO")) IupSetAttribute(undo, "ACTIVE", "No"); if (!IupGetInt(ih, "REDO")) IupSetAttribute(redo, "ACTIVE", "No"); if (!IupGetInt(ih, "UNDO") && !IupGetInt(ih, "REDO")) IupSetAttribute(undolist, "ACTIVE", "No"); IupAppend(menu, IupSeparator()); } /************************** Edit - Clipboard ****************************/ if (!readonly) IupAppend(menu, IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_CUTAC", NULL), "IMAGE=IUP_EditCut"), "ACTION", iMatrixExItemCut_CB, NULL)); IupAppend(menu, IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_COPYAC", NULL), "IMAGE=IUP_EditCopy"), "ACTION", iMatrixExItemCopy_CB, NULL)); if (!readonly) { IupAppend(menu, IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_PASTEAC", NULL), "IMAGE=IUP_EditPaste"), "ACTION", iMatrixExItemPaste_CB, NULL)); IupAppend(menu, IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_ERASEAC", NULL), "IMAGE=IUP_EditErase"), "ACTION", iMatrixExItemDel_CB, NULL)); } IupAppend(menu, IupSetCallbacks(IupItem("_@IUP_SELECTALLAC", NULL), "ACTION", iMatrixExItemSelectAll_CB, NULL)); IupAppend(menu, IupSeparator()); /************************** Edit - Find ****************************/ IupAppend(menu, IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_FINDDLG", NULL), "IMAGE=IUP_EditFind"), "ACTION", iMatrixExItemFind_CB, NULL)); IupAppend(menu, IupSetCallbacks(IupItem("_@IUP_GOTODLG", NULL), "ACTION", iMatrixExItemGoTo_CB, NULL)); IupAppend(menu, IupSeparator()); /************************** View ****************************/ IupAppend(menu, IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_SORTDLG", NULL), "IMAGE=IUP_ToolsSortAscend"), "ACTION", iMatrixExItemSort_CB, NULL)); { int flin, fcol, ret; ret = IupGetIntInt(ih, "FREEZE", &flin, &fcol); if (ret!=2 || lin!=flin || col!=fcol) IupAppend(menu, IupSetCallbacks(IupItem("_@IUP_FREEZE", NULL), "ACTION", iMatrixExItemFreeze_CB, NULL)); else IupAppend(menu, IupSetCallbacks(IupItem("_@IUP_UNFREEZE", NULL), "ACTION", iMatrixExItemFreeze_CB, NULL)); } IupAppend(menu, IupSubmenu("_@IUP_VISIBILITY", IupMenu( IupSetCallbacks(IupItem("_@IUP_HIDECOLUMN", NULL), "ACTION", iMatrixExItemHideCol_CB, NULL), IupSetCallbacks(IupItem("_@IUP_SHOWHIDDENCOLUMNS", NULL), "ACTION", iMatrixExItemShowCol_CB, NULL), IupSetCallbacks(IupItem("_@IUP_HIDELINE", NULL), "ACTION", iMatrixExItemHideLin_CB, NULL), IupSetCallbacks(IupItem("_@IUP_SHOWHIDDENLINES", NULL), "ACTION", iMatrixExItemShowLin_CB, NULL), NULL))); if (IupGetAttributeId(ih, "NUMERICQUANTITY", col)) { if (IupGetIntId(ih, "NUMERICQUANTITYINDEX", col)) /* not None */ IupAppend(menu, IupSetCallbacks(IupItem("_@IUP_COLUMNUNITSDLG", NULL), "ACTION", iMatrixExItemNumericUnits_CB, NULL)); else IupAppend(menu, IupSetCallbacks(IupItem("_@IUP_COLUMNDECIMALSDLG", NULL), "ACTION", iMatrixExItemNumericDecimals_CB, NULL)); } /************************** Data ****************************/ if (!readonly) { IupAppend(menu, IupSeparator()); IupAppend(menu, IupSubmenu("_@IUP_COPYTOSAMECOLUMN", IupMenu( IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_ALLLINES" , NULL), "COPYCOLTO=ALL"), "ACTION", iMatrixExItemCopyColTo_CB, NULL), IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_HERETOTOP" , NULL), "COPYCOLTO=TOP"), "ACTION", iMatrixExItemCopyColTo_CB, NULL), IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_HERETOBOTTOM" , NULL), "COPYCOLTO=BOTTOM"), "ACTION", iMatrixExItemCopyColTo_CB, NULL), IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_INTERVALDLG" , NULL), "COPYCOLTO=INTERVAL"), "ACTION", iMatrixExItemCopyColTo_CB, NULL), IupSetCallbacks(IupSetAttributes(IupItem("_@IUP_SELECTEDLINES" , NULL), "COPYCOLTO=MARKED"), "ACTION", iMatrixExItemCopyColTo_CB, NULL), NULL))); } return menu; } static int iMatrixSetShowMenuContextAttribId(Ihandle *ih, int lin, int col, const char* value) { ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA"); Ihandle* menu = iMatrixExCreateMenuContext(ih, lin, col); IFnnii menucontext_cb; int x = 0, y = 0; iupStrToIntInt(value, &x, &y, ','); IupSetAttribute(menu, "MATRIX_EX_DATA", (char*)matex_data); /* do not use "_IUP_MATEX_DATA" to enable inheritance */ IupSetfAttribute(menu, "MENUCONTEXT_CELL", "%d:%d", lin, col); menucontext_cb = (IFnnii)IupGetCallback(ih, "MENUCONTEXT_CB"); if (menucontext_cb) { int ret = menucontext_cb(ih, menu, lin, col); if (ret == IUP_IGNORE) { IupDestroy(menu); return 0; } } IupPopup(menu, x, y); menucontext_cb = (IFnnii)IupGetCallback(ih, "MENUCONTEXTCLOSE_CB"); if (menucontext_cb) menucontext_cb(ih, menu, lin, col); IupDestroy(menu); return 0; } static int iMatrixExSetShowDialogAttrib(Ihandle *ih, const char* value) { ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA"); int readonly = IupGetInt(ih, "READONLY"); IupSetAttribute(ih, "MATRIX_EX_DATA", (char*)matex_data); /* do not use "_IUP_MATEX_DATA" to enable inheritance */ IupSetStrAttribute(ih, "MENUCONTEXT_CELL", IupGetAttribute(ih, "FOCUSCELL")); if (iupStrEqualNoCase(value, "SETTINGS")) iMatrixExItemSettings_CB(ih); else if (iupStrEqualNoCase(value, "EXPORT_TXT")) { IupSetAttribute(ih, "FILEFORMAT", "TXT"); iMatrixExItemExport_CB(ih); IupSetAttribute(ih, "FILEFORMAT", NULL); } else if (iupStrEqualNoCase(value, "EXPORT_LATEX")) { IupSetAttribute(ih, "FILEFORMAT", "LaTeX"); iMatrixExItemExport_CB(ih); IupSetAttribute(ih, "FILEFORMAT", NULL); } else if (iupStrEqualNoCase(value, "EXPORT_HTML")) { IupSetAttribute(ih, "FILEFORMAT", "HTML"); iMatrixExItemExport_CB(ih); IupSetAttribute(ih, "FILEFORMAT", NULL); } else if (!readonly && iupStrEqualNoCase(value, "IMPORT_TXT")) iMatrixExItemImport_CB(ih); else if (!readonly && iupStrEqualNoCase(value, "UNDOLIST")) iMatrixExItemUndoList_CB(ih); else if (iupStrEqualNoCase(value, "FIND")) iMatrixExItemFind_CB(ih); else if (iupStrEqualNoCase(value, "GOTO")) iMatrixExItemGoTo_CB(ih); else if (iupStrEqualNoCase(value, "SORT")) iMatrixExItemSort_CB(ih); else if (!readonly && iupStrEqualNoCase(value, "COPYCOLTO_INTERVAL")) { IupSetAttribute(ih, "COPYCOLTO", "INTERVAL"); iMatrixExItemCopyColTo_CB(ih); IupSetAttribute(ih, "COPYCOLTO", NULL); } IupSetAttribute(ih, "MENUCONTEXT_CELL", NULL); IupSetAttribute(ih, "MATRIX_EX_DATA", NULL); return 0; } static IFniiiis iMatrixOriginalButton_CB = NULL; static int iMatrixExButton_CB(Ihandle* ih, int b, int press, int x, int y, char* r) { if (iMatrixOriginalButton_CB(ih, b, press, x, y, r)==IUP_IGNORE) return IUP_IGNORE; if (b == IUP_BUTTON3 && press && IupGetInt(ih, "MENUCONTEXT")) { int pos = IupConvertXYToPos(ih, x, y); if (pos >= 0) { int lin, col; int sx, sy; char position[100]; IupTextConvertPosToLinCol(ih, pos, &lin, &col); IupGetIntInt(ih, "SCREENPOSITION", &sx, &sy); sprintf(position, "%d,%d", sx + x, sy + y); iMatrixSetShowMenuContextAttribId(ih, lin, col, position); } } return IUP_DEFAULT; } static IFnii iMatrixOriginalKeyPress_CB = NULL; static int iMatrixExKeyPress_CB(Ihandle* ih, int c, int press) { if (!press) { switch (c) { case K_cT: if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "PORTUGUESE")) { iMatrixExSelectAll(ih); return IUP_IGNORE; } else if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "SPANISH")) { iMatrixExSelectAll(ih); return IUP_IGNORE; } break; case K_cA: if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "ENGLISH")) { iMatrixExSelectAll(ih); return IUP_IGNORE; } break; case K_cV: IupSetAttribute(ih, "PASTE", "FOCUS"); iMatrixListShowLastError(ih); return IUP_IGNORE; case K_cX: IupSetAttribute(ih, "COPY", "MARKED"); iMatrixListShowLastError(ih); IupSetAttribute(ih, "CLEARVALUE", "MARKED"); return IUP_IGNORE; case K_cC: IupSetAttribute(ih, "COPY", "MARKED"); iMatrixListShowLastError(ih); return IUP_IGNORE; case K_cZ: IupSetAttribute(ih, "UNDO", NULL); /* 1 level */ return IUP_IGNORE; case K_cR: if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "PORTUGUESE")) { IupSetAttribute(ih, "REDO", NULL); /* 1 level */ return IUP_IGNORE; } else if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "SPANISH")) { IupSetAttribute(ih, "REDO", NULL); /* 1 level */ return IUP_IGNORE; } break; case K_cY: if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "ENGLISH")) { IupSetAttribute(ih, "REDO", NULL); /* 1 level */ return IUP_IGNORE; } break; case K_cU: { iMatrixExItemUndoList_CB(ih); return IUP_IGNORE; } case K_F3: { char* find = IupGetAttribute(ih, "FIND"); if (find) { /* invert the direction if not a "forward" one */ char* direction = iupAttribGet(ih, "FINDDIRECTION"); if (iupStrEqualNoCase(direction, "LEFTTOP")) iupAttribSet(ih, "FINDDIRECTION", "RIGHTBOTTOM"); else if (iupStrEqualNoCase(direction, "TOPLEFT")) iupAttribSet(ih, "FINDDIRECTION", "BOTTOMRIGHT"); IupSetStrAttribute(ih, "FIND", find); } return IUP_IGNORE; } case K_sF3: { char* find = IupGetAttribute(ih, "FIND"); if (find) { /* invert the direction if not a "reverse" one */ char* direction = iupAttribGet(ih, "FINDDIRECTION"); if (iupStrEqualNoCase(direction, "RIGHTBOTTOM")) iupAttribSet(ih, "FINDDIRECTION", "LEFTTOP"); else if (iupStrEqualNoCase(direction, "BOTTOMRIGHT")) iupAttribSet(ih, "FINDDIRECTION", "TOPLEFT"); IupSetStrAttribute(ih, "FIND", find); } return IUP_IGNORE; } case K_cL: if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "PORTUGUESE")) { ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA"); iupMatrixExFindShowDialog(matex_data); return IUP_IGNORE; } else if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "SPANISH")) { ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA"); iupMatrixExFindShowDialog(matex_data); return IUP_IGNORE; } break; case K_cF: if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "ENGLISH")) { ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA"); iupMatrixExFindShowDialog(matex_data); return IUP_IGNORE; } break; case K_mF3: { ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA"); iupMatrixExFindShowDialog(matex_data); return IUP_IGNORE; } case K_cG: { iMatrixExItemGoTo_CB(ih); return IUP_IGNORE; } case K_ESC: { ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA"); if (matex_data->find_dlg && IupGetInt(matex_data->find_dlg, "VISIBLE")) { IupHide(matex_data->find_dlg); return IUP_IGNORE; } break; } } } return iMatrixOriginalKeyPress_CB(ih, c, press); } static int iMatrixExCreateMethod(Ihandle* ih, void **params) { ImatExData* matex_data = (ImatExData*)malloc(sizeof(ImatExData)); memset(matex_data, 0, sizeof(ImatExData)); iupAttribSet(ih, "_IUP_MATEX_DATA", (char*)matex_data); matex_data->ih = ih; if (!iMatrixOriginalKeyPress_CB) iMatrixOriginalKeyPress_CB = (IFnii)IupGetCallback(ih, "KEYPRESS_CB"); IupSetCallback(ih, "KEYPRESS_CB", (Icallback)iMatrixExKeyPress_CB); if (!iMatrixOriginalButton_CB) iMatrixOriginalButton_CB = (IFniiiis)IupGetCallback(ih, "BUTTON_CB"); IupSetCallback(ih, "BUTTON_CB", (Icallback)iMatrixExButton_CB); (void)params; return IUP_NOERROR; } static void iMatrixExDestroyMethod(Ihandle* ih) { ImatExData* matex_data = (ImatExData*)iupAttribGet(ih, "_IUP_MATEX_DATA"); if (matex_data->busy_progress_dlg) IupDestroy(matex_data->busy_progress_dlg); if (matex_data->find_dlg) IupDestroy(matex_data->find_dlg); if (matex_data->undo_stack) { iupAttribSetClassObject(ih, "UNDOCLEAR", NULL); iupArrayDestroy(matex_data->undo_stack); } free(matex_data); } #include "iup_lng_english_matrix.h" #include "iup_lng_portuguese_matrix.h" #include "iup_lng_portuguese_matrix_utf8.h" #include "iup_lng_spanish_matrix.h" #include "iup_lng_spanish_matrix_utf8.h" static void iMatrixExSetClassUpdate(Iclass* ic) { Ihandle* lng = NULL; (void)ic; if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "ENGLISH")) { lng = iup_load_lng_english_matrix(); } else if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "PORTUGUESE")) { if (IupGetInt(NULL, "UTF8MODE")) lng = iup_load_lng_portuguese_matrix_utf8(); else lng = iup_load_lng_portuguese_matrix(); } else if (iupStrEqualNoCase(IupGetGlobal("LANGUAGE"), "SPANISH")) { if (IupGetInt(NULL, "UTF8MODE")) lng = iup_load_lng_spanish_matrix_utf8(); else lng = iup_load_lng_spanish_matrix(); } if (lng) { IupSetLanguagePack(lng); IupDestroy(lng); } } Iclass* iupMatrixExNewClass(void) { Iclass* ic = iupClassNew(iupRegisterFindClass("matrix")); ic->name = "matrixex"; ic->cons = "MatrixEx"; ic->format = ""; ic->nativetype = IUP_TYPECANVAS; ic->childtype = IUP_CHILDNONE; ic->is_interactive = 1; ic->has_attrib_id = 2; /* has attributes with IDs that must be parsed */ /* Class functions */ ic->New = iupMatrixExNewClass; ic->Create = iMatrixExCreateMethod; ic->Destroy = iMatrixExDestroyMethod; iupClassRegisterAttribute(ic, "FREEZE", NULL, iMatrixExSetFreezeAttrib, NULL, NULL, IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "FREEZECOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "0 0 255", IUPAF_NOT_MAPPED | IUPAF_NO_INHERIT); iupClassRegisterCallback(ic, "MENUCONTEXT_CB", "nii"); iupClassRegisterCallback(ic, "MENUCONTEXTCLOSE_CB", "nii"); iupClassRegisterAttribute(ic, "MENUCONTEXT", NULL, NULL, IUPAF_SAMEASSYSTEM, "Yes", IUPAF_NO_INHERIT); iupClassRegisterAttributeId2(ic, "SHOWMENUCONTEXT", NULL, iMatrixSetShowMenuContextAttribId, IUPAF_WRITEONLY | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "SHOWDIALOG", NULL, iMatrixExSetShowDialogAttrib, NULL, NULL, IUPAF_WRITEONLY | IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "CLASSUPDATE", NULL, (IattribSetFunc)iMatrixExSetClassUpdate, NULL, NULL, IUPAF_WRITEONLY | IUPAF_NO_INHERIT); iMatrixExSetClassUpdate(ic); iupMatrixExRegisterClipboard(ic); iupMatrixExRegisterBusy(ic); iupMatrixExRegisterVisible(ic); iupMatrixExRegisterExport(ic); iupMatrixExRegisterCopy(ic); iupMatrixExRegisterUnits(ic); iupMatrixExRegisterUndo(ic); iupMatrixExRegisterFind(ic); iupMatrixExRegisterSort(ic); return ic; } Ihandle* IupMatrixEx(void) { return IupCreate("matrixex"); }