diff options
author | ericm <ericm> | 1999-11-17 21:56:36 (GMT) |
---|---|---|
committer | ericm <ericm> | 1999-11-17 21:56:36 (GMT) |
commit | e280e2f50c959dd7115b8f01b7b56e5c59b385d3 (patch) | |
tree | 77ed28c18e32c6293337a219c003d6a15615e418 /generic | |
parent | 8382b0478bbf426a871b3a1628475292f867d21d (diff) | |
download | tk-e280e2f50c959dd7115b8f01b7b56e5c59b385d3.zip tk-e280e2f50c959dd7115b8f01b7b56e5c59b385d3.tar.gz tk-e280e2f50c959dd7115b8f01b7b56e5c59b385d3.tar.bz2 |
* tests/listbox.test: New tests for -listvar functionality, and an
odd extra case that wasn't covered before.
* generic/tkListbox.c: Tests exposed some bugs, now fixed.
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkListbox.c | 58 |
1 files changed, 29 insertions, 29 deletions
diff --git a/generic/tkListbox.c b/generic/tkListbox.c index 04b540a..99c4350 100644 --- a/generic/tkListbox.c +++ b/generic/tkListbox.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkListbox.c,v 1.5 1999/11/17 02:38:28 ericm Exp $ + * RCS: @(#) $Id: tkListbox.c,v 1.6 1999/11/17 21:56:37 ericm Exp $ */ #include "tkPort.h" @@ -1259,7 +1259,7 @@ ConfigureListbox(interp, listPtr, objc, objv, flags) int flags; /* Flags to pass to Tk_ConfigureWidget. */ { Tk_SavedOptions savedOptions; - Tcl_Obj *oldListVarObj = NULL; + Tcl_Obj *oldListObj = NULL; int oldExport; oldExport = listPtr->exportSelection; @@ -1267,8 +1267,6 @@ ConfigureListbox(interp, listPtr, objc, objv, flags) Tcl_UntraceVar(interp, listPtr->listVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, (ClientData) listPtr); - oldListVarObj = Tcl_GetVar2Ex(interp, listPtr->listVarName, - (char *)NULL, TCL_GLOBAL_ONLY); } if (Tk_SetOptions(interp, (char *)listPtr, @@ -1319,50 +1317,37 @@ ConfigureListbox(interp, listPtr, objc, objv, flags) * * no listvar | no listvar | no special action */ + oldListObj = listPtr->listObj; if (listPtr->listVarName != NULL) { - /* We now have a listvar */ if (Tcl_GetVar2(interp, listPtr->listVarName, (char *)NULL, TCL_GLOBAL_ONLY) == NULL) { - /* New listvar DOES NOT exist */ Tcl_Obj *listVarObj; - /* Use internal list obj if we have one; else, create an object */ if (listPtr->listObj != NULL) { listVarObj = listPtr->listObj; } else { listVarObj = Tcl_NewObj(); - Tcl_IncrRefCount(listVarObj); } - if (Tcl_SetVar2Ex(interp, listPtr->listVarName, - (char *)NULL, listVarObj, TCL_GLOBAL_ONLY) == NULL) { + if (Tcl_SetVar2Ex(interp, listPtr->listVarName, (char *)NULL, + listVarObj, TCL_GLOBAL_ONLY) == NULL) { Tcl_DecrRefCount(listVarObj); return TCL_ERROR; } } listPtr->listObj = Tcl_GetVar2Ex(interp, listPtr->listVarName, (char *)NULL, TCL_GLOBAL_ONLY); - Tcl_TraceVar(listPtr->interp, listPtr->listVarName, + Tcl_TraceVar(listPtr->interp, listPtr->listVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, (ClientData) listPtr); } else { - /* We do not now have a listvar */ - if (oldListVarObj != NULL) { - /* We used to have a list var */ - if (listPtr->listObj != NULL) { - Tcl_DecrRefCount(listPtr->listObj); - listPtr->listObj = NULL; - } - /* Copy the old listvar's content to the internal list obj */ - listPtr->listObj = Tcl_DuplicateObj(oldListVarObj); - Tcl_IncrRefCount(listPtr->listObj); - } else { - /* We didn't have a listvar before */ - if (listPtr->listObj == NULL) { - /* If we don't have an internal list obj, create one */ - listPtr->listObj = Tcl_NewObj(); - Tcl_IncrRefCount(listPtr->listObj); - } + if (listPtr->listObj == NULL) { + listPtr->listObj = Tcl_NewObj(); } } + Tcl_IncrRefCount(listPtr->listObj); + if (oldListObj != NULL) { + Tcl_DecrRefCount(oldListObj); + } + /* Make sure that the list length is correct */ Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements); @@ -2810,6 +2795,9 @@ ListboxListVarProc(clientData, interp, name1, name2, flags) { Listbox *listPtr = (Listbox *)clientData; Tcl_Obj *oldListObj; + int oldLength; + int i; + Tcl_HashEntry *entry; /* Bwah hahahaha -- puny mortal, you can't unset a -listvar'd variable! */ if (flags & TCL_TRACE_UNSETS) { @@ -2832,9 +2820,21 @@ ListboxListVarProc(clientData, interp, name1, name2, flags) Tcl_DecrRefCount(oldListObj); } - /* Get the list length */ + /* If the list length has decreased, then we should clean up the selection + * from elements past the end of the new list + */ + oldLength = listPtr->nElements; Tcl_ListObjLength(listPtr->interp, listPtr->listObj, &listPtr->nElements); + if (listPtr->nElements < oldLength) { + for (i = listPtr->nElements; i < oldLength; i++) { + entry = Tcl_FindHashEntry(listPtr->selection, (char *)i); + if (entry != NULL) { + Tcl_DeleteHashEntry(entry); + } + } + } + /* * The computed maxWidth may have changed as a result of this operation. * However, we don't want to recompute it every time this trace fires |