diff options
author | treectrl <treectrl> | 2003-01-05 22:57:26 (GMT) |
---|---|---|
committer | treectrl <treectrl> | 2003-01-05 22:57:26 (GMT) |
commit | 7fbe5237ee8e7efbb2fd80982deb738d43ff2fa2 (patch) | |
tree | 9c81761d84082d14191d0cba3a17db02b954c977 /generic/tkTreeItem.c | |
parent | 21bb2bae4fcdbb17dddcb397ef7381ee91ea99dc (diff) | |
download | tktreectrl-7fbe5237ee8e7efbb2fd80982deb738d43ff2fa2.zip tktreectrl-7fbe5237ee8e7efbb2fd80982deb738d43ff2fa2.tar.gz tktreectrl-7fbe5237ee8e7efbb2fd80982deb738d43ff2fa2.tar.bz2 |
New -element option to item sort command.
Allow item sort without columns if -command is used.
Diffstat (limited to 'generic/tkTreeItem.c')
-rw-r--r-- | generic/tkTreeItem.c | 157 |
1 files changed, 144 insertions, 13 deletions
diff --git a/generic/tkTreeItem.c b/generic/tkTreeItem.c index fe69707..d734233 100644 --- a/generic/tkTreeItem.c +++ b/generic/tkTreeItem.c @@ -2037,7 +2037,15 @@ struct SortItem typedef struct SortData SortData; -/* one per TreeColumn */ +/* Used to process -element option */ +struct SortElement +{ + TreeStyle style; + TreeElement elem; + int elemIndex; +}; + +/* One per TreeColumn */ struct SortColumn { int (*proc)(SortData *, struct SortItem *, struct SortItem *, int); @@ -2045,8 +2053,11 @@ struct SortColumn int column; int order; Tcl_Obj *command; + struct SortElement elems[20]; + int elemCount; }; +/* Data for sort as a whole */ struct SortData { TreeCtrl *tree; @@ -2424,23 +2435,23 @@ int ItemSortCmd(ClientData clientData, Tcl_Interp *interp, int objc, TreeCtrl *tree = (TreeCtrl *) clientData; Item *item, *first, *last, *walk, *lastChild; Column *column; - int i, count, index, indexF = 0, indexL = 0; + int i, j, count, elemIndex, index, indexF = 0, indexL = 0; int sawColumn = FALSE, sawCmd = FALSE; static int (*sortProc[5])(SortData *, struct SortItem *, struct SortItem *, int) = { CompareAscii, CompareDict, CompareDouble, CompareLong, CompareCmd }; SortData sortData; TreeColumn treeColumn; + struct SortElement *elemPtr; int notReally = FALSE; int result = TCL_OK; if (TreeItem_FromObj(tree, objv[3], (TreeItem *) &item, 0) != TCL_OK) return TCL_ERROR; - if (tree->columnCount < 1) - { - FormatResult(interp, "there are no columns"); - return TCL_ERROR; - } + /* If the item has no children, then nothing is done and no error + * is generated. */ + if (item->numChildren < 1) + return TCL_OK; /* Defaults: sort ascii strings in column 0 only */ sortData.tree = tree; @@ -2448,6 +2459,7 @@ int ItemSortCmd(ClientData clientData, Tcl_Interp *interp, int objc, sortData.columns[0].column = 0; sortData.columns[0].sortBy = SORT_ASCII; sortData.columns[0].order = 1; + sortData.columns[0].elemCount = 0; sortData.result = TCL_OK; first = item->firstChild; @@ -2456,11 +2468,11 @@ int ItemSortCmd(ClientData clientData, Tcl_Interp *interp, int objc, for (i = 4; i < objc; ) { static CONST char *optionName[] = { "-ascii", "-column", "-command", - "-decreasing", "-dictionary", "-first", "-increasing", "-integer", - "-last", "-notreally", "-real", NULL }; - int numArgs[] = { 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1 }; + "-decreasing", "-dictionary", "-element", "-first", "-increasing", + "-integer", "-last", "-notreally", "-real", NULL }; + int numArgs[] = { 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1 }; enum { OPT_ASCII, OPT_COLUMN, OPT_COMMAND, OPT_DECREASING, OPT_DICT, - OPT_FIRST, OPT_INCREASING, OPT_INTEGER, OPT_LAST, + OPT_ELEMENT, OPT_FIRST, OPT_INCREASING, OPT_INTEGER, OPT_LAST, OPT_NOT_REALLY, OPT_REAL }; if (Tcl_GetIndexFromObj(interp, objv[i], optionName, "option", 0, @@ -2494,6 +2506,7 @@ int ItemSortCmd(ClientData clientData, Tcl_Interp *interp, int objc, /* Defaults for this column */ sortData.columns[sortData.count - 1].sortBy = SORT_ASCII; sortData.columns[sortData.count - 1].order = 1; + sortData.columns[sortData.count - 1].elemCount = 0; } sortData.columns[sortData.count - 1].column = TreeColumn_Index(treeColumn); sawColumn = TRUE; @@ -2509,6 +2522,79 @@ int ItemSortCmd(ClientData clientData, Tcl_Interp *interp, int objc, case OPT_DICT: sortData.columns[sortData.count - 1].sortBy = SORT_DICT; break; + case OPT_ELEMENT: + { + int listObjc; + Tcl_Obj **listObjv; + + if (Tcl_ListObjGetElements(interp, objv[i + 1], &listObjc, + &listObjv) != TCL_OK) + return TCL_ERROR; + elemPtr = sortData.columns[sortData.count - 1].elems; + sortData.columns[sortData.count - 1].elemCount = 0; + if (listObjc == 0) + { + } + else if (listObjc == 1) + { + if (TreeElement_FromObj(tree, listObjv[0], &elemPtr->elem) + != TCL_OK) + { + Tcl_AddErrorInfo(interp, + "\n (processing -element option)"); + return TCL_ERROR; + } + if (!TreeElement_IsType(tree, elemPtr->elem, "text")) + { + FormatResult(interp, + "element %s is not of type \"text\"", + Tcl_GetString(listObjv[0])); + Tcl_AddErrorInfo(interp, + "\n (processing -element option)"); + return TCL_ERROR; + } + elemPtr->style = NULL; + elemPtr->elemIndex = -1; + sortData.columns[sortData.count - 1].elemCount++; + } + else + { + if (listObjc & 1) + { + FormatResult(interp, + "list must have even number of elements"); + Tcl_AddErrorInfo(interp, + "\n (processing -element option)"); + return TCL_ERROR; + } + for (j = 0; j < listObjc; j += 2) + { + if ((TreeStyle_FromObj(tree, listObjv[j], + &elemPtr->style) != TCL_OK) || + (TreeElement_FromObj(tree, listObjv[j + 1], + &elemPtr->elem) != TCL_OK) || + (TreeStyle_FindElement(tree, elemPtr->style, + elemPtr->elem, &elemPtr->elemIndex) != TCL_OK)) + { + Tcl_AddErrorInfo(interp, + "\n (processing -element option)"); + return TCL_ERROR; + } + if (!TreeElement_IsType(tree, elemPtr->elem, "text")) + { + FormatResult(interp, + "element %s is not of type \"text\"", + Tcl_GetString(listObjv[j + 1])); + Tcl_AddErrorInfo(interp, + "\n (processing -element option)"); + return TCL_ERROR; + } + sortData.columns[sortData.count - 1].elemCount++; + elemPtr++; + } + } + break; + } case OPT_FIRST: if (TreeItem_FromObj(tree, objv[i + 1], (TreeItem *) &first, 0) != TCL_OK) return TCL_ERROR; @@ -2545,6 +2631,14 @@ int ItemSortCmd(ClientData clientData, Tcl_Interp *interp, int objc, i += numArgs[index]; } + /* If there are no columns, we cannot perform a sort unless -command + * is specified. */ + if ((tree->columnCount < 1) && (sortData.columns[0].sortBy != SORT_COMMAND)) + { + FormatResult(interp, "there are no columns"); + return TCL_ERROR; + } + if (first == last) { if (notReally) @@ -2640,8 +2734,45 @@ int ItemSortCmd(ClientData clientData, Tcl_Interp *interp, int objc, result = TCL_ERROR; goto done; } - if (TreeStyle_GetSortData(tree, - column->style, sortData.columns[i].sortBy, + + /* -element was empty. Find the first text element in the style */ + if (sortData.columns[i].elemCount == 0) + elemIndex = -1; + + /* -element was element name. Find the element in the style */ + else if ((sortData.columns[i].elemCount == 1) && + (sortData.columns[i].elems[0].style == NULL)) + { + if (TreeStyle_FindElement(tree, column->style, + sortData.columns[i].elems[0].elem, &elemIndex) != TCL_OK) + { + result = TCL_ERROR; + goto done; + } + } + + /* -element was style/element pair list */ + else + { + TreeStyle masterStyle = TreeStyle_GetMaster(tree, column->style); + + /* If the item style does not match any in the -element list, + * we will use the first text element in the item style. */ + elemIndex = -1; + + /* Match a style from the -element list. Look in reverse order + * to handle duplicates. */ + for (j = sortData.columns[i].elemCount - 1; j >= 0; j--) + { + if (sortData.columns[i].elems[j].style == masterStyle) + { + elemIndex = sortData.columns[i].elems[j].elemIndex; + break; + } + } + } + if (TreeStyle_GetSortData(tree, column->style, elemIndex, + sortData.columns[i].sortBy, &sortItem1->longValue, &sortItem1->doubleValue, &sortItem1->string) != TCL_OK) |