summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authortreectrl <treectrl>2006-10-14 19:52:42 (GMT)
committertreectrl <treectrl>2006-10-14 19:52:42 (GMT)
commitd18ff88a19a4c7b21628f05b04dcaf34dc0dab0e (patch)
tree567e03afbd2a51efa659757bbcf94154876b846f /generic
parent1385bea6f89b0585d53707fc12d2b934c8f6b245 (diff)
downloadtktreectrl-d18ff88a19a4c7b21628f05b04dcaf34dc0dab0e.zip
tktreectrl-d18ff88a19a4c7b21628f05b04dcaf34dc0dab0e.tar.gz
tktreectrl-d18ff88a19a4c7b21628f05b04dcaf34dc0dab0e.tar.bz2
TreeColumn_FromObj sets CFO_NOT_MANY by default.
Added -indicatorside option to [column dragconfigure]. Added CFO_LIST_ALL flag. Moved ColumnForEach declarations to tkTreeCtrl.h. Disallow changing the -lock option of the tail column. Rewrote [column delete] to use multi-column descriptions. Fix [column move] to allow proper reordering of locked columns.
Diffstat (limited to 'generic')
-rw-r--r--generic/tkTreeColumn.c271
1 files changed, 221 insertions, 50 deletions
diff --git a/generic/tkTreeColumn.c b/generic/tkTreeColumn.c
index 4065504..09e9012 100644
--- a/generic/tkTreeColumn.c
+++ b/generic/tkTreeColumn.c
@@ -7,7 +7,7 @@
* Copyright (c) 2002-2003 Christian Krone
* Copyright (c) 2003 ActiveState Corporation
*
- * RCS: @(#) $Id: tkTreeColumn.c,v 1.43 2006/10/11 01:13:43 treectrl Exp $
+ * RCS: @(#) $Id: tkTreeColumn.c,v 1.44 2006/10/14 19:52:42 treectrl Exp $
*/
#include "tkTreeCtrl.h"
@@ -393,7 +393,7 @@ Tk_ObjCustomOption columnCustomOption =
ColumnOptionGet,
ColumnOptionRestore,
NULL,
- (ClientData) (CFO_NOT_MANY | CFO_NOT_NULL)
+ (ClientData) (CFO_NOT_NULL)
};
/*
@@ -409,7 +409,7 @@ Tk_ObjCustomOption columnCustomOption_NOT_TAIL =
ColumnOptionGet,
ColumnOptionRestore,
NULL,
- (ClientData) (CFO_NOT_MANY | CFO_NOT_NULL | CFO_NOT_TAIL)
+ (ClientData) (CFO_NOT_NULL | CFO_NOT_TAIL)
};
static Tk_OptionSpec dragSpecs[] = {
@@ -434,6 +434,9 @@ static Tk_OptionSpec dragSpecs[] = {
{TK_OPTION_CUSTOM, "-indicatorcolumn", (char *) NULL, (char *) NULL,
(char *) NULL, -1, Tk_Offset(TreeCtrl, columnDrag.indColumn),
TK_OPTION_NULL_OK, (ClientData) &columnCustomOption, 0},
+ {TK_OPTION_STRING_TABLE, "-indicatorside", (char *) NULL, (char *) NULL,
+ "left", -1, Tk_Offset(TreeCtrl, columnDrag.indSide),
+ 0, (ClientData) arrowSideST, 0},
{TK_OPTION_END, (char *) NULL, (char *) NULL, (char *) NULL,
(char *) NULL, 0, -1, 0, 0, 0}
};
@@ -828,6 +831,14 @@ TreeColumnList_FromObj(
TreeColumnList_Append(columns, tree->columnTail);
}
column = NULL;
+ } else if (flags & CFO_LIST_ALL) {
+ column = (Column *) tree->columns;
+ while (column != NULL) {
+ TreeColumnList_Append(columns, (TreeColumn) column);
+ column = column->next;
+ }
+ TreeColumnList_Append(columns, tree->columnTail);
+ column = NULL;
} else {
column = (Column *) COLUMN_ALL;
}
@@ -902,11 +913,11 @@ TreeColumnList_FromObj(
Column *first, *last;
if (TreeColumn_FromObj(tree, objv[listIndex + 1],
- &_first, CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ &_first, CFO_NOT_NULL) != TCL_OK)
goto errorExit;
first = (Column *) _first;
if (TreeColumn_FromObj(tree, objv[listIndex + 2],
- &_last, CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ &_last, CFO_NOT_NULL) != TCL_OK)
goto errorExit;
last = (Column *) _last;
if (first->index > last->index) {
@@ -1164,7 +1175,7 @@ TreeColumn_FromObj(
{
TreeColumnList columns;
- if (TreeColumnList_FromObj(tree, objPtr, &columns, flags) != TCL_OK)
+ if (TreeColumnList_FromObj(tree, objPtr, &columns, flags | CFO_NOT_MANY) != TCL_OK)
return TCL_ERROR;
/* May be NULL. */
(*columnPtr) = TreeColumnList_Nth(&columns, 0);
@@ -1180,7 +1191,7 @@ TreeColumn_FromObj(
* Determine the order of two columns and swap them if needed.
*
* Results:
- * The return value is the number of items in the range between
+ * The return value is the number of columns in the range between
* first and last.
*
* Side effects:
@@ -1211,34 +1222,18 @@ TreeColumn_FirstAndLast(
return indexLast - indexFirst + 1;
}
-typedef struct ColumnForEach ColumnForEach;
-struct ColumnForEach {
- TreeCtrl *tree;
- int error;
- int all;
- TreeColumn last;
- TreeColumn current;
- TreeColumnList *list;
- int index;
-};
-
-#define COLUMN_FOR_EACH(column, columns, column2s, iter) \
- for (column = ColumnForEach_Start(columns, column2s, iter); \
- column != NULL; \
- column = ColumnForEach_Next(iter))
-
/*
*----------------------------------------------------------------------
*
* ColumnForEach_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.
+ * Begin iterating over items. A command might accept two column
+ * descriptions for a range of column, or a single column description
+ * which may itself refer to multiple column. Either column
+ * description could be COLUMN_ALL.
*
* Results:
- * Returns the first item to iterate over. If an error occurs
+ * Returns the first column to iterate over. If an error occurs
* then ColumnForEach.error is set to 1.
*
* Side effects:
@@ -1271,6 +1266,7 @@ ColumnForEach_Start(
iter->all = TRUE;
if (tree->columns == NULL)
return iter->current = tree->columnTail;
+ iter->next = TreeColumn_Next(tree->columns);
return iter->current = tree->columns;
}
@@ -1279,6 +1275,7 @@ ColumnForEach_Start(
iter->error = 1;
return NULL;
}
+ iter->next = TreeColumn_Next(column);
iter->last = column2;
return iter->current = column;
}
@@ -1311,14 +1308,16 @@ ColumnForEach_Next(
)
{
TreeCtrl *tree = iter->tree;
- TreeColumn next = TreeColumn_Next(iter->current);
+ TreeColumn column;
if (iter->all) {
if (iter->current == tree->columnTail)
return iter->current = NULL;
- if (next == NULL)
+ column = iter->next;
+ if (column == NULL)
return iter->current = tree->columnTail;
- return iter->current = next;
+ iter->next = TreeColumn_Next(column);
+ return iter->current = column;
}
if (iter->list != NULL) {
@@ -1329,9 +1328,9 @@ ColumnForEach_Next(
if (iter->current == iter->last)
return iter->current = NULL;
- if (next == NULL)
- return iter->current = tree->columnTail;
- return iter->current = next;
+ column = iter->next;
+ iter->next = TreeColumn_Next(column);
+ return iter->current = column;
}
/*
@@ -1608,7 +1607,7 @@ unknown:
#ifdef COLUMN_LOCK
void DumpColumns(TreeCtrl *tree)
{
- Column *column = tree->columns;
+ Column *column = (Column *) tree->columns;
return;
dbwin("DumpColumns: columnFirst id=%d\n",
tree->columns ? TreeColumn_GetID(tree->columns) : -1);
@@ -1869,6 +1868,13 @@ Column_Config(
saved.itemBgCount = column->itemBgCount;
}
+ if ((column == (Column *) tree->columnTail) &&
+ (column->lock != COLUMN_LOCK_NONE)) {
+ FormatResult(tree->interp,
+ "can't change the -lock option of the tail column");
+ continue;
+ }
+
/*
* Step 2: Process new values
*/
@@ -3444,7 +3450,7 @@ TreeColumnCmd(
return TCL_ERROR;
}
if (TreeColumn_FromObj(tree, objv[3], &_column,
- CFO_NOT_MANY | CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK)
+ CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK)
return TCL_ERROR;
if (TreeColumn_Bbox(_column, &left, &top, &width, &height) < 0)
break;
@@ -3463,7 +3469,7 @@ TreeColumnCmd(
return TCL_ERROR;
}
if (TreeColumn_FromObj(tree, objv[3], &column,
- CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
resultObjPtr = Tk_GetOptionValue(interp, (char *) column,
((Column *) column)->optionTable, objv[4], tree->tkwin);
@@ -3485,13 +3491,13 @@ TreeColumnCmd(
return TCL_ERROR;
}
if (TreeColumn_FromObj(tree, objv[3], &column1,
- CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
if (Tcl_GetIndexFromObj(interp, objv[4], opName,
"comparison operator", 0, &op) != TCL_OK)
return TCL_ERROR;
if (TreeColumn_FromObj(tree, objv[5], &column2,
- CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
index1 = TreeColumn_Index(column1);
index2 = TreeColumn_Index(column2);
@@ -3516,7 +3522,7 @@ TreeColumnCmd(
if (objc <= 5) {
Tcl_Obj *resultObjPtr;
if (TreeColumn_FromObj(tree, objv[3], &_column,
- CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
column = (Column *) _column;
resultObjPtr = Tk_GetOptionInfo(interp, (char *) column,
@@ -3528,7 +3534,11 @@ TreeColumnCmd(
Tcl_SetObjResult(interp, resultObjPtr);
break;
}
- if (TreeColumnList_FromObj(tree, objv[3], &columns, CFO_NOT_NULL) != TCL_OK)
+ /* If "all" is specified, return a list of columns instead of
+ * COLUMN_ALL, since changing the -lock option of a column
+ * may reorder columns. */
+ if (TreeColumnList_FromObj(tree, objv[3], &columns,
+ CFO_LIST_ALL | CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
COLUMN_FOR_EACH(_column, &columns, NULL, &iter) {
if (Column_Config((Column *) _column, objc - 4, objv + 4, FALSE) != TCL_OK)
@@ -3591,6 +3601,136 @@ TreeColumnCmd(
/* T column delete first ?last? */
case COMMAND_DELETE:
{
+#if 1
+ TreeColumnList columns, column2s;
+ TreeColumn _column;
+ Column *column, *prev, *next;
+ int flags = CFO_NOT_NULL | CFO_NOT_TAIL;
+ ColumnForEach citer;
+ TreeItem item;
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch search;
+ int index;
+
+ if (objc < 4 || objc > 5) {
+ Tcl_WrongNumArgs(interp, 3, objv, "first ?last?");
+ return TCL_ERROR;
+ }
+ if (objc == 5)
+ flags |= CFO_NOT_MANY;
+ if (TreeColumnList_FromObj(tree, objv[3], &columns,
+ flags) != TCL_OK)
+ return TCL_ERROR;
+ if (objc == 5) {
+ if (TreeColumnList_FromObj(tree, objv[4], &column2s,
+ CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK)
+ return TCL_ERROR;
+ }
+ COLUMN_FOR_EACH(_column, &columns, (objc == 5) ? &column2s : NULL,
+ &citer) {
+ /* T column delete "all" */
+ if (citer.all) {
+ column = (Column *) tree->columns;
+ while (column != NULL) {
+ column = Column_Free(column);
+ }
+ ((Column *) tree->columnTail)->index = 0;
+ tree->columns = NULL;
+ tree->columnLast = NULL;
+#ifdef COLUMN_LOCK
+ tree->columnLockLeft = NULL;
+ tree->columnLockNone = NULL;
+ tree->columnLockRight = NULL;
+#endif
+ /* Delete all TreeItemColumns */
+ hPtr = Tcl_FirstHashEntry(&tree->itemHash, &search);
+ while (hPtr != NULL) {
+ item = (TreeItem) Tcl_GetHashValue(hPtr);
+ TreeItem_RemoveAllColumns(tree, item);
+ hPtr = Tcl_NextHashEntry(&search);
+ }
+
+ tree->columnTree = NULL;
+ tree->columnDrag.column = tree->columnDrag.indColumn = NULL;
+ tree->widthOfColumns = tree->headerHeight = -1;
+#ifdef COLUMN_LOCK
+ tree->widthOfColumnsLeft = tree->widthOfColumnsRight = -1;
+#endif
+ Tree_DInfoChanged(tree, DINFO_REDO_COLUMN_WIDTH);
+ goto doneDELETE;
+ }
+ column = (Column *) _column;
+
+ /* Delete all TreeItemColumns */
+ hPtr = Tcl_FirstHashEntry(&tree->itemHash, &search);
+ while (hPtr != NULL) {
+ item = (TreeItem) Tcl_GetHashValue(hPtr);
+ TreeItem_RemoveColumns(tree, item, column->index,
+ column->index);
+ hPtr = Tcl_NextHashEntry(&search);
+ }
+
+ /* Unlink. */
+ prev = column->prev;
+ next = column->next;
+ if (prev == NULL)
+ tree->columns = (TreeColumn) next;
+ else
+ prev->next = next;
+ if (next == NULL)
+ tree->columnLast = (TreeColumn) prev;
+ else
+ next->prev = prev;
+
+ if (_column == tree->columnTree)
+ tree->columnTree = NULL;
+ if (_column == tree->columnDrag.column)
+ tree->columnDrag.column = NULL;
+ if (_column == tree->columnDrag.indColumn)
+ tree->columnDrag.indColumn = NULL;
+
+ (void) Column_Free(column);
+
+ /* Renumber trailing columns */
+ column = next;
+ while (column != NULL) {
+ column->index--;
+ column = column->next;
+ }
+ }
+
+#ifdef COLUMN_LOCK
+ tree->columnLockLeft = NULL;
+ tree->columnLockNone = NULL;
+ tree->columnLockRight = NULL;
+#endif
+ index = 0;
+ column = (Column *) tree->columns;
+ while (column != NULL) {
+ column->index = index++;
+#ifdef COLUMN_LOCK
+ if (column->lock == COLUMN_LOCK_LEFT && tree->columnLockLeft == NULL)
+ tree->columnLockLeft = (TreeColumn) column;
+ if (column->lock == COLUMN_LOCK_NONE && tree->columnLockNone == NULL)
+ tree->columnLockNone = (TreeColumn) column;
+ if (column->lock == COLUMN_LOCK_RIGHT && tree->columnLockRight == NULL)
+ tree->columnLockRight = (TreeColumn) column;
+#endif
+ column = column->next;
+ }
+ ((Column *) tree->columnTail)->index = index;
+
+ tree->widthOfColumns = tree->headerHeight = -1;
+#ifdef COLUMN_LOCK
+ tree->widthOfColumnsLeft = tree->widthOfColumnsRight = -1;
+#endif
+ Tree_DInfoChanged(tree, DINFO_REDO_COLUMN_WIDTH);
+
+doneDELETE:
+ TreeItemList_Free(&columns);
+ if (objc == 5)
+ TreeItemList_Free(&column2s);
+#else
int firstIndex, lastIndex;
TreeColumn _column;
Column *column, *first, *last, *prev = NULL, *next = NULL;
@@ -3725,6 +3865,7 @@ TreeColumnCmd(
tree->widthOfColumnsLeft = tree->widthOfColumnsRight = -1;
#endif
Tree_DInfoChanged(tree, DINFO_REDO_COLUMN_WIDTH);
+#endif
break;
}
@@ -3804,7 +3945,7 @@ TreeColumnCmd(
return TCL_ERROR;
}
if (TreeColumn_FromObj(tree, objv[3], &_column,
- CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
column = (Column *) _column;
/* Update layout if needed */
@@ -3872,22 +4013,49 @@ TreeColumnCmd(
{
TreeColumn _move, _before;
Column *move, *before;
-
+#ifdef COLUMN_LOCK
+ Column *first = NULL, *last = (Column *) tree->columnTail;
+#endif
if (objc != 5) {
Tcl_WrongNumArgs(interp, 3, objv, "column before");
return TCL_ERROR;
}
if (TreeColumn_FromObj(tree, objv[3], &_move,
- CFO_NOT_MANY | CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK)
+ CFO_NOT_NULL | CFO_NOT_TAIL) != TCL_OK)
return TCL_ERROR;
move = (Column *) _move;
if (TreeColumn_FromObj(tree, objv[4], &_before,
- CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
before = (Column *) _before;
+
+ if ((move == before) || (move->index == before->index - 1))
+ break;
#ifdef COLUMN_LOCK
- if (move->lock != before->lock)
+ switch (move->lock) {
+ case COLUMN_LOCK_LEFT:
+ first = (Column *) tree->columnLockLeft;
+ if (tree->columnLockNone != NULL)
+ last = (Column *) tree->columnLockNone;
+ else if (tree->columnLockRight != NULL)
+ last = (Column *) tree->columnLockRight;
+ break;
+ case COLUMN_LOCK_NONE:
+ first = (Column *) tree->columnLockNone;
+ if (tree->columnLockRight != NULL)
+ last = (Column *) tree->columnLockRight;
+ break;
+ case COLUMN_LOCK_RIGHT:
+ first = (Column *) tree->columnLockRight;
+ break;
+ }
+ if (before->index < first->index || before->index > last->index) {
+ FormatResult(tree->interp,
+ "column %s%d and column %s%d -lock options conflict",
+ tree->columnPrefix, move->id,
+ tree->columnPrefix, before->id);
return TCL_ERROR;
+ }
#endif
Column_Move(move, before);
break;
@@ -3904,7 +4072,7 @@ TreeColumnCmd(
return TCL_ERROR;
}
if (TreeColumn_FromObj(tree, objv[3], &_column,
- CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
column = (Column *) _column;
/* Update layout if needed */
@@ -3939,7 +4107,7 @@ TreeColumnCmd(
}
}
if (TreeColumn_FromObj(tree, objv[3], &_column,
- CFO_NOT_MANY | CFO_NOT_NULL) != TCL_OK)
+ CFO_NOT_NULL) != TCL_OK)
return TCL_ERROR;
column = (Column *) _column;
if (visible) {
@@ -4480,7 +4648,10 @@ Tree_DrawHeader(
}
if (tree->columnDrag.indColumn != NULL) {
if (TreeColumn_Bbox(tree->columnDrag.indColumn, &indX, &y, &w, &h) == 0) {
- indX -= 1;
+ if (tree->columnDrag.indSide == SIDE_LEFT)
+ indX -= 1;
+ else
+ indX += w - 1;
indDraw = TRUE;
}
}
@@ -4961,7 +5132,7 @@ Tree_HeaderUnderPoint(
int hit;
hit = Tree_HitTest(tree, x, y);
- if (!nearest && (hit != TREE_HIT_HEADER))
+ if (!nearest && (hit != TREE_AREA_HEADER))
return NULL;
if (nearest) {