summaryrefslogtreecommitdiffstats
path: root/generic/tkTreeItem.c
diff options
context:
space:
mode:
authortreectrl <treectrl>2006-09-22 23:25:23 (GMT)
committertreectrl <treectrl>2006-09-22 23:25:23 (GMT)
commitecf002382d4b4eefc337852f9874541c4e240083 (patch)
tree672da38b4ac7540d1aa6a6a390da2c6df9ec3224 /generic/tkTreeItem.c
parent04f581211a0cfe3a379fa158a46f6ec2d64c83dc (diff)
downloadtktreectrl-ecf002382d4b4eefc337852f9874541c4e240083.zip
tktreectrl-ecf002382d4b4eefc337852f9874541c4e240083.tar.gz
tktreectrl-ecf002382d4b4eefc337852f9874541c4e240083.tar.bz2
Use new Tree_StateFromListObj for getting state flags from a list object.
Added TreeForEach_xxx to make iterating over item-list arguments easier. Fix TreeItem_ListDescendants; it was appending the given item and skipping the last descendant. Rewrote the following commands to accept multi-item item descriptions: item element configure item image item style map item style set item state forcolumn item state set item remove item span item text
Diffstat (limited to 'generic/tkTreeItem.c')
-rw-r--r--generic/tkTreeItem.c1075
1 files changed, 665 insertions, 410 deletions
diff --git a/generic/tkTreeItem.c b/generic/tkTreeItem.c
index da23ab7..166bca2 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.61 2006/09/21 06:35:11 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeItem.c,v 1.62 2006/09/22 23:25:23 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -1526,16 +1526,9 @@ GatherQualifiers(
switch ((enum qualEnum) qual) {
case QUAL_STATE:
{
- int i, listObjc;
- Tcl_Obj **listObjv;
- if (Tcl_ListObjGetElements(interp, objv[j + 1],
- &listObjc, &listObjv) != TCL_OK)
+ if (Tree_StateFromListObj(tree, objv[j + 1], states,
+ SFO_NOT_TOGGLE) != TCL_OK)
return TCL_ERROR;
- for (i = 0; i < listObjc; i++) {
- if (Tree_StateFromObj(tree, listObjv[i], states,
- NULL, SFO_NOT_TOGGLE) != TCL_OK)
- return TCL_ERROR;
- }
break;
}
case QUAL_VISIBLE:
@@ -2177,6 +2170,125 @@ TreeItem_FromObj(
return TCL_OK;
}
+typedef struct TreeForEach TreeForEach;
+struct TreeForEach {
+ TreeCtrl *tree;
+ int error;
+ int all;
+ Tcl_HashSearch search;
+ TreeItem last;
+ TreeItem item;
+ TreeItemList *items;
+ int index;
+};
+
+#define TREE_FOR_EACH(item, items, item2s, iter) \
+ for (item = TreeForEach_Start(items, item2s, iter); \
+ item != NULL; \
+ item = TreeForEach_Next(iter))
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TreeForEach_Start --
+ *
+ * Begin iterating over items. A command might accept two item
+ * descriptions for a range of items, or a single item description
+ * which may itself refer to multiple items. Either item
+ * description could be ITEM_ALL.
+ *
+ * Results:
+ * Returns the first item to iterate over. If an error occurs
+ * then TreeForEach.error is set to 1.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TreeItem
+TreeForEach_Start(
+ TreeItemList *items, /* List of items. */
+ TreeItemList *item2s, /* List of items or NULL. */
+ TreeForEach *iter /* Returned info, pass to
+ TreeForEach_Next. */
+ )
+{
+ TreeCtrl *tree = items->tree;
+ TreeItem item, item2 = NULL;
+
+ item = TreeItemList_ItemN(items, 0);
+ if (item2s)
+ item2 = TreeItemList_ItemN(item2s, 0);
+
+ iter->tree = tree;
+ iter->all = FALSE;
+ iter->error = 0;
+ iter->items = NULL;
+
+ if (item == ITEM_ALL || item2 == ITEM_ALL) {
+ Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(&tree->itemHash, &iter->search);
+ iter->all = TRUE;
+ return iter->item = (TreeItem) Tcl_GetHashValue(hPtr);
+ }
+
+ if (item2 != NULL) {
+ if (TreeItem_FirstAndLast(tree, &item, &item2) == 0) {
+ iter->error = 1;
+ return NULL;
+ }
+ iter->last = item2;
+ return iter->item = item;
+ }
+
+ iter->items = items;
+ iter->index = 0;
+ return iter->item = item;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TreeForEach_Next --
+ *
+ * Returns the next item to iterate over. Keep calling this until
+ * the result is NULL.
+ *
+ * Results:
+ * Returns the next item to iterate over or NULL.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TreeItem
+TreeForEach_Next(
+ TreeForEach *iter /* Initialized by TreeForEach_Start. */
+ )
+{
+ TreeCtrl *tree = iter->tree;
+
+ if (iter->all) {
+ Tcl_HashEntry *hPtr = Tcl_NextHashEntry(&iter->search);
+ if (hPtr == NULL)
+ return iter->item = NULL;
+ return iter->item = (TreeItem) Tcl_GetHashValue(hPtr);
+ }
+
+ if (iter->items != NULL) {
+ if (iter->index >= TreeItemList_Count(iter->items))
+ return iter->item = NULL;
+ return iter->item = TreeItemList_ItemN(iter->items, ++iter->index);
+ }
+
+ if (iter->item == iter->last)
+ return iter->item = NULL;
+ return iter->item = TreeItem_Next(tree, iter->item);
+}
+
/*
*----------------------------------------------------------------------
*
@@ -2407,11 +2519,16 @@ TreeItem_ListDescendants(
Item *item = (Item *) item_;
Item *last;
+ if (item->firstChild == NULL)
+ return;
last = item;
while (last->lastChild != NULL)
last = last->lastChild;
- while (item_ != (TreeItem) last) {
+ item_ = (TreeItem) item->firstChild;
+ while (1) {
TreeItemList_Append(items, item_);
+ if (item_ == (TreeItem) last)
+ break;
item_ = TreeItem_Next(tree, item_);
}
}
@@ -3691,8 +3808,8 @@ TreeItem_DrawButton(
return;
#if defined(MAC_TCL) || defined(MAC_OSX_TK)
- /* QuickDraw on Mac is offset by one pixel in both x and y. */
- macoffset = 1;
+ /* QuickDraw on Mac is offset by one pixel in both x and y. */
+ macoffset = 1;
#endif
indent = TreeItem_Indent(tree, item_);
@@ -4384,8 +4501,10 @@ ItemElementCmd(
int index;
int columnIndex;
Column *column;
+ TreeItemList itemList;
TreeItem _item;
Item *item;
+ int result = TCL_OK;
if (objc < 7) {
Tcl_WrongNumArgs(interp, 3, objv, "command item column element ?arg ...?");
@@ -4396,49 +4515,59 @@ ItemElementCmd(
&index) != TCL_OK)
return TCL_ERROR;
- if (TreeItem_FromObj(tree, objv[4], &_item, 0) != TCL_OK)
- return TCL_ERROR;
- item = (Item *) _item;
-
- if (Item_FindColumnFromObj(tree, item, objv[5], &column, &columnIndex) != TCL_OK)
- return TCL_ERROR;
-
- if ((column == NULL) || (column->style == NULL)) {
- NoStyleMsg(tree, item, columnIndex);
+ if (TreeItemList_FromObj(tree, objv[4], &itemList, IFO_ALLOK) != TCL_OK)
return TCL_ERROR;
+ _item = TreeItemList_ItemN(&itemList, 0);
+ /*
+ * [configure] without an option-value pair can operate on a single item
+ * only. [cget] and [perstate] only operate on a single item.
+ */
+ if ((_item == ITEM_ALL) && ((index != COMMAND_CONFIGURE) || (objc < 9)))
+ _item = tree->root;
+ else if ((index == COMMAND_CONFIGURE) && (objc < 9)) {
+ itemList.items[1] = NULL;
+ itemList.count = 1;
+ _item = itemList.items[0];
}
+ item = (Item *) _item;
switch (index) {
/* T item element perstate I C E option ?stateList? */
case COMMAND_ACTUAL:
case COMMAND_PERSTATE:
{
- int state = item->state | column->cstate;
+ int state;
if (objc < 8 || objc > 9) {
Tcl_WrongNumArgs(tree->interp, 4, objv,
"item column element option ?stateList?");
- return TCL_ERROR;
+ result = TCL_ERROR;
+ break;
+ }
+ if (Item_FindColumnFromObj(tree, item, objv[5], &column,
+ &columnIndex) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
}
+ if ((column == NULL) || (column->style == NULL)) {
+ NoStyleMsg(tree, item, columnIndex);
+ result = TCL_ERROR;
+ break;
+ }
+ state = item->state | column->cstate;
if (objc == 9) {
- int i, listObjc;
- Tcl_Obj **listObjv;
int states[3];
- if (Tcl_ListObjGetElements(interp, objv[8], &listObjc,
- &listObjv) != TCL_OK)
- return TCL_ERROR;
-
- states[0] = states[1] = states[2] = 0;
- for (i = 0; i < listObjc; i++) {
- if (Tree_StateFromObj(tree, listObjv[i], states, NULL,
- SFO_NOT_OFF | SFO_NOT_TOGGLE) != TCL_OK)
- return TCL_ERROR;
+ if (Tree_StateFromListObj(tree, objv[8], states,
+ SFO_NOT_OFF | SFO_NOT_TOGGLE) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
}
state = states[STATE_OP_ON];
}
- return TreeStyle_ElementActual(tree, column->style,
+ result = TreeStyle_ElementActual(tree, column->style,
state, objv[6], objv[7]);
+ break;
}
/* T item element cget I C E option */
@@ -4447,114 +4576,150 @@ ItemElementCmd(
if (objc != 8) {
Tcl_WrongNumArgs(tree->interp, 4, objv,
"item column element option");
- return TCL_ERROR;
+ result = TCL_ERROR;
+ break;
}
- return TreeStyle_ElementCget(tree, (TreeItem) item,
+ if (Item_FindColumnFromObj(tree, item, objv[5], &column,
+ &columnIndex) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
+ }
+ if ((column == NULL) || (column->style == NULL)) {
+ NoStyleMsg(tree, item, columnIndex);
+ result = TCL_ERROR;
+ break;
+ }
+ result = TreeStyle_ElementCget(tree, (TreeItem) item,
(TreeItemColumn) column, column->style, objv[6], objv[7]);
+ break;
}
/* T item element configure I C E ... */
case COMMAND_CONFIGURE:
{
- /* T item element configure I C E option value \
- * + E option value , C E option value */
- int eMask, cMask = 0, iMask = 0;
- int indexElem = 6;
- int result;
+ TreeForEach iter;
+ TreeColumn treeColumn;
+ int columnIndex0;
- while (1) {
- int numArgs = 0;
- char breakChar = '\0';
+ if (TreeColumn_FromObj(tree, objv[5], &treeColumn,
+ CFO_NOT_ALL | CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
+ }
+ columnIndex0 = TreeColumn_Index(treeColumn);
- /* Look for a + or , */
- for (index = indexElem + 1; index < objc; index++) {
- if (numArgs % 2 == 0) {
- int length;
- char *s = Tcl_GetStringFromObj(objv[index], &length);
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
- if ((length == 1) && ((s[0] == '+') || (s[0] == ','))) {
- breakChar = s[0];
- break;
- }
- }
- numArgs++;
- }
+ /* T item element configure I C E option value \
+ * + E option value , C E option value */
+ int eMask, cMask = 0, iMask = 0;
+ int indexElem = 6;
- /* Require at least one option-value pair if more than one
- * element is specified */
- if (breakChar && numArgs < 2) {
- FormatResult(interp,
- "missing option-value pair after element \"%s\"",
- Tcl_GetString(objv[indexElem]));
+ item = (Item *) _item;
+ column = Item_FindColumn(tree, item, columnIndex0);
+ if ((column == NULL) || (column->style == NULL)) {
+ NoStyleMsg(tree, item, columnIndex0);
result = TCL_ERROR;
break;
}
- result = TreeStyle_ElementConfigure(tree, (TreeItem) item,
- (TreeItemColumn) column, column->style, objv[indexElem],
- numArgs, (Tcl_Obj **) objv + indexElem + 1, &eMask);
- if (result != TCL_OK)
- break;
+ while (1) {
+ int numArgs = 0;
+ char breakChar = '\0';
- cMask |= eMask;
- if (cMask & CS_LAYOUT) {
- TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
- Tree_InvalidateColumnWidth(tree, columnIndex);
- }
- iMask |= cMask;
+ /* Look for a + or , */
+ for (index = indexElem + 1; index < objc; index++) {
+ if (numArgs % 2 == 0) {
+ int length;
+ char *s = Tcl_GetStringFromObj(objv[index], &length);
- if (breakChar) {
+ if ((length == 1) && ((s[0] == '+') || (s[0] == ','))) {
+ breakChar = s[0];
+ break;
+ }
+ }
+ numArgs++;
+ }
- if (index == objc - 1) {
- FormatResult(interp, "missing %s after \"%c\"",
- (breakChar == '+') ? "element name" : "column",
- breakChar);
+ /* Require at least one option-value pair if more than one
+ * element is specified. */
+ if ((breakChar || indexElem != 6) && (numArgs < 2)) {
+ FormatResult(interp,
+ "missing option-value pair after element \"%s\"",
+ Tcl_GetString(objv[indexElem]));
result = TCL_ERROR;
break;
}
- /* + indicates start of another element */
- if (breakChar == '+') {
- indexElem = index + 1;
+ result = TreeStyle_ElementConfigure(tree, (TreeItem) item,
+ (TreeItemColumn) column, column->style, objv[indexElem],
+ numArgs, (Tcl_Obj **) objv + indexElem + 1, &eMask);
+ if (result != TCL_OK)
+ break;
+
+ cMask |= eMask;
+ if (cMask & CS_LAYOUT) {
+ TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
+ Tree_InvalidateColumnWidth(tree, columnIndex);
}
+ iMask |= cMask;
- /* , indicates start of another column */
- else if (breakChar == ',') {
- if (Item_FindColumnFromObj(tree, item, objv[index + 1],
- &column, &columnIndex) != TCL_OK) {
+ if (breakChar) {
+
+ if (index == objc - 1) {
+ FormatResult(interp, "missing %s after \"%c\"",
+ (breakChar == '+') ? "element name" : "column",
+ breakChar);
result = TCL_ERROR;
break;
}
- if ((column == NULL) || (column->style == NULL)) {
- NoStyleMsg(tree, item, columnIndex);
- result = TCL_ERROR;
- break;
+
+ /* + indicates start of another element */
+ if (breakChar == '+') {
+ indexElem = index + 1;
}
- indexElem = index + 2;
- if (indexElem == objc) {
- FormatResult(interp,
- "missing element name after column \"%s\"",
- Tcl_GetString(objv[index + 1]));
- result = TCL_ERROR;
- break;
+ /* , indicates start of another column */
+ else if (breakChar == ',') {
+ if (Item_FindColumnFromObj(tree, item, objv[index + 1],
+ &column, &columnIndex) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
+ }
+ if ((column == NULL) || (column->style == NULL)) {
+ NoStyleMsg(tree, item, columnIndex);
+ result = TCL_ERROR;
+ break;
+ }
+ indexElem = index + 2;
+
+ if (indexElem == objc) {
+ FormatResult(interp,
+ "missing element name after column \"%s\"",
+ Tcl_GetString(objv[index + 1]));
+ result = TCL_ERROR;
+ break;
+ }
}
- }
- } else if (index == objc)
+ } else if (index == objc)
+ break;
+ }
+ if (iMask & CS_LAYOUT) {
+ TreeItem_InvalidateHeight(tree, (TreeItem) item);
+ Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
+ Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
+ }
+ else if (iMask & CS_DISPLAY)
+ Tree_InvalidateItemDInfo(tree, (TreeItem) item, NULL);
+ if (result != TCL_OK)
break;
}
- if (iMask & CS_LAYOUT) {
- TreeItem_InvalidateHeight(tree, (TreeItem) item);
- Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
- Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
- }
- else if (iMask & CS_DISPLAY)
- Tree_InvalidateItemDInfo(tree, (TreeItem) item, NULL);
- return result;
+ break;
}
}
- return TCL_OK;
+ TreeItemList_Free(&itemList);
+ return result;
}
/*
@@ -4587,8 +4752,10 @@ ItemStyleCmd(
static CONST char *commandNames[] = { "elements", "map", "set", (char *) NULL };
enum { COMMAND_ELEMENTS, COMMAND_MAP, COMMAND_SET };
int index;
+ TreeItemList itemList;
TreeItem _item;
Item *item;
+ int result = TCL_OK;
if (objc < 5) {
Tcl_WrongNumArgs(interp, 3, objv, "command item ?arg ...?");
@@ -4600,9 +4767,10 @@ ItemStyleCmd(
return TCL_ERROR;
}
- if (TreeItem_FromObj(tree, objv[4], &_item, 0) != TCL_OK) {
+ if (TreeItemList_FromObj(tree, objv[4], &itemList, IFO_ALLOK) != TCL_OK) {
return TCL_ERROR;
}
+ _item = TreeItemList_ItemN(&itemList, 0);
item = (Item *) _item;
switch (index) {
@@ -4614,14 +4782,20 @@ ItemStyleCmd(
if (objc != 6) {
Tcl_WrongNumArgs(interp, 4, objv, "item column");
- return TCL_ERROR;
+ result = TCL_ERROR;
+ break;
}
- if (Item_FindColumnFromObj(tree, item, objv[5], &column, &columnIndex) != TCL_OK) {
- return TCL_ERROR;
+ if (item == (Item *) ITEM_ALL)
+ item = (Item *) tree->root;
+ if (Item_FindColumnFromObj(tree, item, objv[5], &column,
+ &columnIndex) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
}
if ((column == NULL) || (column->style == NULL)) {
NoStyleMsg(tree, item, columnIndex);
- return TCL_ERROR;
+ result = TCL_ERROR;
+ break;
}
TreeStyle_ListElements(tree, column->style);
break;
@@ -4631,35 +4805,53 @@ ItemStyleCmd(
case COMMAND_MAP:
{
TreeStyle style;
+ TreeColumn treeColumn;
Column *column;
int columnIndex;
int objcM;
Tcl_Obj **objvM;
+ TreeForEach iter;
if (objc != 8) {
Tcl_WrongNumArgs(interp, 4, objv, "item column style map");
return TCL_ERROR;
}
- if (Item_CreateColumnFromObj(tree, item, objv[5], &column,
- &columnIndex, NULL) != TCL_OK)
- return TCL_ERROR;
- if (TreeStyle_FromObj(tree, objv[6], &style) != TCL_OK)
- return TCL_ERROR;
- if (column->style != NULL) {
- if (Tcl_ListObjGetElements(interp, objv[7], &objcM, &objvM) != TCL_OK)
- return TCL_ERROR;
- if (objcM & 1) {
- FormatResult(interp, "list must contain even number of elements");
- return TCL_ERROR;
- }
- if (TreeStyle_Remap(tree, column->style, style, objcM, objvM) != TCL_OK)
- return TCL_ERROR;
- } else
- column->style = TreeStyle_NewInstance(tree, style);
+ if (TreeColumn_FromObj(tree, objv[5], &treeColumn,
+ CFO_NOT_ALL | CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
+ }
+ columnIndex = TreeColumn_Index(treeColumn);
+ if (TreeStyle_FromObj(tree, objv[6], &style) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
+ }
+ if (Tcl_ListObjGetElements(interp, objv[7], &objcM, &objvM)
+ != TCL_OK) {
+ result = TCL_ERROR;
+ break;
+ }
+ if (objcM & 1) {
+ FormatResult(interp, "list must contain even number of elements");
+ result = TCL_ERROR;
+ break;
+ }
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ item = (Item *) _item;
+ column = Item_CreateColumn(tree, item, columnIndex, NULL);
+ if (column->style != NULL) {
+ if (TreeStyle_Remap(tree, column->style, style, objcM,
+ objvM) != TCL_OK) {
+ result = TCL_ERROR;
+ break;
+ }
+ } else
+ column->style = TreeStyle_NewInstance(tree, style);
+ TreeItem_InvalidateHeight(tree, (TreeItem) item);
+ Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
+ TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
+ }
Tree_InvalidateColumnWidth(tree, columnIndex);
- TreeItem_InvalidateHeight(tree, (TreeItem) item);
- Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
- TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
break;
}
@@ -4667,17 +4859,27 @@ ItemStyleCmd(
/* T item style set I ?C? ?S? ?C S ...?*/
case COMMAND_SET:
{
- TreeStyle style;
+ struct columnStyle {
+ int columnIndex;
+ TreeStyle style;
+ int changed;
+ };
+ struct columnStyle staticCS[STATIC_SIZE], *cs = staticCS;
+ TreeColumn treeColumn;
Column *column;
- int i, columnIndex, length;
+ int i, count = 0, length, changed = FALSE, changedI;
+ TreeForEach iter;
if (objc < 5) {
Tcl_WrongNumArgs(interp, 4, objv, "item ?column? ?style? ?column style ...?");
return TCL_ERROR;
}
+ /* Return list of styles. */
if (objc == 5) {
- TreeColumn treeColumn = tree->columns;
Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
+ treeColumn = tree->columns;
+ if (_item == ITEM_ALL)
+ item = (Item *) tree->root;
column = item->columns;
while (treeColumn != NULL) {
if ((column != NULL) && (column->style != NULL))
@@ -4693,48 +4895,84 @@ ItemStyleCmd(
Tcl_SetObjResult(interp, listObj);
break;
}
+ /* Return style in one column. */
if (objc == 6) {
+ if (_item == ITEM_ALL)
+ item = (Item *) tree->root;
if (Item_FindColumnFromObj(tree, item, objv[5], &column, NULL) != TCL_OK)
return TCL_ERROR;
if ((column != NULL) && (column->style != NULL))
Tcl_SetObjResult(interp, TreeStyle_ToObj(column->style));
break;
}
+ /* Get column/style pairs. */
+ STATIC_ALLOC(cs, struct columnStyle, objc / 2);
for (i = 5; i < objc; i += 2) {
- if (Item_CreateColumnFromObj(tree, item, objv[i], &column,
- &columnIndex, NULL) != TCL_OK)
- return TCL_ERROR;
+ if (TreeColumn_FromObj(tree, objv[i], &treeColumn,
+ CFO_NOT_ALL | CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneSET;
+ }
+ cs[count].columnIndex = TreeColumn_Index(treeColumn);
if (i + 1 == objc) {
FormatResult(interp, "missing style for column \"%s\"",
Tcl_GetString(objv[i]));
- return TCL_ERROR;
+ result = TCL_ERROR;
+ goto doneSET;
}
(void) Tcl_GetStringFromObj(objv[i + 1], &length);
if (length == 0) {
- if (column->style == NULL)
- continue;
- TreeItemColumn_ForgetStyle(tree, (TreeItemColumn) column);
+ cs[count].style = NULL;
} else {
- if (TreeStyle_FromObj(tree, objv[i + 1], &style) != TCL_OK)
- return TCL_ERROR;
- if (column->style != NULL) {
- if (TreeStyle_GetMaster(tree, column->style) == style)
+ if (TreeStyle_FromObj(tree, objv[i + 1], &cs[count].style)
+ != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneSET;
+ }
+ }
+ cs[count].changed = FALSE;
+ count++;
+ }
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ item = (Item *) _item;
+ changedI = FALSE;
+ for (i = 0; i < count; i++) {
+ column = Item_CreateColumn(tree, item, cs[i].columnIndex, NULL);
+ if (cs[i].style == NULL) {
+ if (column->style == NULL)
continue;
TreeItemColumn_ForgetStyle(tree, (TreeItemColumn) column);
+ } else {
+ if (column->style != NULL) {
+ if (TreeStyle_GetMaster(tree, column->style) == cs[i].style)
+ continue;
+ TreeItemColumn_ForgetStyle(tree, (TreeItemColumn) column);
+ }
+ column->style = TreeStyle_NewInstance(tree, cs[i].style);
+ }
+ TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
+ changedI = TRUE;
+ if (!cs[i].changed) {
+ Tree_InvalidateColumnWidth(tree, cs[i].columnIndex);
+ cs[i].changed = TRUE;
}
- column->style = TreeStyle_NewInstance(tree, style);
}
- Tree_InvalidateColumnWidth(tree, columnIndex);
- TreeItem_InvalidateHeight(tree, (TreeItem) item);
- Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
- TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
- Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
+ if (changedI) {
+ TreeItem_InvalidateHeight(tree, (TreeItem) item);
+ Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
+ changed = TRUE;
+ }
}
+ if (changed)
+ Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
+doneSET:
+ STATIC_FREE(cs, struct columnStyle, objc / 2);
break;
}
}
- return TCL_OK;
+ TreeItemList_Free(&itemList);
+ return result;
}
/* one per column per SortItem */
@@ -5711,27 +5949,33 @@ ItemStateCmd(
/* T item state forcolumn I C ?stateList? */
case COMMAND_FORCOLUMN:
{
+ TreeItemList itemList;
+ TreeColumn treeColumn;
Tcl_Obj *listObj;
Column *column;
int columnIndex;
int i, states[3], stateOn, stateOff;
- int listObjc;
- Tcl_Obj **listObjv;
+ TreeForEach iter;
+ int result = TCL_OK;
if (objc < 6 || objc > 7) {
- Tcl_WrongNumArgs(interp, 5, objv, "column ?stateList?");
+ Tcl_WrongNumArgs(interp, 4, objv, "item column ?stateList?");
return TCL_ERROR;
}
- if (TreeItem_FromObj(tree, objv[4], &_item, 0)
+ if (TreeItemList_FromObj(tree, objv[4], &itemList, IFO_ALLOK)
!= TCL_OK)
return TCL_ERROR;
- item = (Item *) _item;
- if (Item_FindColumnFromObj(tree, item, objv[5], &column,
- &columnIndex) != TCL_OK)
- return TCL_ERROR;
if (objc == 6) {
+ item = (Item *) TreeItemList_ItemN(&itemList, 0);
+ if (item == (Item *) ITEM_ALL)
+ item = (Item *) tree->root;
+ if (Item_FindColumnFromObj(tree, item, objv[5], &column,
+ &columnIndex) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneFORC;
+ }
if ((column == NULL) || !column->cstate)
- break;
+ goto doneFORC;
listObj = Tcl_NewListObj(0, NULL);
for (i = 0; i < 32; i++) {
if (tree->stateNames[i] == NULL)
@@ -5742,28 +5986,33 @@ ItemStateCmd(
}
}
Tcl_SetObjResult(interp, listObj);
- break;
+ goto doneFORC;
}
- states[0] = states[1] = states[2] = 0;
- if (Tcl_ListObjGetElements(interp, objv[6], &listObjc, &listObjv)
- != TCL_OK)
- return TCL_ERROR;
- if (listObjc == 0)
- break;
- for (i = 0; i < listObjc; i++) {
- if (Tree_StateFromObj(tree, listObjv[i], states, NULL,
- SFO_NOT_STATIC) != TCL_OK)
- return TCL_ERROR;
+ if (TreeColumn_FromObj(tree, objv[5], &treeColumn,
+ CFO_NOT_ALL | CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneFORC;
+ }
+ columnIndex = TreeColumn_Index(treeColumn);
+ if (Tree_StateFromListObj(tree, objv[6], states, SFO_NOT_STATIC) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneFORC;
}
- if (column == NULL) {
+ if ((states[0] | states[1] | states[2]) == 0)
+ goto doneFORC;
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ item = (Item *) _item;
column = Item_CreateColumn(tree, item, columnIndex, NULL);
+ stateOn = states[STATE_OP_ON];
+ stateOff = states[STATE_OP_OFF];
+ stateOn |= ~column->cstate & states[STATE_OP_TOGGLE];
+ stateOff |= column->cstate & states[STATE_OP_TOGGLE];
+ Column_ChangeState(tree, item, column, columnIndex,
+ stateOff, stateOn);
}
- stateOn = states[STATE_OP_ON];
- stateOff = states[STATE_OP_OFF];
- stateOn |= ~column->cstate & states[STATE_OP_TOGGLE];
- stateOff |= column->cstate & states[STATE_OP_TOGGLE];
- Column_ChangeState(tree, item, column, columnIndex,
- stateOff, stateOn);
+doneFORC:
+ TreeItemList_Free(&itemList);
+ return result;
break;
}
@@ -5805,81 +6054,47 @@ ItemStateCmd(
/* T item state set I ?I? {state ...} */
case COMMAND_SET:
{
- TreeItem item, itemFirst, itemLast;
- int i, states[3], stateOn, stateOff;
- int listObjc;
- Tcl_Obj **listObjv;
+ TreeItemList itemList, item2List;
+ TreeItem item;
+ int states[3], stateOn, stateOff;
+ TreeForEach iter;
+ int result = TCL_OK;
if (objc < 6 || objc > 7) {
Tcl_WrongNumArgs(interp, 5, objv, "?last? stateList");
return TCL_ERROR;
}
- if (TreeItem_FromObj(tree, objv[4], &itemFirst, IFO_ALLOK) != TCL_OK)
+ if (TreeItemList_FromObj(tree, objv[4], &itemList, IFO_ALLOK) != TCL_OK)
return TCL_ERROR;
if (objc == 6) {
- itemLast = itemFirst;
+ TreeItemList_Init(tree, &item2List, 0);
}
if (objc == 7) {
- if (TreeItem_FromObj(tree, objv[5], &itemLast, IFO_ALLOK) != TCL_OK)
- return TCL_ERROR;
- }
- states[0] = states[1] = states[2] = 0;
- if (Tcl_ListObjGetElements(interp, objv[objc - 1],
- &listObjc, &listObjv) != TCL_OK)
- return TCL_ERROR;
- if (listObjc == 0)
- break;
- for (i = 0; i < listObjc; i++) {
- if (Tree_StateFromObj(tree, listObjv[i], states, NULL,
- SFO_NOT_STATIC) != TCL_OK)
- return TCL_ERROR;
- }
- if ((itemFirst == ITEM_ALL) || (itemLast == ITEM_ALL)) {
- Tcl_HashEntry *hPtr;
- Tcl_HashSearch search;
-
- hPtr = Tcl_FirstHashEntry(&tree->itemHash, &search);
- while (hPtr != NULL) {
- item = (TreeItem) Tcl_GetHashValue(hPtr);
- stateOn = states[STATE_OP_ON];
- stateOff = states[STATE_OP_OFF];
- stateOn |= ~((Item *) item)->state & states[STATE_OP_TOGGLE];
- stateOff |= ((Item *) item)->state & states[STATE_OP_TOGGLE];
- TreeItem_ChangeState(tree, item, stateOff, stateOn);
- hPtr = Tcl_NextHashEntry(&search);
+ if (TreeItemList_FromObj(tree, objv[5], &item2List, IFO_ALLOK) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneSET;
}
- break;
}
- if (objc == 7) {
- int indexFirst, indexLast;
-
- if (TreeItem_RootAncestor(tree, itemFirst) !=
- TreeItem_RootAncestor(tree,itemLast)) {
- FormatResult(interp,
- "item %s%d and item %s%d don't share a common ancestor",
- tree->itemPrefix, TreeItem_GetID(tree, itemFirst),
- tree->itemPrefix, TreeItem_GetID(tree, itemLast));
- return TCL_ERROR;
- }
- TreeItem_ToIndex(tree, itemFirst, &indexFirst, NULL);
- TreeItem_ToIndex(tree, itemLast, &indexLast, NULL);
- if (indexFirst > indexLast) {
- item = itemFirst;
- itemFirst = itemLast;
- itemLast = item;
- }
+ if (Tree_StateFromListObj(tree, objv[objc - 1], states,
+ SFO_NOT_STATIC) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneSET;
}
- item = itemFirst;
- while (item != NULL) {
+ if ((states[0] | states[1] | states[2]) == 0)
+ goto doneSET;
+ TREE_FOR_EACH(item, &itemList, &item2List, &iter) {
stateOn = states[STATE_OP_ON];
stateOff = states[STATE_OP_OFF];
stateOn |= ~((Item *) item)->state & states[STATE_OP_TOGGLE];
stateOff |= ((Item *) item)->state & states[STATE_OP_TOGGLE];
TreeItem_ChangeState(tree, item, stateOff, stateOn);
- if (item == itemLast)
- break;
- item = TreeItem_Next(tree, item);
}
+ if (iter.error)
+ result = TCL_ERROR;
+doneSET:
+ TreeItemList_Free(&itemList);
+ TreeItemList_Free(&item2List);
+ return result;
break;
}
}
@@ -6077,21 +6292,21 @@ TreeItemCmd(
{ 1, 1, 0, 0, 0, "item", NULL }, /* numchildren */
{ 1, 1, 0, 0, 0, "item", NULL }, /* parent */
{ 1, 2, IFO_NOTROOT | IFO_NOTORPHAN, IFO_NOTROOT | AF_NOTANCESTOR | AF_NOT_EQUAL, 0, "item ?newPrevSibling?", NULL }, /* prevsibling */
- { 1, 1, IFO_NOTROOT, 0, 0, "item", NULL }, /* remove */
+ { 1, 1, IFO_ALLOK | IFO_NOTROOT, 0, 0, "item", NULL }, /* remove */
{ 1, 3, 0, AF_NOT_ITEM, AF_NOT_ITEM, "item ?column? ?element?", NULL }, /* bbox */
{ 2, 2, 0, AF_NOT_ITEM, 0, "item option", NULL }, /* cget */
{ 1, 2, IFO_ALLOK, AF_NOT_ITEM, 0, "item ?-recurse?", NULL}, /* collapse */
{ 3, 3, 0, AF_NOT_ITEM, AF_SAMEROOT, "item1 op item2", NULL }, /* compare */
{ 2, 100000, 0, AF_NOT_ITEM, AF_NOT_ITEM, "item list ...", NULL }, /* complex */
- { 1, 100000, 0, AF_NOT_ITEM, AF_NOT_ITEM, "item ?option? ?value? ?option value ...?", NULL }, /* configure */
+ { 1, 100000, IFO_ALLOK, AF_NOT_ITEM, AF_NOT_ITEM, "item ?option? ?value? ?option value ...?", NULL }, /* configure */
{ 0, 1, AF_NOT_ITEM, 0, 0, "?-visible?" , NULL}, /* count */
{ 1, 1, 0, 0, 0, "item", NULL }, /* dump */
{ 0, 0, 0, 0, 0, NULL, ItemElementCmd }, /* element */
- { 1, 2, 0, AF_NOT_ITEM, 0, "item ?boolean?", NULL }, /* enabled */
+ { 1, 2, IFO_ALLOK, AF_NOT_ITEM, 0, "item ?boolean?", NULL }, /* enabled */
{ 1, 2, IFO_ALLOK, AF_NOT_ITEM, 0, "item ?-recurse?", NULL}, /* expand */
- { 1, 1, IFO_NULLOK, 0, 0, "item", NULL }, /* id */
- { 1, 100000, 0, AF_NOT_ITEM, AF_NOT_ITEM, "item ?column? ?image? ?column image ...?", NULL }, /* image */
+ { 1, 1, IFO_ALLOK | IFO_NULLOK, 0, 0, "item", NULL }, /* id */
+ { 1, 100000, IFO_ALLOK, AF_NOT_ITEM, AF_NOT_ITEM, "item ?column? ?image? ?column image ...?", NULL }, /* image */
{ 2, 2, 0, 0, 0, "item item2", NULL }, /* isancestor */
{ 1, 1, 0, 0, 0, "item", NULL }, /* isopen */
{ 1, 2, 0, AF_NOT_ITEM, 0, "item ?-visible?", NULL }, /* order */
@@ -6103,7 +6318,7 @@ TreeItemCmd(
#endif
{ 0, 0, 0, 0, 0, NULL, ItemStateCmd }, /* state */
{ 0, 0, 0, 0, 0, NULL, ItemStyleCmd }, /* style */
- { 1, 100000, 0, AF_NOT_ITEM, AF_NOT_ITEM, "item ?column? ?text? ?column text ...?", NULL }, /* text */
+ { 1, 100000, IFO_ALLOK, AF_NOT_ITEM, AF_NOT_ITEM, "item ?column? ?text? ?column text ...?", NULL }, /* text */
{ 1, 2, IFO_ALLOK, AF_NOT_ITEM, 0, "item ?-recurse?", NULL}, /* toggle */
};
int index;
@@ -6299,6 +6514,8 @@ TreeItemCmd(
int recurse = 0;
int mode = 0; /* lint */
int i, count;
+ TreeItemList items;
+ TreeForEach iter;
if (numArgs == 2) {
char *s = Tcl_GetString(objv[4]);
@@ -6320,41 +6537,19 @@ TreeItemCmd(
mode = -1;
break;
}
- if (item == (Item *) ITEM_ALL) {
- Tcl_HashEntry *hPtr;
- Tcl_HashSearch search;
- TreeItemList items;
-
- TreeItemList_Init(tree, &items, tree->itemCount);
- hPtr = Tcl_FirstHashEntry(&tree->itemHash, &search);
- while (hPtr != NULL) {
- _item = (TreeItem) Tcl_GetHashValue(hPtr);
- TreeItemList_Append(&items, _item);
- hPtr = Tcl_NextHashEntry(&search);
- }
- count = TreeItemList_Count(&items);
- for (i = 0; i < count; i++) {
- _item = TreeItemList_ItemN(&items, i);
- TreeItem_OpenClose(tree, _item, mode, FALSE);
- }
- TreeItemList_Free(&items);
-#ifdef SELECTION_VISIBLE
- Tree_DeselectHidden(tree);
-#endif
- break;
- }
- if (recurse) {
- count = TreeItemList_Count(&itemList);
- for (i = 0; i < count; i++) {
- _item = TreeItemList_ItemN(&itemList, i);
- TreeItem_ListDescendants(tree, _item, &itemList);
+ TreeItemList_Init(tree, &items, 0);
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ TreeItemList_Append(&items, _item);
+ if (!iter.all && recurse) {
+ TreeItem_ListDescendants(tree, _item, &items);
}
}
- count = TreeItemList_Count(&itemList);
+ count = TreeItemList_Count(&items);
for (i = 0; i < count; i++) {
- _item = TreeItemList_ItemN(&itemList, i);
+ _item = TreeItemList_ItemN(&items, i);
TreeItem_OpenClose(tree, _item, mode, FALSE);
}
+ TreeItemList_Free(&items);
#ifdef SELECTION_VISIBLE
Tree_DeselectHidden(tree);
#endif
@@ -6462,12 +6657,16 @@ TreeItemCmd(
}
break;
}
+ /* T item configure I ?option? ?value? ?option value ...? */
case COMMAND_CONFIGURE:
{
- int i, count;
+ TreeForEach iter;
+
if (objc <= 5) {
Tcl_Obj *resultObjPtr;
+ if (_item == ITEM_ALL)
+ _item = tree->root;
resultObjPtr = Tk_GetOptionInfo(interp, (char *) item,
tree->itemOptionTable,
(objc == 4) ? (Tcl_Obj *) NULL : objv[4],
@@ -6477,11 +6676,8 @@ TreeItemCmd(
Tcl_SetObjResult(interp, resultObjPtr);
break;
}
- /* FIXME: ITEM_ALL */
- count = TreeItemList_Count(&itemList);
- for (i = 0; i < count; i++) {
- item = (Item *) TreeItemList_ItemN(&itemList, i);
- result = Item_Configure(tree, item, objc - 4, objv + 4);
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ result = Item_Configure(tree, (Item *) _item, objc - 4, objv + 4);
if (result != TCL_OK)
break;
}
@@ -6514,6 +6710,7 @@ TreeItemCmd(
{
TreeItemList deleted, selected;
int i, count;
+ TreeForEach iter;
/* The root is never deleted */
if (tree->itemCount == 1)
@@ -6529,73 +6726,47 @@ TreeItemCmd(
/*
* ITEM_FLAG_DELETED prevents us from adding the same item
- * twice to the 'deleted' list. It also prevents recursive
+ * twice to the 'deleted' list. It also prevents nested
* calls to this command (through binding scripts) deleting
* the same item twice.
*/
- if ((_item == ITEM_ALL) || (_item2 == ITEM_ALL)) {
- Tcl_HashEntry *hPtr;
- Tcl_HashSearch search;
-
- TreeItemList_Init(tree, &deleted, tree->itemCount - 1);
- TreeItemList_Init(tree, &selected, tree->selectCount);
+ TreeItemList_Init(tree, &deleted, tree->itemCount - 1);
+ TreeItemList_Init(tree, &selected, tree->selectCount);
- hPtr = Tcl_FirstHashEntry(&tree->itemHash, &search);
- while (hPtr != NULL) {
- item = (Item *) Tcl_GetHashValue(hPtr);
- if (!ISROOT(item) && !IS_DELETED(item)) {
+ TREE_FOR_EACH(_item, &itemList, &item2List, &iter) {
+ item = (Item *) _item;
+ if (ISROOT(item))
+ continue;
+ 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);
+ if (iter.all)
+ continue;
+ /* Check every descendant. */
+ if (item->firstChild == NULL)
+ continue;
+ item2 = item;
+ while (item2->lastChild != NULL)
+ item2 = item2->lastChild;
+ item = item->firstChild;
+ while (1) {
+ 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);
}
- hPtr = Tcl_NextHashEntry(&search);
- }
- } else {
- /* A range of items was specified. */
- if (objc == 5) {
- count = TreeItem_FirstAndLast(tree, &_item, &_item2);
- TreeItemList_Free(&itemList);
- TreeItemList_Init(tree, &itemList, count);
- while (1) {
- TreeItemList_Append(&itemList, _item);
- if (_item == _item2)
- break;
- _item = TreeItem_Next(tree, _item);
- }
- }
-
- TreeItemList_Init(tree, &deleted, 0);
- TreeItemList_Init(tree, &selected, tree->selectCount);
-
- count = TreeItemList_Count(&itemList);
- for (i = 0; i < count; i++) {
- item = (Item *) TreeItemList_ItemN(&itemList, i);
- if (ISROOT(item))
- continue;
- if (IS_DELETED(item))
- continue;
-
- /* Check every descendant. */
- item2 = item;
- while (item2->lastChild != NULL)
- item2 = item2->lastChild;
- while (1) {
- 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);
- }
- if (item == item2)
- break;
- item = (Item *) TreeItem_Next(tree, (TreeItem) item);
- }
+ if (item == item2)
+ break;
+ item = (Item *) TreeItem_Next(tree, (TreeItem) item);
}
}
@@ -6631,34 +6802,40 @@ TreeItemCmd(
item->index, item->indexVis, item->neededHeight);
break;
}
+ /* T item enabled I ?boolean? */
case COMMAND_ENABLED:
{
- if (objc == 5) {
- int i, count, enabled;
- TreeItemList newD;
- if (Tcl_GetBooleanFromObj(interp, objv[4], &enabled) != TCL_OK)
- goto errorExit;
- TreeItemList_Init(tree, &newD, tree->selectCount);
- /* FIXME: ITEM_ALL */
- count = TreeItemList_Count(&itemList);
- for (i = 0; i < count; i++) {
- _item = TreeItemList_ItemN(&itemList, i);
- if (enabled != TreeItem_GetEnabled(tree, _item)) {
- int stateOff = enabled ? 0 : STATE_ENABLED;
- int stateOn = enabled ? STATE_ENABLED : 0;
- TreeItem_ChangeState(tree, _item, stateOff, stateOn);
- /* Disabled items cannot be selected. */
- if (!enabled && TreeItem_GetSelected(tree, _item)) {
- Tree_RemoveFromSelection(tree, _item);
- TreeItemList_Append(&newD, _item);
- }
+ int enabled;
+ TreeItemList newD;
+ int stateOff, stateOn;
+ TreeForEach iter;
+
+ if (objc == 4) {
+ if (_item == ITEM_ALL)
+ item = (Item *) tree->root;
+ Tcl_SetObjResult(interp,
+ Tcl_NewBooleanObj(item->state & STATE_ENABLED));
+ break;
+ }
+ if (Tcl_GetBooleanFromObj(interp, objv[4], &enabled) != TCL_OK)
+ goto errorExit;
+ stateOff = enabled ? 0 : STATE_ENABLED;
+ stateOn = enabled ? STATE_ENABLED : 0;
+ TreeItemList_Init(tree, &newD, tree->selectCount);
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ if (enabled != TreeItem_GetEnabled(tree, _item)) {
+ TreeItem_ChangeState(tree, _item, stateOff, stateOn);
+ /* Disabled items cannot be selected. */
+ if (!enabled && TreeItem_GetSelected(tree, _item)) {
+ Tree_RemoveFromSelection(tree, _item);
+ TreeItemList_Append(&newD, _item);
}
}
- if (TreeItemList_Count(&newD))
- TreeNotify_Selection(tree, NULL, &newD);
- TreeItemList_Free(&newD);
}
- Tcl_SetObjResult(interp, Tcl_NewBooleanObj(item->state & STATE_ENABLED));
+ if (TreeItemList_Count(&newD))
+ TreeNotify_Selection(tree, NULL, &newD);
+ TreeItemList_Free(&newD);
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(enabled));
break;
}
case COMMAND_FIRSTCHILD:
@@ -6685,21 +6862,18 @@ TreeItemCmd(
Tcl_SetObjResult(interp, TreeItem_ToObj(tree, (TreeItem) item->firstChild));
break;
}
+ /* T item id I */
case COMMAND_ID:
{
Tcl_Obj *listObj;
- int i, count;
+ TreeForEach iter;
- /* FIXME: ITEM_ALL */
- count = TreeItemList_Count(&itemList);
- if (count) {
- listObj = Tcl_NewListObj(0, NULL);
- for (i = 0; i < count; i++) {
- Tcl_ListObjAppendElement(interp, listObj,
- TreeItem_ToObj(tree, TreeItemList_ItemN(&itemList, i)));
- }
- Tcl_SetObjResult(interp, listObj);
+ listObj = Tcl_NewListObj(0, NULL);
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ Tcl_ListObjAppendElement(interp, listObj,
+ TreeItem_ToObj(tree, _item));
}
+ Tcl_SetObjResult(interp, listObj);
break;
}
case COMMAND_ISANCESTOR:
@@ -6838,13 +7012,22 @@ TreeItemCmd(
}
case COMMAND_REMOVE:
{
- if (item->parent == NULL)
+ TreeForEach iter;
+ int removed = FALSE;
+
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ item = (Item *) _item;
+ if (item->parent != NULL) {
+ TreeItem_RemoveFromParent(tree, (TreeItem) item);
+ Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
+ removed = TRUE;
+ }
+ }
+ if (!removed)
break;
- TreeItem_RemoveFromParent(tree, (TreeItem) item);
if (tree->debug.enable && tree->debug.data)
Tree_Debug(tree);
Tree_InvalidateColumnWidth(tree, -1);
- Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
#ifdef SELECTION_VISIBLE
Tree_DeselectHidden(tree);
#endif
@@ -6865,7 +7048,13 @@ TreeItemCmd(
TreeColumn treeColumn = tree->columns;
Column *column = item->columns;
Tcl_Obj *listObj;
- int i, columnIndex, span;
+ struct columnSpan {
+ int columnIndex;
+ int span;
+ int changed;
+ } staticCS[STATIC_SIZE], *cs = staticCS;
+ int i, count = 0, span, changed = FALSE;
+ TreeForEach iter;
if (objc == 4) {
listObj = Tcl_NewListObj(0, NULL);
@@ -6887,43 +7076,83 @@ TreeItemCmd(
break;
}
if ((objc - 4) & 1) {
- FormatResult(interp, "wrong # args: should be \"column span column span ...\"");
+ FormatResult(interp, "missing argument after column \"%s\"",
+ Tcl_GetString(objv[objc - 1]));
goto errorExit;
}
- TreeItem_InvalidateHeight(tree, (TreeItem) item);
- Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
- Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
+ /* Gather column/span pairs. */
+ STATIC_ALLOC(cs, struct columnSpan, objc / 2);
for (i = 4; i < objc; i += 2) {
- if (Item_CreateColumnFromObj(tree, item, objv[i], &column,
- &columnIndex, NULL) != TCL_OK)
- goto errorExit;
- if (Tcl_GetIntFromObj(interp, objv[i + 1], &span) != TCL_OK)
- goto errorExit;
+ if (TreeColumn_FromObj(tree, objv[i], &treeColumn,
+ CFO_NOT_ALL | CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneSPAN;
+ }
+ if (Tcl_GetIntFromObj(interp, objv[i + 1], &span) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneSPAN;
+ }
if (span <= 0) {
FormatResult(interp, "bad span \"%d\": must be > 0", span);
- goto errorExit;
+ result = TCL_ERROR;
+ goto doneSPAN;
}
- column->span = span;
- TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
- Tree_InvalidateColumnWidth(tree, columnIndex);
+ cs[count].columnIndex = TreeColumn_Index(treeColumn);
+ cs[count].span = span;
+ cs[count].changed = FALSE;
+ count++;
}
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ int changedI = FALSE;
+ for (i = 0; i < count; i++) {
+ item = (Item *) _item;
+ column = Item_CreateColumn(tree, item, cs[i].columnIndex, NULL);
+ if (column->span != cs[i].span) {
+ column->span = cs[i].span;
+ TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
+ changedI = TRUE;
+ if (!cs[i].changed) {
+ Tree_InvalidateColumnWidth(tree, cs[i].columnIndex);
+ cs[i].changed = TRUE;
+ }
+ }
+ }
+ if (changedI) {
+ TreeItem_InvalidateHeight(tree, _item);
+ Tree_FreeItemDInfo(tree, _item, NULL);
+ changed = TRUE;
+ }
+ }
+ if (changed)
+ Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
+doneSPAN:
+ STATIC_FREE(cs, struct columnSpan, objc / 2);
break;
}
-#endif
+#endif /* COLUMN_SPAN */
/* T item image I ?C? ?image? ?C image ...? */
case COMMAND_IMAGE:
/* T item text I ?C? ?text? ?C text ...? */
case COMMAND_TEXT:
{
TreeColumn treeColumn = tree->columns;
- Column *column = item->columns;
+ Column *column;
Tcl_Obj *objPtr;
- int i, columnIndex;
int isImage = (index == COMMAND_IMAGE);
- int result;
-
+ struct columnObj {
+ int columnIndex;
+ Tcl_Obj *obj;
+ int changed;
+ } staticCO[STATIC_SIZE], *co = staticCO;
+ int i, count = 0, changed = FALSE;
+ TreeForEach iter;
+
+ if ((objc < 6) && (_item == ITEM_ALL)) {
+ item = (Item *) tree->root;
+ }
if (objc == 4) {
Tcl_Obj *listObj = Tcl_NewListObj(0, NULL);
+ column = item->columns;
while (treeColumn != NULL) {
if ((column != NULL) && (column->style != NULL))
objPtr = isImage ?
@@ -6959,27 +7188,53 @@ TreeItemCmd(
Tcl_GetString(objv[objc - 1]));
goto errorExit;
}
- TreeItem_InvalidateHeight(tree, (TreeItem) item);
- Tree_FreeItemDInfo(tree, (TreeItem) item, NULL);
- Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
+ /* Gather column/obj pairs. */
+ STATIC_ALLOC(co, struct columnObj, objc / 2);
for (i = 4; i < objc; i += 2) {
- if (Item_FindColumnFromObj(tree, item, objv[i], &column,
- &columnIndex) != TCL_OK)
- goto errorExit;
- if ((column == NULL) || (column->style == NULL)) {
- NoStyleMsg(tree, item, columnIndex);
- goto errorExit;
+ if (TreeColumn_FromObj(tree, objv[i], &treeColumn,
+ CFO_NOT_ALL | CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK) {
+ result = TCL_ERROR;
+ goto doneTEXT;
+ }
+ co[count].columnIndex = TreeColumn_Index(treeColumn);
+ co[count].obj = objv[i + 1];
+ co[count].changed = FALSE;
+ count++;
+ }
+ TREE_FOR_EACH(_item, &itemList, NULL, &iter) {
+ int changedI = FALSE;
+ item = (Item *) _item;
+ for (i = 0; i < count; i++) {
+ column = Item_FindColumn(tree, item, co[i].columnIndex);
+ if ((column == NULL) || (column->style == NULL)) {
+ NoStyleMsg(tree, item, co[i].columnIndex);
+ result = TCL_ERROR;
+ goto doneTEXT;
+ }
+ result = isImage ?
+ TreeStyle_SetImage(tree, _item,
+ (TreeItemColumn) column, column->style, co[i].obj) :
+ TreeStyle_SetText(tree, _item,
+ (TreeItemColumn) column, column->style, co[i].obj);
+ if (result != TCL_OK)
+ goto doneTEXT;
+ TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
+ changedI = TRUE;
+ if (!co[i].changed) {
+ Tree_InvalidateColumnWidth(tree, co[i].columnIndex);
+ co[i].changed = TRUE;
+ }
+ }
+ if (changedI) {
+ TreeItem_InvalidateHeight(tree, _item);
+ Tree_FreeItemDInfo(tree, _item, NULL);
+ changed = TRUE;
}
- result = isImage ?
- TreeStyle_SetImage(tree, (TreeItem) item,
- (TreeItemColumn) column, column->style, objv[i + 1]) :
- TreeStyle_SetText(tree, (TreeItem) item,
- (TreeItemColumn) column, column->style, objv[i + 1]);
- if (result != TCL_OK)
- goto errorExit;
- TreeItemColumn_InvalidateSize(tree, (TreeItemColumn) column);
- Tree_InvalidateColumnWidth(tree, columnIndex);
}
+ if (changed)
+ Tree_DInfoChanged(tree, DINFO_REDO_RANGES);
+doneTEXT:
+ STATIC_FREE(co, struct columnObj, objc / 2);
break;
}
}