summaryrefslogtreecommitdiffstats
path: root/generic/tkListbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkListbox.c')
-rw-r--r--generic/tkListbox.c187
1 files changed, 93 insertions, 94 deletions
diff --git a/generic/tkListbox.c b/generic/tkListbox.c
index 7faa44b..620f82f 100644
--- a/generic/tkListbox.c
+++ b/generic/tkListbox.c
@@ -168,6 +168,13 @@ typedef struct {
} Listbox;
/*
+ * How to encode the keys for the hash tables used to store what items are
+ * selected and what the attributes are.
+ */
+
+#define KEY(i) ((char *) INT2PTR(i))
+
+/*
* ItemAttr structures are used to store item configuration information for
* the items in a listbox
*/
@@ -437,8 +444,8 @@ static void MigrateHashEntries(Tcl_HashTable *table,
static const Tk_ClassProcs listboxClass = {
sizeof(Tk_ClassProcs), /* size */
ListboxWorldChanged, /* worldChangedProc */
- NULL, /* createProc */
- NULL /* modalProc */
+ NULL, /* createProc */
+ NULL /* modalProc */
};
/*
@@ -480,8 +487,7 @@ Tk_ListboxObjCmd(
return TCL_ERROR;
}
- optionTables = (ListboxOptionTables *)
- Tcl_GetAssocData(interp, "ListboxOptionTables", NULL);
+ optionTables = Tcl_GetAssocData(interp, "ListboxOptionTables", NULL);
if (optionTables == NULL) {
/*
* We haven't created the option tables for this widget class yet. Do
@@ -515,7 +521,7 @@ Tk_ListboxObjCmd(
*/
listPtr = ckalloc(sizeof(Listbox));
- memset(listPtr, 0, (sizeof(Listbox)));
+ memset(listPtr, 0, sizeof(Listbox));
listPtr->tkwin = tkwin;
listPtr->display = Tk_Display(tkwin);
@@ -597,6 +603,7 @@ ListboxWidgetObjCmd(
register Listbox *listPtr = clientData;
int cmdIndex, index;
int result = TCL_OK;
+ Tcl_Obj *objPtr;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
@@ -661,9 +668,7 @@ ListboxWidgetObjCmd(
result = ListboxBboxSubCmd(interp, listPtr, index);
break;
- case COMMAND_CGET: {
- Tcl_Obj *objPtr;
-
+ case COMMAND_CGET:
if (objc != 3) {
Tcl_WrongNumArgs(interp, 2, objv, "option");
result = TCL_ERROR;
@@ -679,11 +684,8 @@ ListboxWidgetObjCmd(
Tcl_SetObjResult(interp, objPtr);
result = TCL_OK;
break;
- }
-
- case COMMAND_CONFIGURE: {
- Tcl_Obj *objPtr;
+ case COMMAND_CONFIGURE:
if (objc <= 3) {
objPtr = Tk_GetOptionInfo(interp, (char *) listPtr,
listPtr->optionTable,
@@ -698,10 +700,8 @@ ListboxWidgetObjCmd(
result = ConfigureListbox(interp, listPtr, objc-2, objv+2, 0);
}
break;
- }
case COMMAND_CURSELECTION: {
- char indexStringRep[TCL_INTEGER_SPACE];
int i;
if (objc != 2) {
@@ -718,12 +718,13 @@ ListboxWidgetObjCmd(
* selected.
*/
+ objPtr = Tcl_NewObj();
for (i = 0; i < listPtr->nElements; i++) {
- if (Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i))) {
- sprintf(indexStringRep, "%d", i);
- Tcl_AppendElement(interp, indexStringRep);
+ if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) {
+ Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(i));
}
}
+ Tcl_SetObjResult(interp, objPtr);
result = TCL_OK;
break;
}
@@ -857,7 +858,6 @@ ListboxWidgetObjCmd(
break;
case COMMAND_ITEMCGET: {
- Tcl_Obj *objPtr;
ItemAttr *attrPtr;
if (objc != 4) {
@@ -872,8 +872,10 @@ ListboxWidgetObjCmd(
}
if (index < 0 || index >= listPtr->nElements) {
- Tcl_AppendResult(interp, "item number \"",
- Tcl_GetString(objv[2]), "\" out of range", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "item number \"%s\" out of range",
+ Tcl_GetString(objv[2])));
+ Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
result = TCL_ERROR;
break;
}
@@ -892,7 +894,6 @@ ListboxWidgetObjCmd(
}
case COMMAND_ITEMCONFIGURE: {
- Tcl_Obj *objPtr;
ItemAttr *attrPtr;
if (objc < 3) {
@@ -908,8 +909,10 @@ ListboxWidgetObjCmd(
}
if (index < 0 || index >= listPtr->nElements) {
- Tcl_AppendResult(interp, "item number \"", Tcl_GetString(objv[2]),
- "\" out of range", NULL);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "item number \"%s\" out of range",
+ Tcl_GetString(objv[2])));
+ Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
result = TCL_ERROR;
break;
}
@@ -922,10 +925,9 @@ ListboxWidgetObjCmd(
if (objPtr == NULL) {
result = TCL_ERROR;
break;
- } else {
- Tcl_SetObjResult(interp, objPtr);
- result = TCL_OK;
}
+ Tcl_SetObjResult(interp, objPtr);
+ result = TCL_OK;
} else {
result = ConfigureListboxItem(interp, listPtr, attrPtr,
objc-3, objv+3, index);
@@ -1007,7 +1009,7 @@ ListboxWidgetObjCmd(
}
diff = listPtr->topIndex - index;
if (diff > 0) {
- if (diff <= (listPtr->fullLines/3)) {
+ if (diff <= listPtr->fullLines / 3) {
ChangeListboxView(listPtr, index);
} else {
ChangeListboxView(listPtr, index - (listPtr->fullLines-1)/2);
@@ -1015,7 +1017,7 @@ ListboxWidgetObjCmd(
} else {
diff = index - (listPtr->topIndex + listPtr->fullLines - 1);
if (diff > 0) {
- if (diff <= (listPtr->fullLines/3)) {
+ if (diff <= listPtr->fullLines / 3) {
ChangeListboxView(listPtr, listPtr->topIndex + diff);
} else {
ChangeListboxView(listPtr, index-(listPtr->fullLines-1)/2);
@@ -1090,7 +1092,7 @@ ListboxBboxSubCmd(
*/
if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {
- Tcl_Obj *el;
+ Tcl_Obj *el, *results[4];
const char *stringRep;
int pixelWidth, stringLen, x, y, result;
Tk_FontMetrics fm;
@@ -1111,8 +1113,11 @@ ListboxBboxSubCmd(
x = listPtr->inset + listPtr->selBorderWidth - listPtr->xOffset;
y = ((index - listPtr->topIndex)*listPtr->lineHeight)
+ listPtr->inset + listPtr->selBorderWidth;
- Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d %d %d",
- x, y, pixelWidth, fm.linespace));
+ results[0] = Tcl_NewIntObj(x);
+ results[1] = Tcl_NewIntObj(y);
+ results[2] = Tcl_NewIntObj(pixelWidth);
+ results[3] = Tcl_NewIntObj(fm.linespace);
+ Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
}
return TCL_OK;
}
@@ -1197,9 +1202,8 @@ ListboxSelectionSubCmd(
Tcl_WrongNumArgs(interp, 3, objv, "index");
return TCL_ERROR;
}
- Tcl_SetObjResult(interp,
- Tcl_NewBooleanObj((Tcl_FindHashEntry(listPtr->selection,
- (char *) INT2PTR(first)) != NULL)));
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
+ Tcl_FindHashEntry(listPtr->selection, KEY(first)) != NULL));
result = TCL_OK;
break;
case SELECTION_SET:
@@ -1232,43 +1236,45 @@ ListboxXviewSubCmd(
int objc, /* Number of arguments in the objv array */
Tcl_Obj *const objv[]) /* Array of arguments to the procedure */
{
-
- int index, count, type, windowWidth, windowUnits;
+ int index, count, windowWidth, windowUnits;
int offset = 0; /* Initialized to stop gcc warnings. */
double fraction;
windowWidth = Tk_Width(listPtr->tkwin)
- 2*(listPtr->inset + listPtr->selBorderWidth);
if (objc == 2) {
+ Tcl_Obj *results[2];
+
if (listPtr->maxWidth == 0) {
- Tcl_SetResult(interp, "0.0 1.0", TCL_STATIC);
+ results[0] = Tcl_NewDoubleObj(0.0);
+ results[1] = Tcl_NewDoubleObj(1.0);
} else {
double fraction2;
- fraction = listPtr->xOffset/((double) listPtr->maxWidth);
+ fraction = listPtr->xOffset / (double) listPtr->maxWidth;
fraction2 = (listPtr->xOffset + windowWidth)
- / ((double) listPtr->maxWidth);
+ / (double) listPtr->maxWidth;
if (fraction2 > 1.0) {
fraction2 = 1.0;
}
- Tcl_SetObjResult(interp, Tcl_ObjPrintf("%g %g",
- fraction, fraction2));
+ results[0] = Tcl_NewDoubleObj(fraction);
+ results[1] = Tcl_NewDoubleObj(fraction2);
}
+ Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
} else if (objc == 3) {
if (Tcl_GetIntFromObj(interp, objv[2], &index) != TCL_OK) {
return TCL_ERROR;
}
ChangeListboxOffset(listPtr, index*listPtr->xScrollUnit);
} else {
- type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count);
- switch (type) {
+ switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
case TK_SCROLL_ERROR:
return TCL_ERROR;
case TK_SCROLL_MOVETO:
offset = (int) (fraction*listPtr->maxWidth + 0.5);
break;
case TK_SCROLL_PAGES:
- windowUnits = windowWidth/listPtr->xScrollUnit;
+ windowUnits = windowWidth / listPtr->xScrollUnit;
if (windowUnits > 2) {
offset = listPtr->xOffset
+ count*listPtr->xScrollUnit*(windowUnits-2);
@@ -1308,12 +1314,15 @@ ListboxYviewSubCmd(
int objc, /* Number of arguments in the objv array */
Tcl_Obj *const objv[]) /* Array of arguments to the procedure */
{
- int index, count, type;
+ int index, count;
double fraction;
if (objc == 2) {
+ Tcl_Obj *results[2];
+
if (listPtr->nElements == 0) {
- Tcl_SetResult(interp, "0.0 1.0", TCL_STATIC);
+ results[0] = Tcl_NewDoubleObj(0.0);
+ results[1] = Tcl_NewDoubleObj(1.0);
} else {
double fraction2, numEls = (double) listPtr->nElements;
@@ -1322,17 +1331,17 @@ ListboxYviewSubCmd(
if (fraction2 > 1.0) {
fraction2 = 1.0;
}
- Tcl_SetObjResult(interp, Tcl_ObjPrintf("%g %g",
- fraction, fraction2));
+ results[0] = Tcl_NewDoubleObj(fraction);
+ results[1] = Tcl_NewDoubleObj(fraction2);
}
+ Tcl_SetObjResult(interp, Tcl_NewListObj(2, results));
} else if (objc == 3) {
if (GetListboxIndex(interp, listPtr, objv[2], 0, &index) != TCL_OK) {
return TCL_ERROR;
}
ChangeListboxView(listPtr, index);
} else {
- type = Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count);
- switch (type) {
+ switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {
case TK_SCROLL_MOVETO:
index = (int) (listPtr->nElements*fraction + 0.5);
break;
@@ -1383,8 +1392,7 @@ ListboxGetItemAttributes(
Tcl_HashEntry *entry;
ItemAttr *attrs;
- entry = Tcl_CreateHashEntry(listPtr->itemAttrTable,
- (char *) INT2PTR(index), &isNew);
+ entry = Tcl_CreateHashEntry(listPtr->itemAttrTable, KEY(index), &isNew);
if (isNew) {
attrs = ckalloc(sizeof(ItemAttr));
attrs->border = NULL;
@@ -1910,7 +1918,7 @@ DisplayListbox(
* special foreground/background colors.
*/
- entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(i));
/*
* If the listbox is enabled, items may be drawn differently; they may
@@ -1919,7 +1927,7 @@ DisplayListbox(
*/
if (listPtr->state & STATE_NORMAL) {
- if (Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i))) {
+ if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) {
/*
* Selected items are drawn differently.
*/
@@ -2001,8 +2009,7 @@ DisplayListbox(
}
/* Draw bottom bevel */
if (i + 1 == listPtr->nElements ||
- Tcl_FindHashEntry(listPtr->selection,
- (char *) INT2PTR(i + 1)) == NULL ) {
+ !Tcl_FindHashEntry(listPtr->selection, KEY(i + 1))) {
Tk_3DHorizontalBevel(tkwin, pixmap, selectedBg, x-left,
y + listPtr->lineHeight - listPtr->selBorderWidth,
width+left+right, listPtr->selBorderWidth, 0, 0, 0,
@@ -2238,7 +2245,7 @@ ListboxComputeGeometry(
width = listPtr->width;
if (width <= 0) {
width = (listPtr->maxWidth + listPtr->xScrollUnit - 1)
- /listPtr->xScrollUnit;
+ / listPtr->xScrollUnit;
if (width < 1) {
width = 1;
}
@@ -2439,13 +2446,13 @@ ListboxDeleteSubCmd(
* Remove selection information.
*/
- entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
if (entry != NULL) {
listPtr->numSelected--;
Tcl_DeleteHashEntry(entry);
}
- entry = Tcl_FindHashEntry(listPtr->itemAttrTable, (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(i));
if (entry != NULL) {
ckfree(Tcl_GetHashValue(entry));
Tcl_DeleteHashEntry(entry);
@@ -2739,18 +2746,12 @@ GetListboxIndex(
start = stringRep + 1;
y = strtol(start, &end, 0);
if ((start == end) || (*end != ',')) {
- Tcl_AppendResult(interp, "bad listbox index \"", stringRep,
- "\": must be active, anchor, end, @x,y, or a number",
- NULL);
- return TCL_ERROR;
+ goto badIndex;
}
start = end+1;
y = strtol(start, &end, 0);
if ((start == end) || (*end != '\0')) {
- Tcl_AppendResult(interp, "bad listbox index \"", stringRep,
- "\": must be active, anchor, end, @x,y, or a number",
- NULL);
- return TCL_ERROR;
+ goto badIndex;
}
*indexPtr = NearestListboxElement(listPtr, y);
return TCL_OK;
@@ -2768,10 +2769,11 @@ GetListboxIndex(
* Everything failed, nothing matched. Throw up an error message.
*/
- Tcl_ResetResult(interp);
- Tcl_AppendResult(interp, "bad listbox index \"",
- Tcl_GetString(indexObj), "\": must be active, anchor, ",
- "end, @x,y, or a number", NULL);
+ badIndex:
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad listbox index \"%s\": must be active, anchor, end, @x,y,"
+ " or a number", Tcl_GetString(indexObj)));
+ Tcl_SetErrorCode(interp, "TK", "VALUE", "LISTBOX_INDEX", NULL);
return TCL_ERROR;
}
@@ -2903,7 +2905,7 @@ ListboxScanTo(
*/
newTopIndex = listPtr->scanMarkYIndex
- - (10*(y - listPtr->scanMarkY))/listPtr->lineHeight;
+ - (10*(y - listPtr->scanMarkY)) / listPtr->lineHeight;
if (newTopIndex > maxIndex) {
newTopIndex = listPtr->scanMarkYIndex = maxIndex;
listPtr->scanMarkY = y;
@@ -2955,7 +2957,7 @@ NearestListboxElement(
{
int index;
- index = (y - listPtr->inset)/listPtr->lineHeight;
+ index = (y - listPtr->inset) / listPtr->lineHeight;
if (index >= (listPtr->fullLines + listPtr->partialLine)) {
index = listPtr->fullLines + listPtr->partialLine - 1;
}
@@ -3026,7 +3028,7 @@ ListboxSelect(
*/
for (i = first; i <= last; i++) {
- entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
if (entry != NULL) {
if (!select) {
Tcl_DeleteHashEntry(entry);
@@ -3037,8 +3039,8 @@ ListboxSelect(
}
} else {
if (select) {
- entry = Tcl_CreateHashEntry(listPtr->selection,
- (char *) INT2PTR(i), &isNew);
+ entry = Tcl_CreateHashEntry(listPtr->selection, KEY(i),
+ &isNew);
Tcl_SetHashValue(entry, NULL);
listPtr->numSelected++;
if (firstRedisplay < 0) {
@@ -3052,7 +3054,7 @@ ListboxSelect(
EventuallyRedrawRange(listPtr, first, last);
}
if ((oldCount == 0) && (listPtr->numSelected > 0)
- && (listPtr->exportSelection)) {
+ && listPtr->exportSelection) {
Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY,
ListboxLostSelection, listPtr);
}
@@ -3109,7 +3111,7 @@ ListboxFetchSelection(
needNewline = 0;
Tcl_DStringInit(&selection);
for (i = 0; i < listPtr->nElements; i++) {
- entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
if (entry != NULL) {
if (needNewline) {
Tcl_DStringAppend(&selection, "\n", 1);
@@ -3250,9 +3252,9 @@ ListboxUpdateVScrollbar(
first = 0.0;
last = 1.0;
} else {
- first = listPtr->topIndex / ((double) listPtr->nElements);
+ first = listPtr->topIndex / (double) listPtr->nElements;
last = (listPtr->topIndex + listPtr->fullLines)
- / ((double) listPtr->nElements);
+ / (double) listPtr->nElements;
if (last > 1.0) {
last = 1.0;
}
@@ -3309,15 +3311,15 @@ ListboxUpdateHScrollbar(
if (listPtr->xScrollCmd == NULL) {
return;
}
- windowWidth = Tk_Width(listPtr->tkwin) - 2*(listPtr->inset
- + listPtr->selBorderWidth);
+
+ windowWidth = Tk_Width(listPtr->tkwin)
+ - 2*(listPtr->inset + listPtr->selBorderWidth);
if (listPtr->maxWidth == 0) {
first = 0;
last = 1.0;
} else {
- first = listPtr->xOffset/((double) listPtr->maxWidth);
- last = (listPtr->xOffset + windowWidth)
- /((double) listPtr->maxWidth);
+ first = listPtr->xOffset / (double) listPtr->maxWidth;
+ last = (listPtr->xOffset + windowWidth) / (double) listPtr->maxWidth;
if (last > 1.0) {
last = 1.0;
}
@@ -3429,7 +3431,7 @@ ListboxListVarProc(
* Clean up selection.
*/
- entry = Tcl_FindHashEntry(listPtr->selection, (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
if (entry != NULL) {
listPtr->numSelected--;
Tcl_DeleteHashEntry(entry);
@@ -3439,8 +3441,7 @@ ListboxListVarProc(
* Clean up attributes.
*/
- entry = Tcl_FindHashEntry(listPtr->itemAttrTable,
- (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(listPtr->itemAttrTable, KEY(i));
if (entry != NULL) {
ckfree(Tcl_GetHashValue(entry));
Tcl_DeleteHashEntry(entry);
@@ -3514,23 +3515,21 @@ MigrateHashEntries(
if (offset > 0) {
for (i = last; i >= first; i--) {
- entry = Tcl_FindHashEntry(table, (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(table, KEY(i));
if (entry != NULL) {
clientData = Tcl_GetHashValue(entry);
Tcl_DeleteHashEntry(entry);
- entry = Tcl_CreateHashEntry(table,
- (char *) INT2PTR(i + offset), &isNew);
+ entry = Tcl_CreateHashEntry(table, KEY(i + offset), &isNew);
Tcl_SetHashValue(entry, clientData);
}
}
} else {
for (i = first; i <= last; i++) {
- entry = Tcl_FindHashEntry(table, (char *) INT2PTR(i));
+ entry = Tcl_FindHashEntry(table, KEY(i));
if (entry != NULL) {
clientData = Tcl_GetHashValue(entry);
Tcl_DeleteHashEntry(entry);
- entry = Tcl_CreateHashEntry(table,
- (char *) INT2PTR(i + offset), &isNew);
+ entry = Tcl_CreateHashEntry(table, KEY(i + offset), &isNew);
Tcl_SetHashValue(entry, clientData);
}
}