From f0e924b9c668530de9524084ee2da9fb7077fe32 Mon Sep 17 00:00:00 2001 From: treectrl Date: Fri, 13 Aug 2004 20:24:15 +0000 Subject: Only ReallyVisible() items may be selected. --- generic/tkTreeCtrl.c | 62 +++++++++++++++++++++++++++++++----- generic/tkTreeItem.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 134 insertions(+), 17 deletions(-) diff --git a/generic/tkTreeCtrl.c b/generic/tkTreeCtrl.c index 56e8679..8906668 100644 --- a/generic/tkTreeCtrl.c +++ b/generic/tkTreeCtrl.c @@ -7,7 +7,7 @@ * Copyright (c) 2002-2003 Christian Krone * Copyright (c) 2003 ActiveState Corporation * - * RCS: @(#) $Id: tkTreeCtrl.c,v 1.23 2004/08/11 00:32:08 treectrl Exp $ + * RCS: @(#) $Id: tkTreeCtrl.c,v 1.24 2004/08/13 20:24:15 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -511,6 +511,9 @@ static int TreeWidgetCmd(ClientData clientData, Tcl_Interp *interp, int objc, } recurse = oldRecurse; } +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif #if 0 if (tree->debug.enable) Tree_Debug(tree); @@ -1762,14 +1765,20 @@ void Tree_AddToSelection(TreeCtrl *tree, TreeItem item) { Tcl_HashEntry *hPtr; int isNew; - + +#ifdef SELECTION_VISIBLE + if (!TreeItem_ReallyVisible(tree, item)) + panic("Tree_AddToSelection: item %d not ReallyVisible", + TreeItem_GetID(tree, item)); +#endif if (TreeItem_GetSelected(tree, item)) panic("Tree_AddToSelection: item %d already selected", TreeItem_GetID(tree, item)); TreeItem_ChangeState(tree, item, 0, STATE_SELECTED); hPtr = Tcl_CreateHashEntry(&tree->selection, (char *) item, &isNew); if (!isNew) - panic("Tree_AddToSelection: item %d already in selection hash table"); + panic("Tree_AddToSelection: item %d already in selection hash table", + TreeItem_GetID(tree, item)); tree->selectCount++; } @@ -1783,7 +1792,8 @@ void Tree_RemoveFromSelection(TreeCtrl *tree, TreeItem item) TreeItem_ChangeState(tree, item, STATE_SELECTED, 0); hPtr = Tcl_FindHashEntry(&tree->selection, (char *) item); if (hPtr == NULL) - panic("Tree_RemoveFromSelection: item %d not found in selection hash table"); + panic("Tree_RemoveFromSelection: item %d not found in selection hash table", + TreeItem_GetID(tree, item)); Tcl_DeleteHashEntry(hPtr); tree->selectCount--; } @@ -1839,7 +1849,12 @@ static int TreeSelectionCmd(Tcl_Interp *interp, hPtr = Tcl_FirstHashEntry(&tree->itemHash, &search); while (hPtr != NULL) { item = (TreeItem) Tcl_GetHashValue(hPtr); +#ifdef SELECTION_VISIBLE + if (!TreeItem_GetSelected(tree, item) && + TreeItem_ReallyVisible(tree, item)) { +#else if (!TreeItem_GetSelected(tree, item)) { +#endif Tree_AddToSelection(tree, item); items[count++] = item; } @@ -1876,7 +1891,12 @@ static int TreeSelectionCmd(Tcl_Interp *interp, count = 0; item = itemFirst; while (item != NULL) { +#ifdef SELECTION_VISIBLE + if (!TreeItem_GetSelected(tree, item) && + TreeItem_ReallyVisible(tree, item)) { +#else if (!TreeItem_GetSelected(tree, item)) { +#endif Tree_AddToSelection(tree, item); items[count++] = item; } @@ -2085,7 +2105,18 @@ doneCLEAR: count = tree->itemCount - tree->selectCount; STATIC_ALLOC(newS, TreeItem, count + 1); count = 0; - +#ifdef SELECTION_VISIBLE + item = tree->root; + if (!TreeItem_ReallyVisible(tree, item)) + item = TreeItem_NextVisible(tree, item); + while (item != NULL) { + if (!TreeItem_GetSelected(tree, item)) { + Tree_AddToSelection(tree, item); + newS[count++] = item; + } + item = TreeItem_NextVisible(tree, item); + } +#else /* Include detached items */ hPtr = Tcl_FirstHashEntry(&tree->itemHash, &search); while (hPtr != NULL) { @@ -2096,6 +2127,7 @@ doneCLEAR: } hPtr = Tcl_NextHashEntry(&search); } +#endif if (count) { newS[count] = NULL; TreeNotify_Selection(tree, newS, NULL); @@ -2112,6 +2144,10 @@ doneCLEAR: item = itemS[i]; if (TreeItem_GetSelected(tree, item)) continue; +#ifdef SELECTION_VISIBLE + if (!TreeItem_ReallyVisible(tree, item)) + continue; +#endif /* Add unique item to newly-selected list */ for (j = 0; j < count; j++) if (newS[j] == item) @@ -2156,10 +2192,11 @@ doneCLEAR: hPtr = Tcl_FirstHashEntry(&tree->selection, &search); while (hPtr != NULL) { item = (TreeItem) Tcl_GetHashKey(&tree->selection, hPtr); - Tree_RemoveFromSelection(tree, item); newD[count++] = item; hPtr = Tcl_NextHashEntry(&search); } + for (i = 0; i < count; i++) + Tree_RemoveFromSelection(tree, newD[i]); if (count) { newD[count] = NULL; TreeNotify_Selection(tree, NULL, newD); @@ -2203,6 +2240,10 @@ doneCLEAR: item = itemS[i]; if (TreeItem_GetSelected(tree, item)) continue; +#ifdef SELECTION_VISIBLE + if (!TreeItem_ReallyVisible(tree, item)) + continue; +#endif /* Add unique item to newly-selected list */ for (j = 0; j < countS; j++) if (newS[j] == item) @@ -2256,17 +2297,22 @@ doneCLEAR: if (item == itemS[j]) break; if (j == objcS) { - Tree_RemoveFromSelection(tree, item); newD[countD++] = item; } hPtr = Tcl_NextHashEntry(&search); } + for (i = 0; i < countD; i++) + Tree_RemoveFromSelection(tree, newD[i]); STATIC_ALLOC(newS, TreeItem, objcS + 1); countS = 0; for (i = 0; i < objcS; i++) { item = itemS[i]; if (TreeItem_GetSelected(tree, item)) continue; +#ifdef SELECTION_VISIBLE + if (!TreeItem_ReallyVisible(tree, item)) + continue; +#endif /* Add unique item to newly-selected list */ for (j = 0; j < countS; j++) if (newS[j] == item) @@ -2945,7 +2991,7 @@ DLLEXPORT int Treectrl_Init(Tcl_Interp *interp) #endif #endif Tcl_CreateObjCommand(interp, "treectrl", TreeObjCmd, NULL, NULL); - return Tcl_PkgProvide(interp, "treectrl", "1.0"); + return Tcl_PkgProvide(interp, "treectrl", "1.1"); } DLLEXPORT int Treectrl_SafeInit(Tcl_Interp *interp) diff --git a/generic/tkTreeItem.c b/generic/tkTreeItem.c index d5a38dd..c609f10 100644 --- a/generic/tkTreeItem.c +++ b/generic/tkTreeItem.c @@ -5,7 +5,7 @@ * * Copyright (c) 2002-2004 Tim Baker * - * RCS: @(#) $Id: tkTreeItem.c,v 1.21 2004/08/11 00:35:21 treectrl Exp $ + * RCS: @(#) $Id: tkTreeItem.c,v 1.22 2004/08/13 20:26:55 treectrl Exp $ */ #include "tkTreeCtrl.h" @@ -1138,6 +1138,7 @@ void TreeItem_AddToParent(TreeCtrl *tree, TreeItem item_) TreeItem_UpdateDepth(tree, item_); Tree_InvalidateColumnWidth(tree, -1); + if (tree->debug.enable && tree->debug.data) Tree_Debug(tree); } @@ -1820,7 +1821,11 @@ void TreeItem_DrawButton(TreeCtrl *tree, TreeItem item_, int x, int y, int width int TreeItem_ReallyVisible(TreeCtrl *tree, TreeItem item_) { Item *self = (Item *) item_; - +#if 0 + if (tree->updateIndex) + Tree_UpdateItemIndex(tree); + return self->indexVis != -1; +#else if (!tree->updateIndex) return self->indexVis != -1; @@ -1840,6 +1845,7 @@ int TreeItem_ReallyVisible(TreeCtrl *tree, TreeItem item_) if (!self->parent->isVisible || !(self->parent->state & STATE_OPEN)) return 0; return TreeItem_ReallyVisible(tree, (TreeItem) self->parent); +#endif } TreeItem TreeItem_RootAncestor(TreeCtrl *tree, TreeItem item_) @@ -1934,6 +1940,10 @@ static int Item_Configure(TreeCtrl *tree, Item *item, int objc, tree->updateIndex = 1; Tree_DInfoChanged(tree, DINFO_REDO_RANGES); + +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif } return TCL_OK; @@ -2001,7 +2011,7 @@ static int ItemElementCmd(ClientData clientData, Tcl_Interp *interp, int objc, { int result, eMask; - result = TreeStyle_ElementConfigure(tree, column->style, objv[6], + result = TreeStyle_ElementConfigure(tree, (TreeItem) item, column->style, objv[6], objc - 7, (Tcl_Obj **) objv + 7, &eMask); if (eMask != 0) { @@ -3288,7 +3298,7 @@ static int ItemStateCmd(ClientData clientData, Tcl_Interp *interp, int objc, /* Basically same as "selection clear" */ static void ItemDeleteDeselect(TreeCtrl *tree, TreeItem itemFirst, TreeItem itemLast) { - int indexFirst, indexLast, count; + int i, indexFirst, indexLast, count; TreeItem staticItems[STATIC_SIZE], *items = staticItems; Tcl_HashEntry *hPtr; Tcl_HashSearch search; @@ -3299,7 +3309,6 @@ static void ItemDeleteDeselect(TreeCtrl *tree, TreeItem itemFirst, TreeItem item STATIC_ALLOC(items, TreeItem, count + 1); count = 0; - /* Include detached items */ hPtr = Tcl_FirstHashEntry(&tree->selection, &search); while (hPtr != NULL) { item = (TreeItem) Tcl_GetHashKey(&tree->selection, hPtr); @@ -3308,12 +3317,13 @@ static void ItemDeleteDeselect(TreeCtrl *tree, TreeItem itemFirst, TreeItem item hPtr = Tcl_NextHashEntry(&search); if (hPtr == NULL) break; - item = (TreeItem) Tcl_GetHashValue(hPtr); + item = (TreeItem) Tcl_GetHashKey(&tree->selection, hPtr); } - Tree_RemoveFromSelection(tree, item); items[count++] = item; hPtr = Tcl_NextHashEntry(&search); } + for (i = 0; i < count; i++) + Tree_RemoveFromSelection(tree, items[i]); goto doneCLEAR; } if (itemFirst == itemLast) { @@ -3354,6 +3364,46 @@ doneCLEAR: STATIC_FREE2(items, staticItems); } +#ifdef SELECTION_VISIBLE +/* FIXME: optimize all calls to this routine */ +void Tree_DeselectHidden(TreeCtrl *tree) +{ + TreeItem staticItems[STATIC_SIZE], *items = staticItems; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + TreeItem item; + int i, count; + + if (tree->selectCount < 1) + return; + + if (tree->updateIndex) + Tree_UpdateItemIndex(tree); + + count = tree->selectCount; + STATIC_ALLOC(items, TreeItem, count + 1); + count = 0; + + hPtr = Tcl_FirstHashEntry(&tree->selection, &search); + while (hPtr != NULL) + { + item = (TreeItem) Tcl_GetHashKey(&tree->selection, hPtr); + if (!TreeItem_ReallyVisible(tree, item)) + items[count++] = item; + hPtr = Tcl_NextHashEntry(&search); + } + for (i = 0; i < count; i++) + Tree_RemoveFromSelection(tree, items[i]); + + if (count) + { + items[count] = NULL; + TreeNotify_Selection(tree, NULL, items); + } + STATIC_FREE2(items, staticItems); +} +#endif /* SELECTION_VISIBLE */ + int TreeItemCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { @@ -3701,9 +3751,15 @@ int TreeItemCmd(ClientData clientData, Tcl_Interp *interp, int objc, TreeItem_OpenClose(tree, (TreeItem) item, mode, 0); hPtr = Tcl_NextHashEntry(&search); } +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif break; } TreeItem_OpenClose(tree, (TreeItem) item, mode, recurse); +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif break; } case COMMAND_COMPLEX: @@ -3761,7 +3817,7 @@ int TreeItemCmd(ClientData clientData, Tcl_Interp *interp, int objc, result = TCL_ERROR; goto doneComplex; } - if (TreeStyle_ElementConfigure(tree, column->style, + if (TreeStyle_ElementConfigure(tree, (TreeItem) item, column->style, objv2[0], objc2 - 1, objv2 + 1, &eMask) != TCL_OK) { result = TCL_ERROR; @@ -3951,6 +4007,9 @@ doneComplex: item2->parent = item; item->numChildren++; TreeItem_AddToParent(tree, (TreeItem) item2); +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif } if (item->firstChild != NULL) Tcl_SetObjResult(interp, TreeItem_ToObj(tree, (TreeItem) item->firstChild)); @@ -3988,6 +4047,9 @@ doneComplex: item2->parent = item; item->numChildren++; TreeItem_AddToParent(tree, (TreeItem) item2); +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif } if (item->lastChild != NULL) Tcl_SetObjResult(interp, TreeItem_ToObj(tree, (TreeItem) item->lastChild)); @@ -4010,6 +4072,9 @@ doneComplex: item2->parent = item->parent; item->parent->numChildren++; TreeItem_AddToParent(tree, (TreeItem) item2); +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif } if (item->nextSibling != NULL) Tcl_SetObjResult(interp, TreeItem_ToObj(tree, (TreeItem) item->nextSibling)); @@ -4043,6 +4108,9 @@ doneComplex: item2->parent = item->parent; item->parent->numChildren++; TreeItem_AddToParent(tree, (TreeItem) item2); +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif } if (item->prevSibling != NULL) Tcl_SetObjResult(interp, TreeItem_ToObj(tree, (TreeItem) item->prevSibling)); @@ -4057,6 +4125,9 @@ doneComplex: Tree_Debug(tree); Tree_InvalidateColumnWidth(tree, -1); Tree_FreeItemDInfo(tree, (TreeItem) item, NULL); +#ifdef SELECTION_VISIBLE + Tree_DeselectHidden(tree); +#endif break; } case COMMAND_RNC: @@ -4118,7 +4189,7 @@ doneComplex: itemPrefix, item->id, columnIndex); return TCL_ERROR; } - TreeStyle_SetText(tree, column->style, objv[i + 1]); + TreeStyle_SetText(tree, (TreeItem) item, column->style, objv[i + 1]); column->neededWidth = column->neededHeight = -1; Tree_InvalidateColumnWidth(tree, columnIndex); } -- cgit v0.12