1
2 /* $Id: tixGrSel.c,v 1.2 2004/03/28 02:44:56 hobbs Exp $ */
3
4 /*
5 * tixGrSel.c --
6 *
7 * This module handles the selection
8 *
9 * Copyright (c) 1996, Expert Interface Technologies
10 *
11 * See the file "license.terms" for information on usage and redistribution
12 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 *
14 */
15
16 #include <tixPort.h>
17 #include <tixInt.h>
18 #include <tixDef.h>
19 #include <tixGrid.h>
20
21 EXTERN TIX_DECLARE_SUBCMD(Tix_GrSelection);
22 static TIX_DECLARE_SUBCMD(Tix_GrSelIncludes);
23 static TIX_DECLARE_SUBCMD(Tix_GrSelModify);
24
25 static int Tix_GrSelIncludes _ANSI_ARGS_((ClientData clientData,
26 Tcl_Interp *interp, int argc, CONST84 char **argv));
27 static void Tix_GrAdjustSelection _ANSI_ARGS_((
28 WidgetPtr wPtr, SelectBlock * sbPtr));
29 static void Tix_GrMergeSelection _ANSI_ARGS_((
30 WidgetPtr wPtr, SelectBlock * sbPtr));
31
32 int
Tix_GrSelection(clientData,interp,argc,argv)33 Tix_GrSelection(clientData, interp, argc, argv)
34 ClientData clientData;
35 Tcl_Interp *interp; /* Current interpreter. */
36 int argc; /* Number of arguments. */
37 CONST84 char **argv; /* Argument strings. */
38 {
39 static Tix_SubCmdInfo subCmdInfo[] = {
40 {TIX_DEFAULT_LEN, "adjust", 2, 4, Tix_GrSelModify,
41 "x1 y1 ?x2 y2?"},
42 {TIX_DEFAULT_LEN, "clear", 2, 4, Tix_GrSelModify,
43 "x1 y1 ?x2 y2?"},
44 {TIX_DEFAULT_LEN, "includes", 2, 4, Tix_GrSelIncludes,
45 "x1 y1 ?x2 y2?"},
46 {TIX_DEFAULT_LEN, "set", 2, 4, Tix_GrSelModify,
47 "x1 y1 ?x2 y2?"},
48 {TIX_DEFAULT_LEN, "toggle", 2, 4, Tix_GrSelModify,
49 "x1 y1 ?x2 y2?"},
50 };
51 static Tix_CmdInfo cmdInfo = {
52 Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? ?arg ...?",
53 };
54
55 return Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
56 interp, argc+1, argv-1);
57 }
58
59 static int
Tix_GrSelIncludes(clientData,interp,argc,argv)60 Tix_GrSelIncludes(clientData, interp, argc, argv)
61 ClientData clientData;
62 Tcl_Interp *interp; /* Current interpreter. */
63 int argc; /* Number of arguments. */
64 CONST84 char **argv; /* Argument strings. */
65 {
66 #if 0
67 WidgetPtr wPtr = (WidgetPtr) clientData;
68 #endif
69 return TCL_OK;
70 }
71
72 static void
Tix_GrMergeSelection(wPtr,sbPtr)73 Tix_GrMergeSelection(wPtr, sbPtr)
74 WidgetPtr wPtr;
75 SelectBlock * sbPtr;
76 {
77 Tix_ListIterator li;
78
79 switch (sbPtr->type) {
80 case TIX_GR_SET:
81 case TIX_GR_CLEAR:
82 if (sbPtr->range[0][0] == 0 &&
83 sbPtr->range[1][0] == 0 &&
84 sbPtr->range[0][1] == TIX_GR_MAX &&
85 sbPtr->range[1][1] == TIX_GR_MAX) {
86
87 /* clear everything else from the list
88 */
89 Tix_SimpleListIteratorInit(&li);
90
91 for (Tix_SimpleListStart(&wPtr->selList, &li);
92 !Tix_SimpleListDone(&li);
93 Tix_SimpleListNext (&wPtr->selList, &li)) {
94
95 SelectBlock *ptr = (SelectBlock *)li.curr;
96 Tix_SimpleListDelete(&wPtr->selList, &li);
97 ckfree((char*)ptr);
98 }
99 }
100 if (sbPtr->type == TIX_GR_SET) {
101 Tix_SimpleListAppend(&wPtr->selList, (char*)sbPtr, 0);
102 }
103 goto done;
104 }
105
106 #if 0
107
108 switch (sbPtr->type) {
109 case TIX_GR_TOGGLE: {
110 }
111 break;
112 case TIX_GR_SET: {
113 Tix_SimpleListAppend(&wPtr->selList, (char*)sbPtr, 0);
114 }
115 break;
116 case TIX_GR_CLEAR: {
117 Tix_SimpleListIteratorInit(&li);
118
119 for (Tix_SimpleListStart(&wPtr->selList, &li);
120 !Tix_SimpleListDone(&li);
121 Tix_SimpleListNext (&wPtr->selList, &li)) {
122 }
123 }
124
125 }
126 #else
127
128 Tix_SimpleListAppend(&wPtr->selList, (char*)sbPtr, 0);
129
130 #endif
131
132 done:
133 Tix_GrAddChangedRect(wPtr, sbPtr->range, 0);
134 }
135
136 static void
Tix_GrAdjustSelection(wPtr,sbPtr)137 Tix_GrAdjustSelection(wPtr, sbPtr)
138 WidgetPtr wPtr;
139 SelectBlock * sbPtr;
140 {
141 int changed[2][2];
142 SelectBlock * current;
143
144 current = (SelectBlock*)wPtr->selList.tail;
145
146 /*
147 * The changed region is the union of the area of the current selection
148 * and the adjusted selection.
149 */
150 changed[TIX_X][0] = sbPtr->range[TIX_X][0];
151 changed[TIX_X][1] = sbPtr->range[TIX_X][1];
152 changed[TIX_Y][0] = sbPtr->range[TIX_Y][0];
153 changed[TIX_Y][1] = sbPtr->range[TIX_Y][1];
154
155 if (changed[TIX_X][0] > current->range[TIX_X][0]) {
156 changed[TIX_X][0] = current->range[TIX_X][0];
157 }
158 if (changed[TIX_X][1] < current->range[TIX_X][1]) {
159 changed[TIX_X][1] = current->range[TIX_X][1];
160 }
161 if (changed[TIX_Y][0] > current->range[TIX_Y][0]) {
162 changed[TIX_Y][0] = current->range[TIX_Y][0];
163 }
164 if (changed[TIX_Y][1] < current->range[TIX_Y][1]) {
165 changed[TIX_Y][1] = current->range[TIX_Y][1];
166 }
167
168 /* Adjust the current selection according to sbPtr */
169 current->range[TIX_X][0] = sbPtr->range[TIX_X][0];
170 current->range[TIX_X][1] = sbPtr->range[TIX_X][1];
171 current->range[TIX_Y][0] = sbPtr->range[TIX_Y][0];
172 current->range[TIX_Y][1] = sbPtr->range[TIX_Y][1];
173
174 /* Set the changed area */
175 Tix_GrAddChangedRect(wPtr, changed, 0);
176
177 /* sbPtr is no longer needed */
178 ckfree((char*)sbPtr);
179 }
180
181 static int
Tix_GrSelModify(clientData,interp,argc,argv)182 Tix_GrSelModify(clientData, interp, argc, argv)
183 ClientData clientData;
184 Tcl_Interp *interp; /* Current interpreter. */
185 int argc; /* Number of arguments. */
186 CONST84 char **argv; /* Argument strings. */
187 {
188 WidgetPtr wPtr = (WidgetPtr) clientData;
189 int type, adjust = 0;
190 SelectBlock * sbPtr = NULL;
191 int tmp;
192
193 if (argc != 2 && argc != 4) {
194 return Tix_ArgcError(interp, argc+2, argv-2, 2, "x1 y1 ?x2 y2?");
195 }
196
197 /*
198 * (1) find out the type of operation.
199 */
200 if (argv[-1][0] == 'a') {
201 if (wPtr->selList.numItems <= 0) {
202 /*
203 * There is nothing in the selection list to adjust!
204 */
205 Tcl_AppendResult(interp, "selection list is empty", NULL);
206 return TCL_ERROR;
207 }
208 adjust = 1;
209 type = 0;
210 }
211 else if (argv[-1][0] == 'c') {
212 type = TIX_GR_CLEAR;
213 }
214 else if (argv[-1][0] == 's') {
215 type = TIX_GR_SET;
216 }
217 else {
218 type = TIX_GR_TOGGLE;
219 }
220
221 sbPtr = (SelectBlock*)ckalloc(sizeof(SelectBlock));
222 sbPtr->type = type;
223
224 if (Tcl_GetInt(interp, argv[0], &sbPtr->range[0][0]) != TCL_OK) {
225 goto error;
226 }
227 if (Tcl_GetInt(interp, argv[1], &sbPtr->range[1][0]) != TCL_OK) {
228 goto error;
229 }
230 if (argc == 4) {
231 if (Tcl_GetInt(interp, argv[2], &sbPtr->range[0][1]) != TCL_OK) {
232 if (strcmp(argv[2], "max") == 0) {
233 Tcl_ResetResult(interp);
234 sbPtr->range[0][1] = TIX_GR_MAX;
235 } else {
236 goto error;
237 }
238 }
239 if (Tcl_GetInt(interp, argv[3], &sbPtr->range[1][1]) != TCL_OK) {
240 if (strcmp(argv[3], "max") == 0) {
241 Tcl_ResetResult(interp);
242 sbPtr->range[1][1] = TIX_GR_MAX;
243 } else {
244 goto error;
245 }
246 }
247 } else {
248 sbPtr->range[0][1] = sbPtr->range[0][0];
249 sbPtr->range[1][1] = sbPtr->range[1][0];
250 }
251
252 if (wPtr->selectUnit != tixRowUid) {
253 if (sbPtr->range[0][0] > sbPtr->range[0][1]) {
254 tmp = sbPtr->range[0][1];
255 sbPtr->range[0][1] = sbPtr->range[0][0];
256 sbPtr->range[0][0] = tmp;
257 }
258 } else {
259 sbPtr->range[0][0] = 0;
260 sbPtr->range[0][1] = TIX_GR_MAX;
261 }
262
263 if (wPtr->selectUnit != tixColumnUid) {
264 if (sbPtr->range[1][0] > sbPtr->range[1][1]) {
265 tmp = sbPtr->range[1][1];
266 sbPtr->range[1][1] = sbPtr->range[1][0];
267 sbPtr->range[1][0] = tmp;
268 }
269 } else {
270 sbPtr->range[1][0] = 0;
271 sbPtr->range[1][1] = TIX_GR_MAX;
272 }
273
274 if (adjust) {
275 Tix_GrAdjustSelection(wPtr, sbPtr);
276 sbPtr = NULL;
277 } else {
278 Tix_GrMergeSelection(wPtr, sbPtr);
279 }
280 wPtr->toComputeSel = 1;
281 return TCL_OK;
282
283 error:
284 if (sbPtr) {
285 ckfree((char*)sbPtr);
286 }
287 return TCL_ERROR;
288 }
289