From 7d51879c281d91b4d84a4c06b0dbe2568d4c10cf Mon Sep 17 00:00:00 2001 From: treectrl Date: Sun, 19 Nov 2006 00:48:11 +0000 Subject: Added 2 optional arguments to [selection get] to perform lindex- and lrange-like operations on the sorted list of selected items. --- generic/tkTreeCtrl.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++- generic/tkTreeCtrl.h | 3 ++- generic/tkTreeItem.c | 44 ++++++++++++++++++++++++++++++++++++- 3 files changed, 106 insertions(+), 3 deletions(-) diff --git a/generic/tkTreeCtrl.c b/generic/tkTreeCtrl.c index 1b430b1..a5b1c33 100644 --- a/generic/tkTreeCtrl.c +++ b/generic/tkTreeCtrl.c @@ -7,7 +7,7 @@ * Copyright (c) 2002-2003 Christian Krone * Copyright (c) 2003-2005 ActiveState, a division of Sophos * - * RCS: @(#) $Id: tkTreeCtrl.c,v 1.86 2006/11/15 23:52:13 treectrl Exp $ + * RCS: @(#) $Id: tkTreeCtrl.c,v 1.87 2006/11/19 00:48:11 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -2724,10 +2724,70 @@ doneCLEAR: Tcl_HashEntry *hPtr; Tcl_HashSearch search; +#ifdef SELECTION_VISIBLE + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 3, objv, "?first? ?last?"); + return TCL_ERROR; + } + if (objc > 3) { + int first, last; + TreeItemList items; + + if (TclGetIntForIndex(interp, objv[3], tree->selectCount - 1, + &first) != TCL_OK) { + return TCL_ERROR; + } + if (first < 0) + first = 0; + last = first; + if (objc == 5) { + if (TclGetIntForIndex(interp, objv[4], tree->selectCount - 1, + &last) != TCL_OK) { + return TCL_ERROR; + } + } + if (last >= tree->selectCount) + last = tree->selectCount - 1; + if (first > last) + break; + + /* Build a list of selected items. */ + TreeItemList_Init(tree, &items, tree->selectCount); + hPtr = Tcl_FirstHashEntry(&tree->selection, &search); + while (hPtr != NULL) { + item = (TreeItem) Tcl_GetHashKey(&tree->selection, hPtr); + TreeItemList_Append(&items, item); + hPtr = Tcl_NextHashEntry(&search); + } + + /* Sort it. */ + TreeItemList_Sort(&items); + + if (first == last) { + item = TreeItemList_Nth(&items, first); + Tcl_SetObjResult(interp, TreeItem_ToObj(tree, item)); + } else { + listObj = Tcl_NewListObj(0, NULL); + for (index = first; index <= last; index++) { + item = TreeItemList_Nth(&items, index); + Tcl_ListObjAppendElement(interp, listObj, + TreeItem_ToObj(tree, item)); + } + Tcl_SetObjResult(interp, listObj); + } + + TreeItemList_Free(&items); + break; + } +#else /* SELECTION_VISIBLE */ + /* If any item may be selected, including orphans, then getting + * a sorted list of selected items is impossible. */ if (objc != 3) { Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); return TCL_ERROR; } +#endif /* SELECTION_VISIBLE */ + if (tree->selectCount < 1) break; listObj = Tcl_NewListObj(0, NULL); diff --git a/generic/tkTreeCtrl.h b/generic/tkTreeCtrl.h index d95e180..24d397b 100644 --- a/generic/tkTreeCtrl.h +++ b/generic/tkTreeCtrl.h @@ -7,7 +7,7 @@ * Copyright (c) 2002-2003 Christian Krone * Copyright (c) 2003 ActiveState Corporation * - * RCS: @(#) $Id: tkTreeCtrl.h,v 1.72 2006/11/12 05:47:35 treectrl Exp $ + * RCS: @(#) $Id: tkTreeCtrl.h,v 1.73 2006/11/19 00:48:14 treectrl Exp $ */ #include "tkPort.h" @@ -950,6 +950,7 @@ extern void TreePtrList_Free(TreePtrList *tilPtr); #define TreeItemList_Items(L) ((TreeItem *) (L)->pointers) #define TreeItemList_Nth(L,n) ((TreeItem) (L)->pointers[n]) #define TreeItemList_Count(L) ((L)->count) +extern void TreeItemList_Sort(TreeItemList *items); #define TreeColumnList_Init TreePtrList_Init #define TreeColumnList_Append TreePtrList_Append diff --git a/generic/tkTreeItem.c b/generic/tkTreeItem.c index 75300af..c23649d 100644 --- a/generic/tkTreeItem.c +++ b/generic/tkTreeItem.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2006 Tim Baker * - * RCS: @(#) $Id: tkTreeItem.c,v 1.90 2006/11/18 04:35:55 treectrl Exp $ + * RCS: @(#) $Id: tkTreeItem.c,v 1.91 2006/11/19 00:48:14 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -6491,6 +6491,48 @@ ItemSortCmd( /* *---------------------------------------------------------------------- * + * TreeItemList_Sort -- + * + * Sorts a list of items. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +TILSCompare( + CONST VOID *first_, + CONST VOID *second_ + ) +{ + TreeItem first = *(TreeItem *) first_; + TreeItem second = *(TreeItem *) second_; + + return first->index - second->index; +} + +void +TreeItemList_Sort( + TreeItemList *items + ) +{ + Tree_UpdateItemIndex(items->tree); + + /* TkTable uses this, but mentions possible lack of thread-safety. */ + qsort((VOID *) TreeItemList_Items(items), + (size_t) TreeItemList_Count(items), + sizeof(TreeItem), + TILSCompare); +} + +/* + *---------------------------------------------------------------------- + * * ItemStateCmd -- * * This procedure is invoked to process the [item state] widget -- cgit v0.12