1 
2 /*	$Id: tixHLCol.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $	*/
3 
4 /*
5  *  tixHLCol.c ---
6  *
7  *
8  *	Implements columns inside tixHList widgets
9  *
10  * Copyright (c) 1996, Expert Interface Technologies
11  *
12  * See the file "license.terms" for information on usage and redistribution
13  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14  *
15  */
16 
17 #include <tixPort.h>
18 #include <tixInt.h>
19 #include <tixHList.h>
20 
21 static TIX_DECLARE_SUBCMD(Tix_HLItemCreate);
22 static TIX_DECLARE_SUBCMD(Tix_HLItemConfig);
23 static TIX_DECLARE_SUBCMD(Tix_HLItemCGet);
24 static TIX_DECLARE_SUBCMD(Tix_HLItemDelete);
25 static TIX_DECLARE_SUBCMD(Tix_HLItemExists);
26 
27 static TIX_DECLARE_SUBCMD(Tix_HLColWidth);
28 
29 static HListElement *	Tix_HLGetColumn(Tcl_Interp *interp, WidgetPtr wPtr,
30 	CONST84 char ** argv, int * column_ret, int mustExist);
31 
32 HListColumn *
Tix_HLAllocColumn(wPtr,chPtr)33 Tix_HLAllocColumn(wPtr, chPtr)
34     WidgetPtr wPtr;
35     HListElement * chPtr;
36 {
37     HListColumn * column;
38     int i;
39 
40     column =
41       (HListColumn*)ckalloc(sizeof(HListColumn)*wPtr->numColumns);
42     for (i=0; i<wPtr->numColumns; i++) {
43 	column[i].type = HLTYPE_COLUMN;
44 	column[i].self = (char*)&column[i];
45 	column[i].chPtr = chPtr;
46 	column[i].iPtr = NULL;
47 	column[i].iPtr = NULL;
48 	column[i].width = UNINITIALIZED;
49     }
50     return column;
51 }
52 
53 static HListElement *
Tix_HLGetColumn(interp,wPtr,argv,column_ret,mustExist)54 Tix_HLGetColumn(interp, wPtr, argv, column_ret, mustExist)
55     Tcl_Interp *interp;
56     WidgetPtr wPtr;
57     CONST84 char ** argv;
58     int * column_ret;
59     int mustExist;
60 {
61     HListElement * chPtr;
62     int column;
63 
64     if ((chPtr = Tix_HLFindElement(interp, wPtr, argv[0])) == NULL) {
65 	return NULL;
66     }
67     if (Tcl_GetInt(interp, argv[1], &column) != TCL_OK) {
68 	return NULL;
69     }
70     if (column >= wPtr->numColumns || column < 0) {
71 	Tcl_AppendResult(interp, "Column \"", argv[1],
72 	    "\" does not exist", (char*)NULL);
73 	return NULL;
74     }
75     if (mustExist && chPtr->col[column].iPtr == NULL) {
76 	Tcl_AppendResult(interp, "entry \"", argv[0],
77 	    "\" does not have an item at column ", argv[1], NULL);
78 	return NULL;
79     }
80 
81     * column_ret = column;
82     return chPtr;
83 }
84 
85 /*----------------------------------------------------------------------
86  * "item" sub command
87  *----------------------------------------------------------------------
88  */
89 int
Tix_HLItem(clientData,interp,argc,argv)90 Tix_HLItem(clientData, interp, argc, argv)
91     ClientData clientData;
92     Tcl_Interp *interp;		/* Current interpreter. */
93     int argc;			/* Number of arguments. */
94     CONST84 char **argv;	/* Argument strings. */
95 {
96     static Tix_SubCmdInfo subCmdInfo[] = {
97 	{TIX_DEFAULT_LEN, "cget", 3, 3, Tix_HLItemCGet,
98 	   "entryPath column option"},
99 	{TIX_DEFAULT_LEN, "configure", 2, TIX_VAR_ARGS, Tix_HLItemConfig,
100 	   "entryPath column ?option? ?value ...?"},
101 	{TIX_DEFAULT_LEN, "create", 2, TIX_VAR_ARGS, Tix_HLItemCreate,
102 	   "entryPath column ?option value ...?"},
103 	{TIX_DEFAULT_LEN, "delete", 2, 2, Tix_HLItemDelete,
104 	   "entryPath column"},
105 	{TIX_DEFAULT_LEN, "exists", 2, 2, Tix_HLItemExists,
106 	   "entryPath column"},
107     };
108     static Tix_CmdInfo cmdInfo = {
109 	Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
110     };
111 
112     return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
113 	interp, argc+1, argv-1);
114 }
115 
116 /*----------------------------------------------------------------------
117  * "item cget" sub command
118  *----------------------------------------------------------------------
119  */
120 static int
Tix_HLItemCGet(clientData,interp,argc,argv)121 Tix_HLItemCGet(clientData, interp, argc, argv)
122     ClientData clientData;
123     Tcl_Interp *interp;		/* Current interpreter. */
124     int argc;			/* Number of arguments. */
125     CONST84 char **argv;	/* Argument strings. */
126 {
127     WidgetPtr wPtr = (WidgetPtr) clientData;
128     HListElement * chPtr;
129     int column;
130 
131     if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
132 	return TCL_ERROR;
133     }
134 
135     return Tk_ConfigureValue(interp, wPtr->dispData.tkwin,
136 	chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
137 	(char *)chPtr->col[column].iPtr, argv[2], 0);
138 }
139 
140 /*----------------------------------------------------------------------
141  * "item configure" sub command
142  *----------------------------------------------------------------------
143  */
144 static int
Tix_HLItemConfig(clientData,interp,argc,argv)145 Tix_HLItemConfig(clientData, interp, argc, argv)
146     ClientData clientData;
147     Tcl_Interp *interp;		/* Current interpreter. */
148     int argc;			/* Number of arguments. */
149     CONST84 char **argv;	/* Argument strings. */
150 {
151     WidgetPtr wPtr = (WidgetPtr) clientData;
152     HListElement * chPtr;
153     int column;
154 
155     if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
156 	return TCL_ERROR;
157     }
158 
159     if (argc == 2) {
160 	return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin,
161 	    chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
162 	    (char *)chPtr->col[column].iPtr, NULL, 0);
163     } else if (argc == 3) {
164 	return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin,
165 	    chPtr->col[column].iPtr->base.diTypePtr->itemConfigSpecs,
166 	    (char *)chPtr->col[column].iPtr, argv[2], 0);
167     } else {
168 	Tix_HLMarkElementDirty(wPtr, chPtr);
169 	Tix_HLResizeWhenIdle(wPtr);
170 
171 	return Tix_DItemConfigure(chPtr->col[column].iPtr,
172 	    argc-2, argv+2, TK_CONFIG_ARGV_ONLY);
173     }
174 }
175 
176 /*----------------------------------------------------------------------
177  * "item create" sub command
178  *----------------------------------------------------------------------
179  */
180 static int
Tix_HLItemCreate(clientData,interp,argc,argv)181 Tix_HLItemCreate(clientData, interp, argc, argv)
182     ClientData clientData;
183     Tcl_Interp *interp;		/* Current interpreter. */
184     int argc;			/* Number of arguments. */
185     CONST84 char **argv;	/* Argument strings. */
186 {
187     WidgetPtr wPtr = (WidgetPtr) clientData;
188     HListElement * chPtr;
189     int column, i;
190     size_t len;
191     Tix_DItem * iPtr;
192     CONST84 char * ditemType = NULL;
193 
194     if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 0)) == NULL) {
195 	return TCL_ERROR;
196     }
197 
198     if (argc %2) {
199 	Tcl_AppendResult(interp, "value for \"", argv[argc-1],
200 	    "\" missing", NULL);
201 	return TCL_ERROR;
202     }
203     for (i=2; i<argc; i+=2) {
204 	len = strlen(argv[i]);
205 	if (strncmp(argv[i], "-itemtype", len) == 0) {
206 	    ditemType = argv[i+1];
207 	}
208     }
209     if (ditemType == NULL) {
210 	ditemType = wPtr->diTypePtr->name;
211     }
212 
213     iPtr = Tix_DItemCreate(&wPtr->dispData, ditemType);
214     if (iPtr == NULL) {
215 	return TCL_ERROR;
216     }
217 
218     iPtr->base.clientData = (ClientData)&chPtr->col[column];
219     if (Tix_DItemConfigure(iPtr, argc-2, argv+2, 0) != TCL_OK) {
220 	return TCL_ERROR;
221     }
222 
223     if (chPtr->col[column].iPtr != NULL) {
224 	if (Tix_DItemType(chPtr->col[column].iPtr) == TIX_DITEM_WINDOW) {
225 	    Tix_WindowItemListRemove(&wPtr->mappedWindows,
226 		chPtr->col[column].iPtr);
227 	}
228 	Tix_DItemFree(chPtr->col[column].iPtr);
229     }
230     chPtr->col[column].iPtr = iPtr;
231     Tix_HLMarkElementDirty(wPtr, chPtr);
232     Tix_HLResizeWhenIdle(wPtr);
233 
234     return TCL_OK;
235 }
236 /*----------------------------------------------------------------------
237  * "item delete" sub command
238  *----------------------------------------------------------------------
239  */
240 static int
Tix_HLItemDelete(clientData,interp,argc,argv)241 Tix_HLItemDelete(clientData, interp, argc, argv)
242     ClientData clientData;
243     Tcl_Interp *interp;		/* Current interpreter. */
244     int argc;			/* Number of arguments. */
245     CONST84 char **argv;	/* Argument strings. */
246 {
247     WidgetPtr wPtr = (WidgetPtr) clientData;
248     HListElement * chPtr;
249     int column;
250 
251     if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 1)) == NULL) {
252 	return TCL_ERROR;
253     }
254 
255     if (column == 0) {
256 	Tcl_AppendResult(interp,"Cannot delete item at column 0",(char*)NULL);
257 	return TCL_ERROR;
258     }
259 
260     if (Tix_DItemType(chPtr->col[column].iPtr) == TIX_DITEM_WINDOW) {
261 	Tix_WindowItemListRemove(&wPtr->mappedWindows,
262 	    chPtr->col[column].iPtr);
263     }
264 
265     /* Free the item and leave a blank */
266     Tix_DItemFree(chPtr->col[column].iPtr);
267     chPtr->col[column].iPtr = NULL;
268 
269     Tix_HLMarkElementDirty(wPtr, chPtr);
270     Tix_HLResizeWhenIdle(wPtr);
271 
272     return TCL_OK;
273 }
274 
275 /*----------------------------------------------------------------------
276  * "item exists" sub command
277  *----------------------------------------------------------------------
278  */
279 static int
Tix_HLItemExists(clientData,interp,argc,argv)280 Tix_HLItemExists(clientData, interp, argc, argv)
281     ClientData clientData;
282     Tcl_Interp *interp;		/* Current interpreter. */
283     int argc;			/* Number of arguments. */
284     CONST84 char **argv;	/* Argument strings. */
285 {
286     WidgetPtr wPtr = (WidgetPtr) clientData;
287     HListElement * chPtr;
288     int column;
289 
290     if ((chPtr=Tix_HLGetColumn(interp, wPtr, argv, &column, 0)) == NULL) {
291 	return TCL_ERROR;
292     }
293 
294     if (chPtr->col[column].iPtr == NULL) {
295 	Tcl_AppendResult(interp, "0", NULL);
296     } else {
297 	Tcl_AppendResult(interp, "1", NULL);
298     }
299 
300     return TCL_OK;
301 }
302 /*----------------------------------------------------------------------
303  * "column" sub command
304  *----------------------------------------------------------------------
305  */
306 int
Tix_HLColumn(clientData,interp,argc,argv)307 Tix_HLColumn(clientData, interp, argc, argv)
308     ClientData clientData;
309     Tcl_Interp *interp;		/* Current interpreter. */
310     int argc;			/* Number of arguments. */
311     CONST84 char **argv;	/* Argument strings. */
312 {
313     static Tix_SubCmdInfo subCmdInfo[] = {
314 	{TIX_DEFAULT_LEN, "width", 1, 3, Tix_HLColWidth,
315 	   "column ?-char? ?size?"},
316     };
317     static Tix_CmdInfo cmdInfo = {
318 	Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
319     };
320 
321     return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
322 	interp, argc+1, argv-1);
323 }
324 
325 /*----------------------------------------------------------------------
326  * "column width" sub command
327  *----------------------------------------------------------------------
328  */
329 static int
Tix_HLColWidth(clientData,interp,argc,argv)330 Tix_HLColWidth(clientData, interp, argc, argv)
331     ClientData clientData;
332     Tcl_Interp *interp;		/* Current interpreter. */
333     int argc;			/* Number of arguments. */
334     CONST84 char **argv;	/* Argument strings. */
335 {
336     WidgetPtr wPtr = (WidgetPtr) clientData;
337     int column;
338     char buff[128];
339     int newWidth;
340 
341     if (Tcl_GetInt(interp, argv[0], &column) != TCL_OK) {
342 	return TCL_ERROR;
343     }
344     if (column >= wPtr->numColumns || column < 0) {
345 	Tcl_AppendResult(interp, "Column \"", argv[0],
346 	    "\" does not exist", (char*)NULL);
347 	return TCL_ERROR;
348     }
349     if (argc == 1) {		/* Query */
350 	if (wPtr->root->dirty || wPtr->allDirty) {
351 	    /* We must update the geometry NOW otherwise we will get a wrong
352 	     * width
353 	     */
354 	    Tix_HLCancelResizeWhenIdle(wPtr);
355 	    Tix_HLComputeGeometry((ClientData)wPtr);
356 	}
357 	sprintf(buff, "%d", wPtr->actualSize[column].width);
358 	Tcl_AppendResult(interp, buff, NULL);
359 	return TCL_OK;
360     }
361     else if (argc == 2) {
362 	if (argv[1][0] == '\0') {
363 	    newWidth = UNINITIALIZED;
364 	    goto setwidth;
365 	}
366 	if (Tk_GetPixels(interp, wPtr->dispData.tkwin, argv[1],
367 		 &newWidth) != TCL_OK) {
368 	    return TCL_ERROR;
369 	}
370  	if (newWidth < 0) {
371 	    newWidth = 0;
372 	}
373     }
374     else if (argc == 3 && strcmp(argv[1], "-char")==0) {
375 	if (argv[2][0] == '\0') {
376 	    newWidth = UNINITIALIZED;
377 	    goto setwidth;
378 	}
379 	if (Tcl_GetInt(interp, argv[2], &newWidth) != TCL_OK) {
380 	    return TCL_ERROR;
381 	}
382 	if (newWidth < 0) {
383 	    newWidth = 0;
384 	}
385 	newWidth *= wPtr->scrollUnit[0];
386     }
387     else {
388 	return Tix_ArgcError(interp, argc+3, argv-3, 3,
389 	    "column ?-char? ?size?");
390     }
391 
392   setwidth:
393 
394     if (wPtr->reqSize[column].width == newWidth) {
395 	return TCL_OK;
396     } else {
397 	wPtr->reqSize[column].width = newWidth;
398     }
399 
400     if (wPtr->actualSize[column].width == newWidth) {
401 	return TCL_OK;
402     } else {
403 	wPtr->allDirty = 1;
404 	Tix_HLResizeWhenIdle(wPtr);
405 	return TCL_OK;
406     }
407 }
408