summaryrefslogtreecommitdiffstats
path: root/generic/tkTreeItem.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkTreeItem.c')
-rw-r--r--generic/tkTreeItem.c118
1 files changed, 91 insertions, 27 deletions
diff --git a/generic/tkTreeItem.c b/generic/tkTreeItem.c
index ce22ad6..199aff5 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.73 2006/10/29 02:33:02 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeItem.c,v 1.74 2006/10/30 23:03:22 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -63,7 +63,7 @@ static CONST char *ItemUid = "Item", *ItemColumnUid = "ItemColumn";
#define IS_ALL(i) (((TreeItem) i) == ITEM_ALL)
-#define IS_DELETED(i) (((i)->flags & ITEM_FLAG_DELETED) != 0)
+#define IS_DELETED(i) ((((Item *) i)->flags & ITEM_FLAG_DELETED) != 0)
/*
* Flags returned by Tk_SetOptions() (see itemOptionSpecs below).
@@ -1691,6 +1691,7 @@ Qualifiers_Free(
* "ID MODIFIERS"
* -- returning multiple items --
* all QUALIFIERS
+ * QUALIFIERS (like "all QUALIFIERS")
* list listOfItemDescs
* range QUALIFIERS
* tag tagExpr QUALIFIERS
@@ -1723,9 +1724,9 @@ Qualifiers_Free(
* QUALIFIERS:
* depth integer
* state stateList
+ * tag tagExpr
* visible
* !visible
- * tag tagExpr
*
* Examples:
* $T item id "first visible firstchild"
@@ -1759,7 +1760,7 @@ TreeItemList_FromObj(
Tcl_Obj **objv, *elemPtr;
Item *item = NULL;
Qualifiers q;
- int qualArgsTotal = 0;
+ int qualArgsTotal;
static CONST char *indexName[] = {
"active", "all", "anchor", "end", "first", "last", "list",
@@ -2539,7 +2540,7 @@ Item_ToggleOpen(
*
* TreeItem_OpenClose --
*
- * Inverts the STATE_OPEN flag of an Item, possibly recursively.
+ * Inverts the STATE_OPEN flag of an Item.
*
* Results:
* Items may be displayed/undisplayed.
@@ -2555,17 +2556,18 @@ void
TreeItem_OpenClose(
TreeCtrl *tree, /* Widget info. */
TreeItem item_, /* Item token. */
- int mode, /* -1: toggle
+ int mode /* -1: toggle
* 0: close
* 1: open */
- int recurse /* TRUE to perform same op on descendants,
- * FALSE to only affect given item. */
)
{
Item *item = (Item *) item_;
- Item *child;
int stateOff = 0, stateOn = 0;
+ /* When processing a list of items, any <Expand> or <Collapse> event
+ * may result in items being deleted. */
+ if (IS_DELETED(item_)) return;
+
if (mode == -1) {
if (item->state & STATE_OPEN)
stateOff = STATE_OPEN;
@@ -2578,13 +2580,10 @@ TreeItem_OpenClose(
if (stateOff != stateOn) {
TreeNotify_OpenClose(tree, item_, stateOn, TRUE);
+ if (IS_DELETED(item_)) return;
Item_ToggleOpen(tree, item, stateOff, stateOn);
TreeNotify_OpenClose(tree, item_, stateOn, FALSE);
}
- if (recurse) {
- for (child = item->firstChild; child != NULL; child = child->nextSibling)
- TreeItem_OpenClose(tree, (TreeItem) child, mode, recurse);
- }
}
/*
@@ -2637,6 +2636,31 @@ TreeItem_Delete(
/*
*----------------------------------------------------------------------
*
+ * TreeItem_Deleted --
+ *
+ * Return 1 if the given item is deleted.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TreeItem_Deleted(
+ TreeCtrl *tree, /* Widget info. */
+ TreeItem item_ /* Item token. */
+ )
+{
+ return IS_DELETED(item_);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TreeItem_FirstAndLast --
*
* Determine the order of two items and swap them if needed.
@@ -3173,10 +3197,37 @@ TreeItem_FreeResources(
if (self->rInfo != NULL)
Tree_FreeItemRInfo(tree, item_);
Tk_FreeConfigOptions((char *) self, tree->itemOptionTable, tree->tkwin);
+
+ /* Add the item record to the "preserved" list. It will be freed later. */
+ TreeItemList_Append(&tree->preserveItemList, item_);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TreeItem_Release --
+ *
+ * Finally free an item record when it is no longer needed.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Memory is deallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TreeItem_Release(
+ TreeCtrl *tree, /* Widget info. */
+ TreeItem item_ /* Item token. */
+ )
+{
#ifdef ALLOC_HAX
- AllocHax_Free(tree->allocData, ItemUid, (char *) self, sizeof(Item));
+ AllocHax_Free(tree->allocData, ItemUid, (char *) item_, sizeof(Item));
#else
- WFREE(self, Item);
+ WFREE(item_, Item);
#endif
}
@@ -7233,8 +7284,9 @@ TreeItemCmd(
ItemForEach iter;
if (numArgs == 2) {
- char *s = Tcl_GetString(objv[4]);
- if (strcmp(s, "-recurse")) {
+ int len;
+ char *s = Tcl_GetStringFromObj(objv[4], &len);
+ if (strncmp(s, "-recurse", len)) {
FormatResult(interp, "bad option \"%s\": must be -recurse",
s);
goto errorExit;
@@ -7262,7 +7314,7 @@ TreeItemCmd(
count = TreeItemList_Count(&items);
for (i = 0; i < count; i++) {
_item = TreeItemList_Nth(&items, i);
- TreeItem_OpenClose(tree, _item, mode, FALSE);
+ TreeItem_OpenClose(tree, _item, mode);
}
TreeItemList_Free(&items);
#ifdef SELECTION_VISIBLE
@@ -7462,9 +7514,9 @@ TreeItemCmd(
if (IS_DELETED(item))
continue;
item->flags |= ITEM_FLAG_DELETED;
- TreeItemList_Append(&deleted, (TreeItem) item);
- if (TreeItem_GetSelected(tree, (TreeItem) item))
- TreeItemList_Append(&selected, (TreeItem) item);
+ TreeItemList_Append(&deleted, _item);
+ if (TreeItem_GetSelected(tree, _item))
+ TreeItemList_Append(&selected, _item);
if (iter.all)
continue;
/* Check every descendant. */
@@ -7475,15 +7527,16 @@ TreeItemCmd(
item2 = item2->lastChild;
item = item->firstChild;
while (1) {
+ _item = (TreeItem) item;
if (IS_DELETED(item)) {
/* Skip all descendants (they are already flagged). */
while (item->lastChild != NULL)
item = item->lastChild;
} else {
item->flags |= ITEM_FLAG_DELETED;
- TreeItemList_Append(&deleted, (TreeItem) item);
- if (TreeItem_GetSelected(tree, (TreeItem) item))
- TreeItemList_Append(&selected, (TreeItem) item);
+ TreeItemList_Append(&deleted, _item);
+ if (TreeItem_GetSelected(tree, _item))
+ TreeItemList_Append(&selected, _item);
}
if (item == item2)
break;
@@ -7506,9 +7559,20 @@ TreeItemCmd(
/* Generate <ItemDelete> event for items being deleted. */
TreeNotify_ItemDeleted(tree, &deleted);
- /* Add deleted items to the preserved list so they can be
- * freed when no longer in use. */
- TreeItemList_Concat(&tree->preserveItemList, &deleted);
+ /* Remove every item from its parent. Needed because items
+ * are deleted recursively. */
+ for (i = 0; i < count; i++) {
+ _item = TreeItemList_Nth(&deleted, i);
+ TreeItem_RemoveFromParent(tree, _item);
+ }
+
+ /* Delete the items. The item record will be freed when no
+ * longer in use; however, the item cannot be referred to
+ * by commands from this point on. */
+ for (i = 0; i < count; i++) {
+ _item = TreeItemList_Nth(&deleted, i);
+ TreeItem_Delete(tree, _item);
+ }
}
TreeItemList_Free(&selected);