Tk-TableMatrix
view release on metacpan or search on metacpan
pTk/mTk/Tktable800/tkTable.c view on Meta::CPAN
/*
*----------------------------------------------------------------------
*
* TableRestrictProc --
* A Tk_RestrictProc used by TableValidateChange to eliminate any
* extra key input events in the event queue that
* have a serial number no less than a given value.
*
* Results:
* Returns either TK_DISCARD_EVENT or TK_DEFER_EVENT.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static Tk_RestrictAction
TableRestrictProc(serial, eventPtr)
ClientData serial;
XEvent *eventPtr;
{
if ((eventPtr->type == KeyRelease || eventPtr->type == KeyPress) &&
((eventPtr->xany.serial-(unsigned int)serial) > 0)) {
return TK_DEFER_EVENT;
} else {
return TK_PROCESS_EVENT;
}
}
/*
*--------------------------------------------------------------
*
* TableValidateChange --
* This procedure is invoked when any character is added or
* removed from the table widget, or a set has triggered validation.
*
* Results:
* TCL_OK if the validatecommand accepts the new string,
* TCL_BREAK if the validatecommand rejects the new string,
* TCL_ERROR if any problems occured with validatecommand.
*
* Side effects:
* The insertion/deletion may be aborted, and the
* validatecommand might turn itself off (if an error
* or loop condition arises).
*
*--------------------------------------------------------------
*/
int
TableValidateChange(tablePtr, r, c, old, new, index)
register Table *tablePtr; /* Table that needs validation. */
int r, c; /* row,col index of cell in user coords */
char *old; /* current value of cell */
char *new; /* potential new value of cell */
int index; /* index of insert/delete, -1 otherwise */
{
register Tcl_Interp *interp = tablePtr->interp;
int code, booln; /* perltk: Bool to booln to avoid problems with DEFINES*/
Tk_RestrictProc *rstrct;
ClientData cdata;
if (tablePtr->valCmd == NULL || tablePtr->validate == 0) {
return TCL_OK;
}
/* Magic code to make this bit of code UI synchronous in the face of
* possible new key events */
XSync(tablePtr->display, False);
rstrct = Tk_RestrictEvents(TableRestrictProc, (ClientData)
NextRequest(tablePtr->display), &cdata);
/*
* If we're already validating, then we're hitting a loop condition
* Return and set validate to 0 to disallow further validations
* and prevent current validation from finishing
*/
if (tablePtr->flags & VALIDATING) {
tablePtr->validate = 0;
return TCL_OK;
}
tablePtr->flags |= VALIDATING;
code = LangDoCallback(tablePtr->interp, tablePtr->valCmd, 1, 5, "%d %d %s %s %d",
r, c, old, new, index);
if (code != TCL_OK && code != TCL_RETURN) {
Tcl_AddErrorInfo(interp,
"\n\t(in validation command executed by table)");
Tcl_BackgroundError(interp);
code = TCL_ERROR;
} else if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp),
&booln) != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n\tboolean not returned by validation command");
Tcl_BackgroundError(interp);
code = TCL_ERROR;
} else {
code = (booln) ? TCL_OK : TCL_BREAK;
}
Tcl_SetStringObj(Tcl_GetObjResult(interp), (char *) NULL, 0);
/*
* If ->validate has become VALIDATE_NONE during the validation,
* it means that a loop condition almost occured. Do not allow
* this validation result to finish.
*/
if (tablePtr->validate == 0) {
code = TCL_ERROR;
}
/* If validate will return ERROR, then disallow further validations */
if (code == TCL_ERROR) {
tablePtr->validate = 0;
}
Tk_RestrictEvents(rstrct, cdata, &cdata);
tablePtr->flags &= ~VALIDATING;
return code;
}
/*
*--------------------------------------------------------------
*
* ExpandPercents --
* Given a command and an event, produce a new command
* by replacing % constructs in the original command
* with information from the X event.
*
* Results:
* The new expanded command is appended to the dynamic string
* given by dsPtr.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
void
ExpandPercents(tablePtr, before, r, c, old, new, index, dsPtr, cmdType)
Table *tablePtr; /* Table that needs validation. */
char *before; /* Command containing percent
* expressions to be replaced. */
int r, c; /* row,col index of cell */
char *old; /* current value of cell */
char *new; /* potential new value of cell */
int index; /* index of insert/delete */
Tcl_DString *dsPtr; /* Dynamic string in which to append
* new command. */
int cmdType; /* type of command to make %-subs for */
{
int length, spaceNeeded, cvtFlags;
#ifdef TCL_UTF_MAX
Tcl_UniChar ch;
#else
char ch;
#endif
char *string, buf[INDEX_BUFSIZE];
/* This returns the static value of the string as set in the array */
if (old == NULL && cmdType == CMD_VALIDATE) {
old = TableGetCellValue(tablePtr, r, c);
}
while (1) {
if (*before == '\0') {
break;
}
/*
* Find everything up to the next % character and append it
* to the result string.
*/
string = before;
#ifdef TCL_UTF_MAX
/* No need to convert '%', as it is in ascii range */
( run in 1.758 second using v1.01-cache-2.11-cpan-39bf76dae61 )