source: tags/arb_5.1/MERGE/MG_checkfield.cxx

Last change on this file was 5953, checked in by westram, 15 years ago
  • awt_create_selection_list_on_scand
    • pass label for popup button - currently there are multiple buttons with same remote-command-id in query window, this offers a way to fix it.
    • packed two bool params ('add_all_fields_pseudo_field' and 'include_hidden_fields') into enum 'awt_selected_fields'
  • moved awt_changekey.hxx to (empty) awt_item_sel_list.hxx
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <ctype.h>
5
6#include <arbdb.h>
7#include <arbdbt.h>
8#include <aw_root.hxx>
9#include <aw_device.hxx>
10#include <aw_window.hxx>
11#include <aw_awars.hxx>
12#include <awt.hxx>
13#include <awt_item_sel_list.hxx>
14#include <awt_sel_boxes.hxx>
15
16#include "merge.hxx"
17
18#define AWAR_SOURCE_FIELD "/tmp/merge1/chk/source"
19#define AWAR_DEST_FIELD   "/tmp/merge1/chk/dest"
20#define AWAR_TOUPPER      "/tmp/merge1/chk/ToUpper"
21#define AWAR_EXCLUDE      "/tmp/merge1/chk/exclude"
22#define AWAR_CORRECT      "/tmp/merge1/chk/correct"
23#define AWAR_ETAG         "/tmp/merge1/chk/tag"
24
25
26int gbs_cmp_strings(char *str1,char *str2, int *tab){   /* returns 0 if strings are equal */
27    char *s1,*s2;
28    int c1,c2;
29    s1 = str1;
30    s2 = str2;
31    int count = 10;
32    do {
33        do { c1= *(s1++); } while (tab[c1] < 0);
34        do { c2= *(s2++); } while (tab[c2] < 0);
35        if (tab[c1] != tab[c2]) {   /* difference found */
36            return 1;
37        }
38        count --;
39    } while (count && c1 && c2);
40    return 0;
41}
42
43
44char *GBS_diff_strings(char *str1,char * &str2, char *exclude , long ToUpper, long correct,
45                       char **res1, char **res2, long *corrrected){
46
47    char  buffer1[256];
48    char  buffer2[256];
49    char *dest1 = buffer1;
50    char *dest2 = buffer2;
51    char *s1,*s2;
52    int   c1,c2;
53    int   count = 3;
54    int   tab[256];
55    int   i;
56
57    s1 = str1;
58    s2 = str2;
59    *dest1 = 0;
60    *dest2 = 0;
61    tab[0] = 0;
62    char gapchar = '#';
63    if (strlen(exclude)) gapchar = exclude[0];
64    else    exclude = 0;
65
66    for (i=1;i<256;i++) {
67        tab[i] = i;
68        if (exclude && strchr(exclude,i)) {
69            tab[i] = -1;
70            continue;
71        }
72        if (ToUpper && i>= 'a' && i<= 'z' ){
73            tab[i] = i-'a'+'A';
74        }
75    }
76
77    do {
78        do { c1= *(s1++); } while (tab[c1] < 0);
79        do { c2= *(s2++); } while (tab[c2] < 0);
80        if (tab[c1] != tab[c2]) {   /* difference found */
81            if (correct) {
82                /* check subsitution */
83                {
84                    int c = s2[-1];
85                    s2[-1] = s1[-1];
86                    if (toupper(c1) == toupper(c2) ||
87                        !gbs_cmp_strings(s1,s2,&tab[0]) ){
88                        *corrrected = 1;
89                        continue;
90                    }
91                    s2[-1] = c;
92                }
93
94                /* check insertion in s2 */
95                if (!gbs_cmp_strings(s1-1,s2,&tab[0]) ){
96                    s2[-1] = gapchar;
97                    do { c2= *(s2++); } while (tab[c2] < 0); /* eat s2 */
98                    *corrrected = 1;
99                    continue;
100                }
101                /* check deletion in s2 */
102                if ( !gbs_cmp_strings(s1,s2-1,&tab[0]) ){
103                    int toins = c1;
104                    char *toinspos = s2-1;
105                    if (toinspos > str2) toinspos--;
106                    if (tab[(unsigned char)toinspos[0]]> 0) { /* real insertion */
107                        GBS_strstruct *str = GBS_stropen(strlen(str2+10));
108                        int pos = s2-str2-1;
109                        GBS_strncat(str,str2,pos);
110                        GBS_chrcat(str,toins);
111                        GBS_strcat(str,str2+pos);
112                        delete str2;
113                        str2 = GBS_strclose(str);
114                        s2 = str2+pos+1;
115                        *corrrected = 1;
116                        continue;
117                    }
118                    int side=1; /* 0 = left   1= right */
119                    if ( tab[(unsigned char)s1[0]]<0 ) side = 0;
120                    if ( ! side ) {
121                        while ( toinspos > str2 &&
122                                tab[(unsigned char)toinspos[-1]] < 0 ) toinspos--;
123                    }
124                    toinspos[0] = toins;
125                    *corrrected = 1;
126                    do { c1= *(s1++); } while (tab[c1] < 0); /* eat s1 */
127                    continue;
128                }
129            }
130            if (count >=0){
131                sprintf(dest1,"%ti ",s1-str1-1);
132                sprintf(dest2,"%ti ",s2-str2-1);
133                dest1 += strlen(dest1);
134                dest2 += strlen(dest2);
135            }
136            count --;
137        }
138    } while (c1 && c2);
139
140    if (c1 || c2) {
141        sprintf(dest1,"... %ti ",s1-str1-1);
142        sprintf(dest2,"... %ti ",s2-str2-1);
143        dest1 += strlen(dest1);
144        dest2 += strlen(dest2);
145    }
146    if (count<0){
147        sprintf(dest1,"and %i more",1-count);
148        sprintf(dest2,"and %i more",1-count);
149        dest1 += strlen(dest1);
150        dest2 += strlen(dest2);
151    }
152    if (strlen(buffer1) ) {
153        *res1 = strdup(buffer1);
154        *res2 = strdup(buffer2);
155    }else{
156        *res1 = 0;
157        *res2 = 0;
158    }
159    return 0;
160}
161
162#undef IS_QUERIED
163#define IS_QUERIED(gb_species) (1 & GB_read_usr_private(gb_species))
164
165void mg_check_field_cb(AW_window *aww){
166    AW_root  *root    = aww->get_root();
167    GB_ERROR  error   = 0;
168    char     *source  = root->awar(AWAR_SOURCE_FIELD)->read_string();
169    char     *dest    = root->awar(AWAR_DEST_FIELD)->read_string();
170    char     *exclude = root->awar(AWAR_EXCLUDE)->read_string();
171    long      ToUpper = root->awar(AWAR_TOUPPER)->read_int();
172    long      correct = root->awar(AWAR_CORRECT)->read_int();
173    char     *tag     = root->awar(AWAR_ETAG)->read_string();
174
175    if (source[0] == 0) {
176        error = "Please select a source field";
177    }
178    else if (dest[0] == 0) {
179        error = "Please select a dest field";
180    }
181    else {
182        aw_openstatus("Checking fields");
183        error = GB_begin_transaction(GLOBAL_gb_merge);
184       
185        if (!error) {
186            error = GB_begin_transaction(GLOBAL_gb_dest);
187
188            GBDATA *gb_species_data1 = GB_search(GLOBAL_gb_merge, "species_data", GB_CREATE_CONTAINER);
189            GBDATA *gb_species_data2 = GB_search(GLOBAL_gb_dest,  "species_data", GB_CREATE_CONTAINER);
190
191            GBDATA *gb_species1;
192            GBDATA *gb_species2;
193           
194            int     sum_species   = 0;
195            int     species_count = 0;
196           
197            // First step: count selected species
198            for (gb_species1 = GBT_first_species_rel_species_data(gb_species_data1);
199                 gb_species1 && !error;
200                 gb_species1 = GBT_next_species(gb_species1))
201            {
202                if (IS_QUERIED(gb_species1)) sum_species++;
203            }
204
205            // Delete all 'dest' fields in gb_database 2
206            for (gb_species2 = GBT_first_species_rel_species_data(gb_species_data2);
207                 gb_species2 && !error;
208                 gb_species2 = GBT_next_species(gb_species2))
209            {
210                GBDATA *gbd    = GB_search(gb_species2,dest,GB_FIND);
211                if (gbd) error = GB_delete(gbd);
212            }
213
214            for (gb_species1 = GBT_first_species_rel_species_data(gb_species_data1);
215                 gb_species1 && !error;
216                 gb_species1 = GBT_next_species(gb_species1))
217            {
218                {
219                    GBDATA *gbd    = GB_search(gb_species1,dest,GB_FIND);
220                    if (gbd) error = GB_delete(gbd);
221                }
222
223                if (!error) {
224                    if (IS_QUERIED(gb_species1)) {
225                        species_count++;
226                        if ((species_count & 0xf) == 0) aw_status(species_count/ (double)sum_species);
227
228                        const char *name1 = GBT_read_name(gb_species1);
229                        gb_species2       = GB_find_string(gb_species_data2, "name", name1, GB_IGNORE_CASE, down_2_level);
230                        if (!gb_species2) {
231                            aw_message(GBS_global_string("WARNING: Species %s not found in DB II", name1));
232                        }
233                        else {
234                            gb_species2 = GB_get_father(gb_species2);
235
236                            GBDATA *gb_field1 = GB_search(gb_species1,source,GB_FIND);
237                            GBDATA *gb_field2 = GB_search(gb_species2,source,GB_FIND);
238                            char   *s1        = gb_field1 ? GB_read_as_tagged_string(gb_field1, tag) : 0;
239                            char   *s2        = gb_field2 ? GB_read_as_tagged_string(gb_field2, tag) : 0;
240
241                            if (s1 || s2) {
242                                char *positions1 = 0;
243                                char *positions2 = 0;
244                               
245                                if (s1 && s2) {
246                                    long corrected = 0;
247                                    GBS_diff_strings(s1,s2,exclude,ToUpper,correct,&positions1,&positions2,&corrected);
248                                    if (corrected) {
249                                        error             = GB_write_as_string(gb_field2,s2);
250                                        if (!error) error = GB_write_flag(gb_species2,1);
251                                    }
252                                }
253                                else {
254                                    positions1 = GBS_global_string_copy("field missing in %s DB", s1 ? "other" : "this");
255                                    positions2 = GBS_global_string_copy("field missing in %s DB", s2 ? "other" : "this");
256                                }
257
258                                if (positions1 && !error) {
259                                    error             = GBT_write_string(gb_species2, dest, positions2);
260                                    if (!error) error = GBT_write_string(gb_species1, dest, positions1);
261                                }
262
263                                free(positions2);
264                                free(positions1);
265                            }
266
267                            free(s2);
268                            free(s1);
269                        }
270                    }
271                }
272            }
273
274            aw_closestatus();
275            error = GB_end_transaction(GLOBAL_gb_merge, error);
276            error = GB_end_transaction(GLOBAL_gb_dest, error);
277        }
278    }
279    if (error) aw_message(error);
280
281    free(tag);
282    free(exclude);
283    free(dest);
284    free(source);
285}
286
287
288AW_window *create_mg_check_fields(AW_root *aw_root){
289    AW_window_simple *aws = 0;
290
291    aw_root->awar_string(AWAR_SOURCE_FIELD);
292    aw_root->awar_string(AWAR_DEST_FIELD,"tmp",AW_ROOT_DEFAULT);
293    aw_root->awar_string(AWAR_EXCLUDE,".-",AW_ROOT_DEFAULT);
294    aw_root->awar_string(AWAR_ETAG,"");
295    aw_root->awar_int(AWAR_TOUPPER);
296    aw_root->awar_int(AWAR_CORRECT);
297
298    aws = new AW_window_simple;
299    aws->init( aw_root, "MERGE_COMPARE_FIELDS","COMPARE DATABASE FIELDS");
300    aws->load_xfig("merge/seqcheck.fig");
301
302    aws->callback( (AW_CB0)AW_POPDOWN);
303    aws->create_button("CLOSE","CLOSE","C");
304
305    aws->at("help");
306    aws->callback(AW_POPUP_HELP,(AW_CL)"checkfield.hlp");
307    aws->create_button("HELP","HELP","H");
308
309
310    aws->at("exclude");
311    aws->create_input_field(AWAR_EXCLUDE);
312
313    aws->at("toupper");
314    aws->create_toggle(AWAR_TOUPPER);
315
316    aws->at("correct");
317    aws->create_toggle(AWAR_CORRECT);
318
319    aws->at("tag");
320    aws->create_input_field(AWAR_ETAG,6);
321
322    awt_create_selection_list_on_scandb(GLOBAL_gb_dest,aws,AWAR_SOURCE_FIELD,
323                                        AWT_STRING_FILTER, "source",0, &AWT_species_selector, 20, 10);
324
325    awt_create_selection_list_on_scandb(GLOBAL_gb_dest,aws,AWAR_DEST_FIELD,
326                                        (1<<GB_STRING)|(1<<GB_INT), "dest",0, &AWT_species_selector, 20, 10);
327
328#if defined(DEVEL_RALF)
329#warning check code above. Maybe one call has to get GLOBAL_gb_merge ?
330#endif // DEVEL_RALF
331
332
333    aws->at("go");
334    aws->highlight();
335    aws->callback(mg_check_field_cb);
336    aws->create_button("GO","GO");
337
338    return (AW_window *)aws;
339}
Note: See TracBrowser for help on using the repository browser.