source: tags/initial/WINDOW/AW_nawar.cxx

Last change on this file was 2, checked in by oldcode, 23 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.7 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <arbdb.h>
6#include "aw_root.hxx"
7#include "aw_nawar.hxx"
8#define AWAR_EPS 0.00000001
9
10//#define DUMP_AWAR_CHANGES
11
12AW_var_target::AW_var_target(void* pntr, AW_var_target *nexti){
13    next = nexti;
14    pointer = pntr;
15}
16
17AW_var_callback::AW_var_callback( void (*vc_cb)(AW_root*,AW_CL,AW_CL), AW_CL cd1, AW_CL cd2, AW_var_callback *nexti ) {
18
19    value_changed_cb            = vc_cb;
20    value_changed_cb_cd1                = cd1;
21    value_changed_cb_cd2                = cd2;
22    next                                = nexti;
23}
24
25
26void AW_var_callback::run_callback(AW_root *root) {
27    if (this->next) this->next->run_callback(root);     // callback the whole list
28    if (!this->value_changed_cb) return;
29    this->value_changed_cb(root,this->value_changed_cb_cd1,this->value_changed_cb_cd2);
30}
31
32void AW_var_gbdata_callback_delete_intern(GBDATA *, int *cl) {
33    AW_awar *awar = (AW_awar *)cl;
34    awar->gb_var = 0;
35    awar->update();
36}
37
38extern "C" 
39void AW_var_gbdata_callback(GBDATA *, int *cl, GB_CB_TYPE) {
40    AW_awar *awar = (AW_awar *)cl;
41    awar->update();
42}
43
44extern "C"
45void AW_var_gbdata_callback_delete(GBDATA *gbd, int *cl, GB_CB_TYPE) {
46    AW_var_gbdata_callback_delete_intern(gbd, cl);
47}
48   
49#define AW_MSG_UNMAPPED_AWAR "Sorry (Unmapped AWAR):\n"\
50                "       you cannot write to this field because it is either deleted or\n"\
51                "       unmapped. In the last case you should select a different item and\n"\
52                "       reselect this."
53
54char *AW_awar::read_as_string( void ) {
55    char *rt;
56    if (!gb_var)        return strdup("?????");
57    GB_push_transaction(gb_var);
58    rt = GB_read_as_string( gb_var );
59    GB_pop_transaction(gb_var);
60    return rt;
61}
62
63char *AW_awar::read_string(){
64    if (!gb_var)        return strdup("?????");
65    GB_transaction dummy(gb_var);
66    return GB_read_as_string( gb_var );
67}
68
69void AW_awar::get( char **p_string ) {
70    delete *p_string;
71    *p_string = read_string();
72}
73
74
75long AW_awar::read_int(){
76    if (!gb_var) return 0;
77    GB_transaction dummy(gb_var);
78    return (long)GB_read_int( gb_var );
79}
80
81void AW_awar::get( long *p_int ) {
82    *p_int =  (long)read_int( );
83}
84
85double AW_awar::read_float(){
86    if (!gb_var) return 0.0;
87    GB_transaction dummy(gb_var);
88    return GB_read_float( gb_var );
89}
90
91void AW_awar::get( double *p_double ) {
92    *p_double =  read_float( );
93}
94
95
96void AW_awar::get( float *p_float ) {
97    if (!gb_var){
98        *p_float = 0.0;         return;
99    }
100    *p_float =  read_float( );
101}
102
103
104GB_ERROR AW_awar::write_string(const char *aw_string) {
105    if (!gb_var) return AW_MSG_UNMAPPED_AWAR;
106    GB_push_transaction(gb_var);
107#if defined(DUMP_AWAR_CHANGES)
108    fprintf(stderr, "change awar '%s' write_string(%s)\n", awar_name, aw_string);
109#endif // DUMP_AWAR_CHANGES
110    if ( GB_write_string( gb_var, aw_string ) ) {
111        GB_pop_transaction(gb_var);
112        return GB_get_error();
113    }
114    GB_pop_transaction(gb_var);
115    return 0;
116}
117
118GB_ERROR AW_awar::write_as_string(const char *aw_value) {
119    if (!gb_var) return AW_MSG_UNMAPPED_AWAR;
120    GB_transaction dummy(gb_var);
121#if defined(DUMP_AWAR_CHANGES)
122    fprintf(stderr, "change awar '%s' write_as_string(%s)\n", awar_name, aw_value);
123#endif // DUMP_AWAR_CHANGES
124    if ( GB_write_as_string( gb_var, aw_value ) ) {
125        return GB_get_error();
126    }
127    return 0;
128}
129
130
131GB_ERROR AW_awar::write_int( long aw_int ) {
132    if (!gb_var) return AW_MSG_UNMAPPED_AWAR;
133    GB_transaction dummy(gb_var);
134#if defined(DUMP_AWAR_CHANGES)
135    fprintf(stderr, "change awar '%s' write_int(%li)\n", awar_name, aw_int);
136#endif // DUMP_AWAR_CHANGES
137    if ( GB_write_int( gb_var, aw_int ) ) {
138        return GB_get_error();
139    }
140    return 0;
141}
142
143
144GB_ERROR AW_awar::write_float( double aw_double ) {
145    if (!gb_var) return AW_MSG_UNMAPPED_AWAR;
146    GB_transaction dummy(gb_var);
147#if defined(DUMP_AWAR_CHANGES)
148    fprintf(stderr, "change awar '%s' write_float(%f)\n", awar_name, aw_double);
149#endif // DUMP_AWAR_CHANGES
150    if ( GB_write_float( gb_var, aw_double ) ) {
151        return GB_get_error();
152    }
153    return 0;
154}
155
156void AW_awar::touch( void ) {
157    if (!gb_var) {
158        return;
159    }
160    GB_transaction dummy(gb_var);
161    GB_touch( gb_var );
162}
163
164AW_default aw_main_root_default = (AW_default) "this is a dummy text asfasf asfd";
165
166AW_default aw_check_default_file(AW_default root_default, AW_default default_file,const char *varname)
167{
168    if (default_file == aw_main_root_default)  return root_default;
169    if (default_file == NULL) {
170        AW_ERROR("Creating variable '%s' with zero default file\n",varname);
171        return root_default;
172    }
173    return default_file;
174}
175
176
177// for string
178AW_awar *AW_root::awar_string( const char *var_name, const char *default_value, AW_default default_file ) {
179    AW_awar *vs;
180    vs = (AW_awar *)GBS_read_hash(hash_table_for_variables, (char *)var_name);
181    if (vs) return vs;  /* already defined */
182    default_file = aw_check_default_file(this->application_database,default_file,var_name);
183
184    vs = new AW_awar( AW_STRING, var_name, default_value, 0, default_file, this );
185    GBS_write_hash( hash_table_for_variables, (char *)var_name, (long)vs );
186    return vs;
187}
188
189
190// for int
191AW_awar *AW_root::awar_int( const char *var_name, long default_value, AW_default default_file ) {
192    AW_awar *vs;
193    vs = (AW_awar *)GBS_read_hash(hash_table_for_variables, (char *)var_name);
194    if (vs) return vs;  /* already defined */
195    default_file = aw_check_default_file(this->application_database,default_file,var_name);
196
197    vs = new AW_awar( AW_INT, var_name, (char *)default_value, 0, default_file, this );
198    GBS_write_hash( hash_table_for_variables, (char *)var_name, (long)vs );
199    return vs;
200}
201
202
203// for float
204AW_awar *AW_root::awar_float( const char *var_name, float default_value, AW_default default_file ) {
205    AW_awar *vs;
206    vs = (AW_awar *)GBS_read_hash(hash_table_for_variables, (char *)var_name);
207    if (vs) return vs;  /* already defined */
208    default_file = aw_check_default_file(this->application_database,default_file,var_name);
209
210    vs = new AW_awar( AW_FLOAT, var_name, "", (double)default_value, default_file, this );
211    GBS_write_hash( hash_table_for_variables, (char *)var_name, (long)vs );
212    return vs;
213}
214
215AW_awar *AW_root::awar_no_error( const char *var_name){
216    AW_awar *vs = (AW_awar *)GBS_read_hash(hash_table_for_variables, (char *)var_name);
217    return vs;
218}
219
220AW_awar *AW_root::awar( const char *var_name){
221    AW_awar *vs = (AW_awar *)GBS_read_hash(hash_table_for_variables, (char *)var_name);
222    if (vs) return vs;  /* already defined */
223    AW_ERROR("AWAR %s not defined",var_name);
224    return this->awar_string(var_name);
225}
226
227
228AW_awar *AW_awar::add_callback( void (*f)(class AW_root*,AW_CL,AW_CL), AW_CL cd1, AW_CL cd2 ) {
229    callback_list = new AW_var_callback(f,cd1,cd2,callback_list);
230    return this;
231}
232
233AW_awar *AW_awar::add_callback( void (*f)(AW_root*,AW_CL), AW_CL cd1 ) {
234    add_callback((AW_RCB)f,cd1,0);
235    return this;
236}
237
238AW_awar *AW_awar::add_callback( void (*f)(AW_root*)){
239    add_callback((AW_RCB)f,0,0);
240    return this;
241}
242
243AW_awar *AW_awar::remove_callback( void (*f)(AW_root*,AW_CL,AW_CL), AW_CL cd1, AW_CL cd2 ){
244    // remove a callback, please set unused AW_CL to (AW_CL)0
245    AW_var_callback *prev = 0;
246    AW_var_callback *vc;
247    for (vc = callback_list; vc; vc = vc->next){
248        if (vc->value_changed_cb== f &&
249            vc->value_changed_cb_cd1 == cd1 &&
250            vc->value_changed_cb_cd2 == cd2){
251            if (prev) {
252                prev->next = vc->next;
253            }else{
254                callback_list = vc->next;
255            }
256            delete vc;
257            break;
258        }
259        prev = vc;
260    }
261    return this;
262}
263
264GB_ERROR        AW_awar::toggle_toggle(){
265    char *var = this->read_as_string();
266    GB_ERROR    error =0;
267    if (var[0] == '0' || var[0] == 'n') {
268        switch (this->variable_type) {
269            case AW_STRING:     error = this->write_string("yes");break;
270            case AW_INT:        error = this->write_int(1);break;
271            case AW_FLOAT:      error = this->write_float(1.0);break;
272            default: break;
273        }
274    }else{
275        switch (this->variable_type) {
276            case AW_STRING:     error = this->write_string("no");break;
277            case AW_INT:        error = this->write_int(0);break;
278            case AW_FLOAT:      error = this->write_float(0.0);break;
279            default: break;
280        }
281    }
282    delete var;
283    return error;
284}
285
286
287
288AW_awar *AW_awar::set_minmax(float min, float max){
289    if (min>max || variable_type == AW_STRING) {
290        AW_ERROR("ERROR: set MINMAX for AWAR '%s' invalid",awar_name);
291    }else{
292        pp.f.min = min;
293        pp.f.max = max;
294    }
295    return this;
296}
297
298
299AW_awar *AW_awar::add_target_var( char **ppchr){
300    if (variable_type != AW_STRING) {
301        AW_ERROR("Cannot set target awar '%s', WRONG AWAR TYPE",awar_name);
302    }else{
303        target_list = new AW_var_target((void *)ppchr,target_list);
304        update_target(target_list);
305    }
306    return this;
307}
308
309AW_awar *AW_awar::add_target_var( float *pfloat){
310    if (variable_type != AW_FLOAT) {
311        AW_ERROR("Cannot set target awar '%s', WRONG AWAR TYPE",awar_name);
312    }else{
313        target_list = new AW_var_target((void *)pfloat,target_list);
314        update_target(target_list);
315    }
316    return this;
317}
318
319AW_awar *AW_awar::add_target_var( long *pint){
320    if (variable_type != AW_INT) {
321        AW_ERROR("Cannot set target awar '%s', WRONG AWAR TYPE",awar_name);
322    }else{
323        target_list = new AW_var_target((void *)pint,target_list);
324        update_target(target_list);
325    }
326    return this;
327}
328
329
330AW_awar *AW_awar::set_srt(const char *srt)
331{
332    if (variable_type != AW_STRING) {
333        AW_ERROR("ERROR: set SRT for AWAR '%s' invalid",awar_name);
334    }else{
335        pp.srt = srt;
336    }
337    return this;
338}
339
340
341AW_awar *AW_awar::map( AW_default gbd) {
342    if (gbd) GB_push_transaction((GBDATA *)gbd);
343    if (gb_var) {               /* old map */
344        GB_remove_callback((GBDATA *)gb_var, GB_CB_CHANGED, (GB_CB)AW_var_gbdata_callback, (int *)this);
345        GB_remove_callback((GBDATA *)gb_var, GB_CB_DELETE, (GB_CB)AW_var_gbdata_callback_delete, (int *)this);
346    }
347    if (gbd){
348        GB_add_callback((GBDATA *) gbd, GB_CB_CHANGED, (GB_CB)AW_var_gbdata_callback, (int *)this );
349        GB_add_callback((GBDATA *) gbd, GB_CB_DELETE, (GB_CB)AW_var_gbdata_callback_delete, (int *)this );
350    }
351    gb_var      = (GBDATA *)gbd;
352    this->update();
353    if (gbd) GB_pop_transaction((GBDATA *)gbd);
354    return this;
355}
356
357AW_awar *AW_awar::map( AW_awar *dest) {
358    return this->map(dest->gb_var);
359}
360
361AW_awar *AW_awar::unmap( ) {
362    return this->map(gb_origin);
363}
364
365AW_VARIABLE_TYPE AW_awar::get_type(){
366    return this->variable_type;
367}
368
369void AW_awar::update(void)
370{
371    AW_BOOL out_of_range = AW_FALSE;
372    if (gb_var && ((pp.f.min != pp.f.max) || pp.srt) ) {
373        float fl;
374        char *str;
375        switch (variable_type) {
376            case AW_INT:{
377                long lo;
378
379                lo = this->read_int();
380                if (lo < pp.f.min -.5) {
381                    out_of_range = AW_TRUE;
382                    lo = (int)(pp.f.min + 0.5);
383                }
384                if (lo>pp.f.max + .5) {
385                    out_of_range = AW_TRUE;
386                    lo = (int)(pp.f.max + 0.5);
387                }
388                if (out_of_range) {
389                    if (root) root->changer_of_variable = 0;
390                    this->write_int(lo);
391                    return;             // returns update !!!!
392                }
393                break;
394            }
395            case AW_FLOAT:
396                fl = this->read_float();
397                if (fl < pp.f.min) {
398                    out_of_range = AW_TRUE;
399                    fl = pp.f.min+AWAR_EPS;
400                }
401                if (fl>pp.f.max) {
402                    out_of_range = AW_TRUE;
403                    fl = pp.f.max-AWAR_EPS;
404                }
405                if (out_of_range) {
406                    if (root) root->changer_of_variable = 0;
407                    this->write_float(fl);              // returns update !!!!
408                    return;
409                }
410                break;
411
412            case AW_STRING:
413                str = this->read_string();
414                char *n;
415                n = GBS_string_eval(str,pp.srt,0);
416                if (!n) AW_ERROR("SRT ERROR %s %s",pp.srt,GB_get_error());
417                else{
418                    if (strcmp(n,str)) {
419                        this->write_string(n);
420                        delete n;
421                        delete str;
422                        return;
423                    }
424                    delete n;
425                }
426                delete str;
427                break;
428            default:
429                break;
430        }
431    }
432    this->update_targets();
433    this->run_callbacks();
434}
435
436void AW_awar::run_callbacks(){
437    if (callback_list) callback_list->run_callback(root);
438
439}
440
441// send data to all variables
442void AW_awar::update_target(AW_var_target*pntr){
443    if (!pntr->pointer) return;
444    switch(variable_type) {
445        case AW_STRING:
446            this->get((char **)pntr->pointer);break;
447        case AW_FLOAT:
448            this->get((double *)pntr->pointer);break;
449        case AW_INT:
450            this->get((long *)pntr->pointer);break;
451        default:
452            GB_warning("Unknown awar type");
453    }
454}
455
456// send data to all variables
457void AW_awar::update_targets(void){
458    AW_var_target*pntr;
459    for (pntr = target_list; pntr; pntr = pntr->next){
460        update_target(pntr);
461    }
462}
463
464AW_awar::AW_awar(AW_VARIABLE_TYPE var_type, const char *var_name, const char *var_value, double var_double_value, AW_default default_file, AW_root *rooti){
465    memset((char *)this,0,sizeof(AW_awar));
466    GB_transaction dummy((GBDATA *)default_file);
467    this->awar_name = strdup(var_name);
468    this->root = rooti;
469    GBDATA *gb_def = GB_search((GBDATA *)default_file, var_name,GB_FIND);
470    if ( gb_def ) {                                                  // belege Variable mit Datenbankwert
471        AW_VARIABLE_TYPE gbtype;
472        gbtype = (AW_VARIABLE_TYPE) GB_read_type( gb_def );
473        if ( gbtype != var_type ) {
474            GB_warning("Wrong Awar type %s\n",var_name);
475            GB_delete( gb_def );
476            gb_def = 0;
477        }
478    }
479    if (!gb_def) {             // belege Variable mit Programmwert
480        gb_def = GB_search( (GBDATA *)default_file, var_name, (GB_TYPES)var_type);
481
482        switch ( var_type ) {
483            case AW_STRING:
484#if defined(DUMP_AWAR_CHANGES)
485                fprintf(stderr, "creating awar_string '%s' with default value '%s'\n", var_name, (char*)var_value);
486#endif // DUMP_AWAR_CHANGES
487                GB_write_string( gb_def, (char *)var_value );
488                break;
489            case AW_INT:
490#if defined(DUMP_AWAR_CHANGES)
491                fprintf(stderr, "creating awar_int '%s' with default value '%li'\n", var_name, (long)var_value);
492#endif // DUMP_AWAR_CHANGES
493                GB_write_int( gb_def, (long)var_value );
494                break;
495            case AW_FLOAT:
496#if defined(DUMP_AWAR_CHANGES)
497                fprintf(stderr, "creating awar_float '%s' with default value '%f'\n", var_name, (double)var_double_value);
498#endif // DUMP_AWAR_CHANGES
499                GB_write_float( gb_def, (double)var_double_value );
500                break;
501            default:
502                GB_warning("AWAR '%s' cannot be created because of inallowed type",var_name);
503                break;
504        }
505    }
506    variable_type               = var_type;
507    this->gb_origin = gb_def;
508    this->map(gb_def);
509}
510
511
512
513AW_default AW_root::open_default(const char *default_name)
514{
515    GBDATA *gb_default;
516    gb_default = GB_open(default_name,"rwcD");
517    if (gb_default) GB_no_transaction(gb_default);
518    else GB_print_error();
519    return (AW_default) gb_default;
520}
521
522
523AW_error *AW_root::save_default( const char *var_name ) {
524    AW_awar *vs;
525    if ( (vs = this->awar( var_name ))  ) {
526        AW_root::save_default((AW_default)vs->gb_var,NULL);
527        return 0;
528    }else {
529        AW_ERROR("AW_root::save_default: Variable %s not defined", var_name);
530    }
531    return 0;
532}
533
534
535AW_error *AW_root::save_default(AW_default aw_default,const char *file_name)
536{
537    GBDATA *gb_tmp;
538    GBDATA *gb_main = GB_get_root((GBDATA *)aw_default);
539    GB_push_transaction(gb_main);
540    gb_tmp = GB_find(gb_main,"tmp",0,down_level);
541    if (gb_tmp) GB_set_temporary(gb_tmp);
542    aw_update_awar_window_geometrie(this);
543    GB_pop_transaction(gb_main);
544    GB_save_in_home(gb_main,file_name,"a");
545    return 0;
546}
547
548AW_default AW_root::get_default(const char *varname) {
549    GBDATA      *gbd;
550    AW_awar *vs;
551    if ( (vs = this->awar( varname )) ) {
552        gbd = vs->gb_var;
553        return (AW_default)GB_get_root(gbd);
554    }else {
555        AW_ERROR("AW_root::get_default: Variable %s not defined", varname);
556    }
557    return 0;
558}
559
560AW_default AW_root::get_gbdata( const char *varname) {
561    GBDATA      *gbd;
562    AW_awar *vs;
563    if ( (vs = this->awar( varname )) ) {
564        gbd = vs->gb_var;
565        return (AW_default)gbd;
566    }else {
567        AW_ERROR("AW_root::get_gbdata: Variable %s not defined", varname);
568    }
569    return 0;
570}
Note: See TracBrowser for help on using the repository browser.