OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tix/] [generic/] [tixOption.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tixOption.c --
3
 *
4
 *      Handle the "$widget config" commands
5
 *
6
 * Copyright (c) 1996, Expert Interface Technologies
7
 *
8
 * See the file "license.terms" for information on usage and redistribution
9
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10
 *
11
 */
12
 
13
/* ToDo:
14
 *
15
 * 1) ConfigSpec structures shouldn't be shared between parent and child
16
 *    classes.
17
 * 2) Specs array should be compacted (no duplication) and sorted according
18
 *    to argvName during class declaration.
19
 * 3) Merge aliases with specs
20
 *
21
 */
22
#include <tk.h>
23
#include <tixPort.h>
24
#include <tixInt.h>
25
 
26
static char *                   FormatConfigInfo _ANSI_ARGS_((
27
                                    Tcl_Interp *interp, TixClassRecord *cPtr,
28
                                    char * widRec, TixConfigSpec * spec));
29
/*
30
 * This is a lightweight interface for querying the value of a
31
 * variable in the object. This is simpler compared to
32
 * [lindex [$w config -flag] 4]
33
 */
34
int Tix_GetVar (interp, cPtr, widRec, flag)
35
    Tcl_Interp *interp;
36
    TixClassRecord *cPtr;
37
    char * widRec;
38
    char * flag;
39
{
40
    TixConfigSpec * spec;
41
    char * value;
42
 
43
    spec = Tix_FindConfigSpecByName(interp, cPtr, flag);
44
    if (spec != NULL) {
45
        if (spec->isAlias) {
46
            flag = spec->realPtr->argvName;
47
        } else {
48
            /* The user may have specified a shorthand like -backgro */
49
            flag = spec->argvName;
50
        }
51
        value = Tcl_GetVar2(interp, widRec, flag, TCL_GLOBAL_ONLY);
52
 
53
        Tcl_AppendResult(interp, value, (char*)NULL);
54
        return TCL_OK;
55
    }
56
    else {
57
        return TCL_ERROR;
58
    }
59
}
60
 
61
int
62
Tix_QueryOneOption(interp, cPtr, widRec, flag)
63
    Tcl_Interp *interp;
64
    TixClassRecord *cPtr;
65
    char *widRec;
66
    char *flag;
67
{
68
    TixConfigSpec * spec;
69
    char * list;
70
 
71
    spec = Tix_FindConfigSpecByName(interp, cPtr, flag);
72
    if (spec != NULL) {
73
        list = FormatConfigInfo(interp, cPtr, widRec, spec);
74
        Tcl_SetResult(interp, list, TCL_VOLATILE);
75
 
76
        ckfree(list);
77
        return TCL_OK;
78
    }
79
    else {
80
        return TCL_ERROR;
81
    }
82
}
83
 
84
/*
85
 * Tix_QueryAllOptions --
86
 *
87
 *      Note: This function does not call Tix_FindConfigSpec() because
88
 * it just needs to print out the list of all configSpecs from the
89
 * class structure.
90
 *
91
 */
92
int
93
Tix_QueryAllOptions (interp, cPtr, widRec)
94
    Tcl_Interp *interp;
95
    TixClassRecord * cPtr;
96
    char *widRec;
97
{
98
    int         i, code = TCL_OK;
99
    char      * list;
100
    char      * lead = "{";
101
 
102
    /* Iterate over all the options of class */
103
    for (i=0; i<cPtr->nSpecs; i++) {
104
        if (cPtr->specs[i] && cPtr->specs[i]->argvName) {
105
            list = FormatConfigInfo(interp, cPtr, widRec, cPtr->specs[i]);
106
            Tcl_AppendResult(interp, lead, list, "}", (char *) NULL);
107
 
108
            ckfree(list);
109
            lead = " {";
110
        }
111
    }
112
 
113
    return code;
114
}
115
 
116
TixConfigSpec *
117
Tix_FindConfigSpecByName(interp, cPtr, flag)
118
    Tcl_Interp * interp;
119
    TixClassRecord * cPtr;
120
    char * flag;
121
{
122
    char * classRec;
123
    char * key;
124
    int nMatch, i;
125
    size_t len;
126
    Tcl_HashEntry *hashPtr;
127
    TixConfigSpec *configSpec;
128
 
129
    classRec = cPtr->className;
130
 
131
    /*
132
     * First try to look up the confifspec in a hash table,
133
     * it should be faster.
134
     */
135
 
136
    key = Tix_GetConfigSpecFullName(classRec, flag);
137
    hashPtr = Tcl_FindHashEntry(_TixGetHashTable(interp, "tixSpecTab", NULL),
138
            key);
139
    ckfree(key);
140
 
141
    if (hashPtr) {
142
        return (TixConfigSpec *) Tcl_GetHashValue(hashPtr);
143
    }
144
 
145
    /*
146
     * The user may specified a partial name. Try to match, but will
147
     * return error if we don't get exactly one match.
148
     */
149
    len = strlen(flag);
150
    for (configSpec=NULL,nMatch=0,i=0; i<cPtr->nSpecs; i++) {
151
        if (strncmp(flag, cPtr->specs[i]->argvName, len) == 0) {
152
            if (nMatch > 0) {
153
                Tcl_ResetResult(interp);
154
                Tcl_AppendResult(interp, "ambiguous option \"", flag, "\"",
155
                    (char*)NULL);
156
                return NULL;
157
            } else {
158
                nMatch ++;
159
                configSpec = cPtr->specs[i];
160
            }
161
        }
162
    }
163
 
164
    if (configSpec == NULL) {
165
        Tcl_ResetResult(interp);
166
        Tcl_AppendResult(interp, "unknown option \"", flag, "\"", (char*)NULL);
167
        return NULL;
168
    } else {
169
        return configSpec;
170
    }
171
}
172
 
173
char * Tix_GetConfigSpecFullName(classRec, flag)
174
    char * classRec;
175
    char * flag;
176
{
177
    char * buff;
178
    int    max;
179
    int    conLen;
180
 
181
    conLen = strlen(classRec);
182
    max = conLen + strlen(flag) + 1;
183
    buff = (char*)ckalloc(max * sizeof(char));
184
 
185
    strcpy(buff, classRec);
186
    strcpy(buff+conLen, flag);
187
 
188
    return buff;
189
}
190
 
191
int Tix_ChangeOptions(interp, cPtr, widRec, argc, argv)
192
    Tcl_Interp *interp;
193
    TixClassRecord *cPtr;
194
    char * widRec;
195
    int argc;
196
    char ** argv;
197
{
198
    int i, code = TCL_OK;
199
    TixConfigSpec * spec;
200
 
201
    if (argc == 0) {
202
        goto done;
203
    }
204
 
205
    if ((argc %2) != 0) {
206
        if (Tix_FindConfigSpecByName(interp, cPtr, argv[argc-1])) {
207
            Tcl_AppendResult(interp, "value for \"", argv[argc-1],
208
                "\" missing", (char*)NULL);
209
        } else {
210
            /* The error message is already appended by
211
             * Tix_FindConfigSpecByName()
212
             */
213
        }
214
        code = TCL_ERROR;
215
        goto done;
216
    }
217
 
218
    for (i=0; i<argc; i+=2) {
219
        spec = Tix_FindConfigSpecByName(interp, cPtr, argv[i]);
220
 
221
        if (spec == NULL) {
222
            code = TCL_ERROR;
223
            goto done;
224
        }
225
        if (Tix_ChangeOneOption(interp, cPtr, widRec, spec,
226
                argv[i+1], 0, 0)!=TCL_OK) {
227
            code = TCL_ERROR;
228
            goto done;
229
        }
230
    }
231
 
232
  done:
233
    return code;
234
}
235
 
236
int Tix_CallConfigMethod(interp, cPtr, widRec, spec, value)
237
    Tcl_Interp *interp;
238
    TixClassRecord *cPtr;
239
    char * widRec;
240
    TixConfigSpec *spec;
241
    char * value;
242
{
243
    char * argv[2];
244
    char method[200];
245
    char * context = Tix_GetContext(interp, widRec);
246
    char * c;
247
 
248
    sprintf(method, "config%s", spec->argvName);
249
 
250
    c = Tix_FindMethod(interp, context, method);
251
    if (c != NULL) {
252
        argv[0] = value;
253
        return Tix_CallMethod(interp, c, widRec, method, 1, argv);
254
    }
255
 
256
    c = Tix_FindMethod(interp, context, "config");
257
    if (c != NULL) {
258
        argv[0] = spec->argvName;
259
        argv[1] = value;
260
        return Tix_CallMethod(interp, c, widRec, "config", 2, argv);
261
    }
262
 
263
    return TCL_OK;
264
}
265
 
266
int Tix_ChangeOneOption(interp, cPtr, widRec, spec, value, isDefault, isInit)
267
    Tcl_Interp *interp;
268
    TixClassRecord *cPtr;
269
    char * widRec;
270
    TixConfigSpec *spec;
271
    char * value;
272
    int isDefault;              /* Set to be true when Tix tries to set
273
                                 * the options according to their default
274
                                 * values */
275
    int isInit;                 /* Set to true only if the option was
276
                                 * specified at the widget creation command
277
                                 */
278
{
279
    int code = TCL_OK;
280
    char * newValue = NULL;
281
 
282
    if (spec->isAlias) {
283
        spec = spec->realPtr;
284
    }
285
 
286
    /* -- STEP 1 --
287
     * Check if these variables are protected.
288
     *  readonly means the variable can never be assigned to.
289
     *  static means ths variable can only ne assigned during initialization.
290
     */
291
 
292
    if (!isDefault && spec->readOnly) {
293
        Tcl_AppendResult(interp, "cannot assigned to readonly variable \"",
294
                spec->argvName, "\"", (char*) NULL);
295
        code = TCL_ERROR;
296
        goto done;
297
    }
298
    if (!(isInit || isDefault) && spec->isStatic) {
299
        Tcl_AppendResult(interp, "cannot assigned to static variable \"",
300
                spec->argvName, "\"", (char*) NULL);
301
        code = TCL_ERROR;
302
        goto done;
303
    }
304
 
305
    /* -- STEP 2 --
306
     * Call the verify command to check whether the value is acceptable
307
     *
308
     */
309
    if (spec->verifyCmd != NULL) {
310
        char * cmdArgv[2];
311
        cmdArgv[0] = spec->verifyCmd;
312
        cmdArgv[1] = value;
313
 
314
        if (Tix_EvalArgv(interp, 2, cmdArgv) != TCL_OK) {
315
            code = TCL_ERROR;
316
            goto done;
317
        } else {
318
            newValue = value = tixStrDup(interp->result);
319
        }
320
    }
321
 
322
    /* -- STEP 3 --
323
     * Call the configuration method of the widget. This method may
324
     * override the user-supplied value. The configuration method should
325
     * not be called during initialization.
326
     */
327
    if (isInit || isDefault) {
328
        /* No need to call the configuration method */
329
        Tcl_SetVar2(interp, widRec, spec->argvName, value,TCL_GLOBAL_ONLY);
330
    }
331
    else {
332
        if (Tix_CallConfigMethod(interp, cPtr, widRec, spec, value)!=TCL_OK) {
333
            code = TCL_ERROR;
334
            goto done;
335
        }
336
        /* -- STEP 4 --
337
         * If the configuration method does not override the value, set
338
         * it in the widget record.
339
         *
340
         * If the configuration method has override the value, it will
341
         * return a non-empty string. In this case, it is the configuration
342
         * method's responsibility to set the value in the widget record.
343
         */
344
        if (interp->result && (*interp->result)) {
345
            /* value was overrided. Don't do anything */
346
            Tcl_ResetResult(interp);
347
        } else {
348
            Tcl_SetVar2(interp, widRec, spec->argvName, value,TCL_GLOBAL_ONLY);
349
        }
350
    }
351
 
352
  done:
353
    if (newValue) {
354
        ckfree(newValue);
355
    }
356
    return code;
357
}
358
 
359
static char * FormatConfigInfo(interp, cPtr, widRec, sPtr)
360
    Tcl_Interp *interp;
361
    TixClassRecord *cPtr;
362
    char * widRec;
363
    TixConfigSpec * sPtr;
364
{
365
    char *argv[6];
366
 
367
    if (sPtr->isAlias) {
368
        if (cPtr->isWidget) {
369
            argv[0] = sPtr->argvName;
370
            argv[1] = sPtr->realPtr->dbName;
371
        } else {
372
            argv[0] = sPtr->argvName;
373
            argv[1] = sPtr->realPtr->argvName;
374
        }
375
        return Tcl_Merge(2, argv);
376
    } else {
377
        argv[0] = sPtr->argvName;
378
        argv[1] = sPtr->dbName;
379
        argv[2] = sPtr->dbClass;
380
        argv[3] = sPtr->defValue;
381
        argv[4] = Tcl_GetVar2(interp, widRec, argv[0], TCL_GLOBAL_ONLY);
382
 
383
        return Tcl_Merge(5, argv);
384
    }
385
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.