Index: doc/ttk_treeview.n ================================================================== --- doc/ttk_treeview.n +++ doc/ttk_treeview.n @@ -230,10 +230,17 @@ and may be reinserted at another point in the tree with the \fBmove\fR operation, but will not be displayed until that is done. The root item may not be detached. See also: \fBdelete\fR. +.TP +\fIpathname \fBdetached \fR?\fIitem\fR? +. +If \fIitem\fR is provided, returns a boolean value indicating whether it is +the name of a detached item (see \fBdetach\fR). Otherwise, returns a list of +all the detached items (in an arbitrary order). The root item is never +detached. .TP \fIpathname \fBexists \fIitem\fR Returns 1 if the specified \fIitem\fR is present in the tree, 0 otherwise. .TP Index: generic/ttk/ttkTreeview.c ================================================================== --- generic/ttk/ttkTreeview.c +++ generic/ttk/ttkTreeview.c @@ -3243,10 +3243,54 @@ TtkRedisplayWidget(&tv->core); ckfree(items); return TCL_OK; } +/* Is an item detached? The root is never detached. */ +static int IsDetached(Treeview *tv, TreeItem *item) +{ + return item->next == NULL && item->prev == NULL && + item->parent == NULL && item != tv->tree.root; +} + +/* + $tv detached ?$item? -- + * List detached items (in arbitrary order) or query the detached state of + * $item. + */ +static int TreeviewDetachedCommand( + void *recordPtr, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]) +{ + Treeview *tv = (Treeview *)recordPtr; + TreeItem *item; + + if (objc == 2) { + /* List detached items */ + Tcl_HashSearch search; + Tcl_HashEntry *entryPtr = Tcl_FirstHashEntry(&tv->tree.items, &search); + Tcl_Obj *objPtr = Tcl_NewObj(); + + while (entryPtr != NULL) { + item = Tcl_GetHashValue(entryPtr); + entryPtr = Tcl_NextHashEntry(&search); + if (IsDetached(tv, item)) { + Tcl_ListObjAppendElement(NULL, objPtr, ItemID(tv, item)); + } + } + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; + } else if (objc == 3) { + /* Query; the root is never reported as detached */ + if (!(item = FindItem(interp, tv, objv[2]))) { + return TCL_ERROR; + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(IsDetached(tv, item))); + return TCL_OK; + } else { + Tcl_WrongNumArgs(interp, 2, objv, "?item?"); + return TCL_ERROR; + } +} /* + $tv delete $items -- * Delete each item in $items. * * Do this in two passes: * First detach the item and all its descendants and remove them @@ -4351,10 +4395,11 @@ { "cget", TtkWidgetCgetCommand,0 }, { "column", TreeviewColumnCommand,0 }, { "configure", TtkWidgetConfigureCommand,0 }, { "delete", TreeviewDeleteCommand,0 }, { "detach", TreeviewDetachCommand,0 }, + { "detached", TreeviewDetachedCommand,0 }, { "drag", TreeviewDragCommand,0 }, { "drop", TreeviewDropCommand,0 }, { "exists", TreeviewExistsCommand,0 }, { "focus", TreeviewFocusCommand,0 }, { "heading", TreeviewHeadingCommand,0 }, Index: tests/ttk/treeview.test ================================================================== --- tests/ttk/treeview.test +++ tests/ttk/treeview.test @@ -189,14 +189,15 @@ } set result } -result [list 0 1 2 3 4 5 6] test treeview-3.6 "detach" -body { + set before [.tv detached newnode] .tv detach newnode consistencyCheck .tv - .tv children {} -} -result [list newfirstone firstnode anotherone onemore lastnode newlastone] + list [.tv children {}] [.tv detached] $before [.tv detached newnode] +} -result {{newfirstone firstnode anotherone onemore lastnode newlastone} newnode 0 1} # XREF: treeview-2.13 test treeview-3.7 "detach didn't screw up internal links" -body { consistencyCheck .tv set result [list] @@ -227,21 +228,23 @@ update consistencyCheck .tv } -returnCodes error -result "Cannot detach root item" test treeview-3.12 "Reattach" -body { + set before [.tv detached newnode] .tv move newnode {} end consistencyCheck .tv - .tv children {} -} -result [list newfirstone firstnode anotherone onemore lastnode newlastone newnode] + list [.tv children {}] $before [.tv detached newnode] [.tv detached] +} -result {{newfirstone firstnode anotherone onemore lastnode newlastone newnode} 1 0 {}} # Bug # ????? test treeview-3.13 "Re-reattach" -body { + set before [.tv detached newnode] .tv move newnode {} end consistencyCheck .tv - .tv children {} -} -result [list newfirstone firstnode anotherone onemore lastnode newlastone newnode] + list [.tv children {}] $before [.tv detached newnode] +} -result {{newfirstone firstnode anotherone onemore lastnode newlastone newnode} 0 0} catch { .tv insert newfirstone end -id x1 .tv insert newfirstone end -id x2 .tv insert newfirstone end -id x3