Tk Source Code

Check-in [602f9502]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to tclconference@googlegroups.com
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:First test-implementation of "$t yupdate -command <command>". TODO: more testcases and documentation
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tip-438
Files: files | file ages | folders
SHA1:602f950252e9ab9973a075d6002205fbf95b1f53
User & Date: jan.nijtmans 2015-11-19 20:46:40
Context
2015-11-19
21:04
better argument checking check-in: 70ea2f72 user: jan.nijtmans tags: tip-438
20:46
First test-implementation of "$t yupdate -command <command>". TODO: more testcases and documentation check-in: 602f9502 user: jan.nijtmans tags: tip-438
2015-11-16
17:21
Better test for bug [2677890] since [19960bcef8] breaks relevance/efficiency of the previous version of textDisp-34.1 check-in: 18c0eaf0 user: fvogel tags: tip-438
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkText.c.

1504
1505
1506
1507
1508
1509
1510













1511
1512
1513
1514
1515




1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
....
1989
1990
1991
1992
1993
1994
1995




1996
1997
1998
1999
2000
2001
2002
    case TEXT_WINDOW:
	result = TkTextWindowCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_XVIEW:
	result = TkTextXviewCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_YUPDATE: {













        if (objc != 2) {
            Tcl_WrongNumArgs(interp, 2, objv, NULL);
            result = TCL_ERROR;
            goto done;
        }




        TkTextUpdateLineMetrics(textPtr, 1,
                TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), -1);
        break;
    }
    case TEXT_YVIEW:
	result = TkTextYviewCmd(textPtr, interp, objc, objv);
	break;
    }

  done:
................................................................................
    if (textPtr->insertBlinkHandler != NULL) {
	Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
    }

    textPtr->tkwin = NULL;
    textPtr->refCount--;
    Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd);




    if (textPtr->refCount == 0) {
	ckfree((char *) textPtr);
    }
}
 
/*
 *----------------------------------------------------------------------







>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
>
>
>
>
|
|
|







 







>
>
>
>







1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
....
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
    case TEXT_WINDOW:
	result = TkTextWindowCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_XVIEW:
	result = TkTextXviewCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_YUPDATE: {
	    if ((objc == 4) && !strncmp(Tcl_GetString(objv[2]), "-command", objv[3]->length)) {
		    Tcl_Obj *cmd = objv[3];
		    Tcl_IncrRefCount(cmd);
		    if (TkTextPendingyupdate(textPtr)) {
			if (textPtr->linesUpdatedCmd) {
			    Tcl_DecrRefCount(textPtr->linesUpdatedCmd);
			}
			textPtr->linesUpdatedCmd = cmd;
		    } else {
			result = Tcl_EvalObjEx(interp, cmd, TCL_EVAL_GLOBAL);
			Tcl_DecrRefCount(cmd);
		    }
		    break;
		} else if (objc != 2) {
		    Tcl_WrongNumArgs(interp, 2, objv, "?-command command?");
		    result = TCL_ERROR;
		    goto done;
		}
		if (textPtr->linesUpdatedCmd) {
		    Tcl_DecrRefCount(textPtr->linesUpdatedCmd);
		}
		textPtr->linesUpdatedCmd = NULL;
		TkTextUpdateLineMetrics(textPtr, 1,
			TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), -1);
	break;
    }
    case TEXT_YVIEW:
	result = TkTextYviewCmd(textPtr, interp, objc, objv);
	break;
    }

  done:
................................................................................
    if (textPtr->insertBlinkHandler != NULL) {
	Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler);
    }

    textPtr->tkwin = NULL;
    textPtr->refCount--;
    Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd);
    if (textPtr->linesUpdatedCmd != 0){
	Tcl_DecrRefCount(textPtr->linesUpdatedCmd);
	textPtr->linesUpdatedCmd = 0;
    }
    if (textPtr->refCount == 0) {
	ckfree((char *) textPtr);
    }
}
 
/*
 *----------------------------------------------------------------------

Changes to generic/tkText.h.

778
779
780
781
782
783
784

785
786
787
788
789
790
791
    int undo;			/* Non-zero means the undo/redo behaviour is
				 * enabled. */
    int maxUndo;		/* The maximum depth of the undo stack
				 * expressed as the maximum number of compound
				 * statements. */
    int autoSeparators;		/* Non-zero means the separators will be
				 * inserted automatically. */

} TkText;

/*
 * Flag values for TkText records:
 *
 * GOT_SELECTION:		Non-zero means we've already claimed the
 *				selection.







>







778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
    int undo;			/* Non-zero means the undo/redo behaviour is
				 * enabled. */
    int maxUndo;		/* The maximum depth of the undo stack
				 * expressed as the maximum number of compound
				 * statements. */
    int autoSeparators;		/* Non-zero means the separators will be
				 * inserted automatically. */
    Tcl_Obj *linesUpdatedCmd; /* Command to be executed when lines are up to date */
} TkText;

/*
 * Flag values for TkText records:
 *
 * GOT_SELECTION:		Non-zero means we've already claimed the
 *				selection.

Changes to generic/tkTextDisp.c.

2938
2939
2940
2941
2942
2943
2944
2945
2946











2947
2948
2949
2950
2951
2952
2953
     */

    if (dInfoPtr->metricEpoch == -1
	    && lineNum == dInfoPtr->lastMetricUpdateLine) {
	/*
	 * We have looped over all lines, so we're done. We must release our
	 * refCount on the widget (the timer token was already set to NULL
	 * above).
	 */












	textPtr->refCount--;
	if (textPtr->refCount == 0) {
	    ckfree((char *) textPtr);
	}
	return;
    }







|

>
>
>
>
>
>
>
>
>
>
>







2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
     */

    if (dInfoPtr->metricEpoch == -1
	    && lineNum == dInfoPtr->lastMetricUpdateLine) {
	/*
	 * We have looped over all lines, so we're done. We must release our
	 * refCount on the widget (the timer token was already set to NULL
	 * above). If there is a registered command, run that first.
	 */

	if (textPtr->linesUpdatedCmd != NULL) {
		Tcl_Preserve((ClientData)textPtr->interp);
	    int code = Tcl_EvalObjEx(textPtr->interp, textPtr->linesUpdatedCmd, TCL_EVAL_GLOBAL);
		if (code != TCL_OK && code != TCL_CONTINUE
			&& code != TCL_BREAK) {
		    Tcl_AddErrorInfo(textPtr->interp, "\n    (text yupdate)");
		    Tcl_BackgroundError(textPtr->interp);
		}
		Tcl_Release((ClientData)textPtr->interp);
	}

	textPtr->refCount--;
	if (textPtr->refCount == 0) {
	    ckfree((char *) textPtr);
	}
	return;
    }

Changes to tests/textDisp.test.

4186
4187
4188
4189
4190
4191
4192


















4193
4194
4195
4196
4197
4198
4199
    wm geometry . "[expr {$width * 2}]x$height+$left+$top"
    update
    .t1 yupdate
    set negative
} -cleanup {
    destroy .t1
} -result {0}



















deleteWindows
option clear

# cleanup
cleanupTests
return







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
    wm geometry . "[expr {$width * 2}]x$height+$left+$top"
    update
    .t1 yupdate
    set negative
} -cleanup {
    destroy .t1
} -result {0}

test textDisp-34.2 {text yupdate syntax} -body {
} -body {
    pack [text .t1] -expand 1 -fill both
    .t1 yupdate foo
} -cleanup {
    destroy .t1
} -returnCodes 1 -result {wrong # args: should be ".t1 yupdate ?-command command?"}

test textDisp-34.3 {text yupdate syntax} -body {
} -body {
    set ::x 0
    pack [text .t1] -expand 1 -fill both
    .t1 yupdate -command [list set ::x 1]
    set ::x
} -cleanup {
    destroy .t1
} -result {1}

deleteWindows
option clear

# cleanup
cleanupTests
return