source: branches/profile/SL/GUI_ALIVIEW/AWT_filter.cxx

Last change on this file was 12205, checked in by westram, 10 years ago
  • inlined default param for create_option_menu
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.6 KB
Line 
1#include "awt_filter.hxx"
2#include "awt_sel_boxes.hxx"
3#include "ga_local.h"
4
5#include <aw_awars.hxx>
6#include <aw_root.hxx>
7#include <aw_select.hxx>
8#include <AP_filter.hxx>
9#include <arbdbt.h>
10#include <arb_strbuf.h>
11#include <ad_cb.h>
12
13//! recalc filter
14static void awt_create_select_filter_window_aw_cb(UNFIXED, adfiltercbstruct *cbs) {
15    // update the variables
16    AW_root *aw_root = cbs->awr;
17    GB_push_transaction(cbs->gb_main);
18    char *target = aw_root->awar(cbs->def_subname)->read_string();
19    char *to_free_target = target;
20    char *use = aw_root->awar(cbs->def_alignment)->read_string();
21    char *name = strchr(target, 1);
22    GBDATA *gbd = 0;
23    if (name) {
24        *(name++) = 0;
25        target++;
26        GBDATA *gb_species;
27        if (target[-1] == '@') {
28            gb_species = GBT_find_species(cbs->gb_main, name);
29        }
30        else {
31            gb_species = GBT_find_SAI(cbs->gb_main, name);
32        }
33        if (gb_species) {
34            GBDATA *gb_ali = GB_search(gb_species, use, GB_FIND);
35            if (gb_ali) {
36                gbd = GB_search(gb_ali, target, GB_FIND);
37            }
38            else {
39                GB_clear_error();
40            }
41        }
42    }
43    if (!gbd) {     // nothing selected
44        aw_root->awar(cbs->def_name)->write_string("none");
45        aw_root->awar(cbs->def_source)->write_string("No Filter Sequence ->All Columns Selected");
46        aw_root->awar(cbs->def_filter)->write_string("");
47        aw_root->awar(cbs->def_len)   ->write_int(-1);  // export filter
48    }
49    else {
50        GBDATA *gb_name = GB_get_father(gbd);   // ali_xxxx
51        gb_name = GB_brother(gb_name, "name");
52        char *name2 = GB_read_string(gb_name);
53        aw_root->awar(cbs->def_name)->write_string(name2);
54        free(name2);
55        char *_2filter = aw_root->awar(cbs->def_2filter)->read_string();
56        long _2filter_len = strlen(_2filter);
57
58        char *s, *str;
59        long len = GBT_get_alignment_len(cbs->gb_main, use);
60        GBS_strstruct *strstruct = GBS_stropen(5000);
61        long i; for (i=0; i<len; i++) { // build position line
62            if (i%10 == 0) {
63                GBS_chrcat(strstruct, '#');
64            }
65            else if (i%5==0) {
66                GBS_chrcat(strstruct, '|');
67            }
68            else {
69                GBS_chrcat(strstruct, '.');
70            }
71        }
72        GBS_chrcat(strstruct, '\n');
73        char *data = GBS_mempntr(strstruct);
74
75        for (i=0; i<len-10; i++) {  // place markers
76            if (i%10 == 0) {
77                char buffer[256];
78                sprintf(buffer, "%li", i+1);
79                strncpy(data+i+1, buffer, strlen(buffer));
80            }
81        }
82
83        if (GB_read_type(gbd) == GB_STRING) {   // read the filter
84            str = GB_read_string(gbd);
85        }
86        else {
87            str = GB_read_bits(gbd, '-', '+');
88        }
89        GBS_strcat(strstruct, str);
90        GBS_chrcat(strstruct, '\n');
91        char *canc = aw_root->awar(cbs->def_cancel)->read_string();
92        long min = aw_root->awar(cbs->def_min)->read_int()-1;
93        long max = aw_root->awar(cbs->def_max)->read_int()-1;
94        long flen = 0;
95        for (i=0, s=str; *s; ++s, ++i) {    // transform the filter
96            if (strchr(canc, *s) || (i<min) || (max>0 && i > max))
97            {
98                *s = '0';
99            }
100            else {
101                if (i > _2filter_len || _2filter[i] != '0') {
102                    *s = '1';
103                    flen++;
104                }
105                else {
106                    *s = '0';
107                }
108            }
109        }
110        GBS_strcat(strstruct, str);
111        GBS_chrcat(strstruct, '\n');
112        data = GBS_strclose(strstruct);
113        aw_root->awar(cbs->def_len)   ->write_int(flen);    // export filter
114        aw_root->awar(cbs->def_filter)->write_string(str);  // export filter
115        aw_root->awar(cbs->def_source)->write_string(data); // set display
116        free(_2filter);
117        free(str);
118        free(canc);
119        free(data);
120    }
121    free(to_free_target);
122    free(use);
123    GB_pop_transaction(cbs->gb_main);
124}
125
126static void awt_add_sequences_to_list(adfiltercbstruct *cbs, const char *use, GBDATA *gb_extended, const char *pre, char tpre) {
127    GBDATA *gb_ali = GB_entry(gb_extended, use);
128
129    if (gb_ali) {
130        int         count   = 0;
131        GBDATA     *gb_type = GB_entry(gb_ali, "_TYPE");
132        const char *TYPE    = gb_type ? GB_read_char_pntr(gb_type) : "";
133        const char *name    = GBT_read_name(gb_extended);
134        GBDATA     *gb_data;
135
136        for (gb_data = GB_child(gb_ali); gb_data; gb_data = GB_nextChild(gb_data)) {
137            if (GB_read_key_pntr(gb_data)[0] != '_') {
138                long type = GB_read_type(gb_data);
139
140                if (type == GB_BITS || type == GB_STRING) {
141                    char *str;
142
143                    if (count) str = GBS_global_string_copy("%s%-20s SEQ_%i %s", pre, name, count + 1, TYPE);
144                    else str       = GBS_global_string_copy("%s%-20s       %s", pre, name, TYPE);
145
146                    const char *target = GBS_global_string("%c%s%c%s", tpre, GB_read_key_pntr(gb_data), 1, name);
147
148                    cbs->filterlist->insert(str, target);
149                    free(str);
150                    count++;
151                }
152            }
153        }
154    }
155}
156
157static void awt_create_select_filter_window_gb_cb(UNFIXED, adfiltercbstruct *cbs) {
158    // update list widget and variables
159    GB_push_transaction(cbs->gb_main);
160
161    if (cbs->filterlist) {
162        char *use = cbs->awr->awar(cbs->def_alignment)->read_string();
163
164        cbs->filterlist->clear();
165        cbs->filterlist->insert_default("none", "");
166
167        const char *name = GBT_readOrCreate_char_pntr(cbs->gb_main, AWAR_SPECIES_NAME, "");
168        if (name[0]) {
169            GBDATA *gb_species = GBT_find_species(cbs->gb_main, name);
170            if (gb_species) {
171                awt_add_sequences_to_list(cbs, use, gb_species, "SEL. SPECIES:", '@');
172            }
173        }
174
175        for (GBDATA *gb_extended = GBT_first_SAI(cbs->gb_main);
176             gb_extended;
177             gb_extended = GBT_next_SAI(gb_extended))
178        {
179            awt_add_sequences_to_list(cbs, use, gb_extended, "", ' ');
180        }
181
182        cbs->filterlist->update();
183        free(use);
184    }
185    awt_create_select_filter_window_aw_cb(0, cbs);
186    GB_pop_transaction(cbs->gb_main);
187}
188
189
190adfiltercbstruct *awt_create_select_filter(AW_root *aw_root, GBDATA *gb_main, const char *def_name) {
191    /*! Create a data structure for filters (needed for awt_create_select_filter_win)
192     *
193     * @param aw_root application root
194     * @param gb_main DB root node
195     * @param def_name filter name awar (has to exist, name has to be "SOMETHING/name")
196     * awars "SOMETHING/filter" (STRING) and
197     * "SOMETHING/alignment" (STRING) have to exist as well!
198     *
199     */
200
201    adfiltercbstruct *acbs   = new adfiltercbstruct;
202    acbs->gb_main            = gb_main;
203    AW_default        aw_def = AW_ROOT_DEFAULT;
204
205    GB_push_transaction(acbs->gb_main);
206
207#if defined(DEBUG)
208    {
209        int len = strlen(def_name);
210
211        ga_assert(len >= 5);
212        ga_assert(strcmp(def_name+len-5, "/name") == 0); // filter awar has to be "SOMETHING/name"
213    }
214#endif                          // DEBUG
215
216    acbs->def_name      = GBS_string_eval(def_name, "/name=/name", 0);
217    acbs->def_filter    = GBS_string_eval(def_name, "/name=/filter", 0);
218    acbs->def_alignment = GBS_string_eval(def_name, "/name=/alignment", 0);
219
220    acbs->def_min = GBS_string_eval(def_name, "*/name=tmp/*1/min:tmp/tmp=tmp", 0);
221    acbs->def_max = GBS_string_eval(def_name, "*/name=tmp/*1/max:tmp/tmp=tmp", 0);
222    aw_root->awar_int(acbs->def_min)->add_callback(makeRootCallback(awt_create_select_filter_window_aw_cb, acbs));
223    aw_root->awar_int(acbs->def_max)->add_callback(makeRootCallback(awt_create_select_filter_window_aw_cb, acbs));
224
225    acbs->def_len = GBS_string_eval(def_name, "*/name=tmp/*1/len:tmp/tmp=tmp", 0);
226    aw_root->awar_int(acbs->def_len);
227
228    acbs->def_dest = GBS_string_eval(def_name, "*/name=tmp/*1/dest:tmp/tmp=tmp", 0);
229    aw_root->awar_string(acbs->def_dest, "", aw_def);
230
231    acbs->def_cancel = GBS_string_eval(def_name, "*/name=*1/cancel", 0);
232    aw_root->awar_string(acbs->def_cancel, ".0-=", aw_def);
233
234    acbs->def_simplify = GBS_string_eval(def_name, "*/name=*1/simplify", 0);
235    aw_root->awar_int(acbs->def_simplify, 0, aw_def);
236
237    acbs->def_subname = GBS_string_eval(def_name, "*/name=tmp/*1/subname:tmp/tmp=tmp", 0);
238    aw_root->awar_string(acbs->def_subname);
239
240    acbs->def_source = GBS_string_eval(def_name, "*/name=tmp/*/source:tmp/tmp=tmp", 0);
241    aw_root->awar_string(acbs->def_source);
242
243    acbs->def_2name      = GBS_string_eval(def_name, "*/name=tmp/*/2filter/name:tmp/tmp=tmp", 0);
244    acbs->def_2filter    = GBS_string_eval(def_name, "*/name=tmp/*/2filter/filter:tmp/tmp=tmp", 0);
245    acbs->def_2alignment = GBS_string_eval(def_name, "*/name=tmp/*/2filter/alignment:tmp/tmp=tmp", 0);
246
247    aw_root->awar_string(acbs->def_2name)->write_string("- none -");
248    aw_root->awar_string(acbs->def_2filter);
249    aw_root->awar_string(acbs->def_2alignment);
250
251    acbs->filterlist = 0;
252    acbs->aw_filt    = 0;
253    acbs->awr        = aw_root;
254    {
255        char *fname = aw_root->awar(acbs->def_name)->read_string();
256        const char *fsname = GBS_global_string(" data%c%s", 1, fname);
257        free(fname);
258        aw_root->awar(acbs->def_subname)->write_string(fsname);     // cause an callback
259    }
260
261    aw_root->awar(acbs->def_subname)->touch();      // cause an callback
262
263    GBDATA *gb_sai_data = GBT_get_SAI_data(acbs->gb_main);
264    GBDATA *gb_sel      = GB_search(acbs->gb_main, AWAR_SPECIES_NAME, GB_STRING);
265
266    GB_add_callback(gb_sai_data, GB_CB_CHANGED, makeDatabaseCallback(awt_create_select_filter_window_gb_cb, acbs));
267    GB_add_callback(gb_sel,      GB_CB_CHANGED, makeDatabaseCallback(awt_create_select_filter_window_gb_cb, acbs));
268
269    aw_root->awar(acbs->def_alignment)->add_callback(makeRootCallback(awt_create_select_filter_window_gb_cb, acbs));
270    aw_root->awar(acbs->def_2filter)  ->add_callback(makeRootCallback(awt_create_select_filter_window_aw_cb, acbs));
271    aw_root->awar(acbs->def_subname)  ->add_callback(makeRootCallback(awt_create_select_filter_window_aw_cb, acbs));
272
273    awt_create_select_filter_window_gb_cb(0, acbs);
274
275    GB_pop_transaction(acbs->gb_main);
276    return acbs;
277}
278
279
280void awt_set_awar_to_valid_filter_good_for_tree_methods(GBDATA *gb_main, AW_root *awr, const char *awar_name) {
281    GB_transaction transaction_var(gb_main);
282    if (GBT_find_SAI(gb_main, "POS_VAR_BY_PARSIMONY")) {
283        awr->awar(awar_name)->write_string("POS_VAR_BY_PARSIMONY");
284        return;
285    }
286    if (GBT_find_SAI(gb_main, "ECOLI")) {
287        awr->awar(awar_name)->write_string("ECOLI");
288        return;
289    }
290}
291
292static AW_window *awt_create_2_filter_window(AW_root *aw_root, adfiltercbstruct *acbs) {
293    GB_push_transaction(acbs->gb_main);
294    aw_root->awar(acbs->def_2alignment)->map(acbs->def_alignment);
295    adfiltercbstruct *s2filter = awt_create_select_filter(aw_root, acbs->gb_main, acbs->def_2name);
296    GB_pop_transaction(acbs->gb_main);
297    return awt_create_select_filter_win(aw_root, s2filter);
298}
299
300char *AWT_get_combined_filter_name(AW_root *aw_root, GB_CSTR prefix) {
301    char       *combined_name = aw_root->awar(GBS_global_string("%s/filter/name", prefix))->read_string(); // "gde/filter/name"
302    const char *awar_prefix   = AWAR_GDE_FILTER;
303    const char *awar_repeated = "/2filter";
304    const char *awar_postfix  = "/name";
305    int         prefix_len    = strlen(awar_prefix);
306    int         repeated_len  = strlen(awar_repeated);
307    int         postfix_len   = strlen(awar_postfix);
308    int         count;
309
310    for (count = 1; ; ++count) {
311        char *awar_name = new char[prefix_len + count*repeated_len + postfix_len + 1];
312        strcpy(awar_name, awar_prefix);
313        int c;
314        for (c=0; c<count; ++c) strcat(awar_name, awar_repeated);
315        strcat(awar_name, awar_postfix);
316
317        AW_awar *awar_found = aw_root->awar_no_error(awar_name);
318        delete [] awar_name;
319
320        if (!awar_found) break; // no more filters defined
321        char *content = awar_found->read_string();
322
323        if (strstr(content, "none")==0) { // don't add filters named 'none'
324            freeset(combined_name, GBS_global_string_copy("%s/%s", combined_name, content));
325        }
326    }
327
328    return combined_name;
329}
330
331AW_window *awt_create_select_filter_win(AW_root *aw_root, adfiltercbstruct *acbs) {
332    //! Create a filter selection window
333    if (!acbs->aw_filt) {
334        GB_push_transaction(acbs->gb_main);
335
336        AW_window_simple *aws = new AW_window_simple;
337        {
338            int   checksum  = GBS_checksum(acbs->def_name, true, NULL);
339            char *window_id = GBS_global_string_copy("FILTER_SELECT_%i", checksum); // make window id awar specific
340
341            aws->init(aw_root, window_id, "Select Filter");
342            free(window_id);
343        }
344        aws->load_xfig("awt/filter.fig");
345        aws->button_length(10);
346
347        aws->at("close"); aws->callback((AW_CB0)AW_POPDOWN);
348        aws->create_button("CLOSE", "CLOSE", "C");
349
350        aws->at("help"); aws->callback(makeHelpCallback("sel_fil.hlp"));
351        aws->create_button("HELP", "HELP", "H");
352
353        acbs->aw_filt = aws; // store the filter selection window in 'acbs'
354
355        aws->at("filter");
356        acbs->filterlist = aws->create_selection_list(acbs->def_subname, 20, 3, true);
357
358        aws->at("2filter");
359        aws->callback(makeCreateWindowCallback(awt_create_2_filter_window, acbs));
360        aws->create_button(acbs->def_2name, acbs->def_2name);
361
362        aws->at("zero");
363        aws->callback(makeWindowCallback(awt_create_select_filter_window_aw_cb, acbs));
364        aws->create_input_field(acbs->def_cancel, 10);
365
366        aws->at("sequence");
367        aws->create_text_field(acbs->def_source, 1, 1);
368
369        aws->at("min");
370        aws->create_input_field(acbs->def_min, 4);
371
372        aws->at("max");
373        aws->create_input_field(acbs->def_max, 4);
374
375        aws->at("simplify");
376        aws->create_option_menu(acbs->def_simplify, true);
377        aws->insert_option("ORIGINAL DATA", "O", 0);
378        aws->sens_mask(AWM_EXP);
379        aws->insert_option("TRANSVERSIONS ONLY", "T", 1);
380        aws->insert_option("SIMPLIFIED AA", "A", 2);
381        aws->sens_mask(AWM_ALL);
382        aws->update_option_menu();
383
384        awt_create_select_filter_window_gb_cb(0, acbs);
385
386        aws->button_length(7);
387        aws->at("len");    aws->create_button(0, acbs->def_len);
388
389        GB_pop_transaction(acbs->gb_main);
390    }
391
392    return acbs->aw_filt;
393}
394
395AP_filter *awt_get_filter(adfiltercbstruct *acbs) {
396    /*! create a filter from settings made in filter-definition window.
397     *  always returns a filter, use awt_invalid_filter() to check for validity
398     */
399    AP_filter *filter = NULL;
400
401    if (acbs) {
402        GB_push_transaction(acbs->gb_main);
403
404        char *filter_string = acbs->awr->awar(acbs->def_filter)->read_string();
405        long  len           = 0;
406
407        {
408            char *use = acbs->awr->awar(acbs->def_alignment)->read_string();
409
410            len = GBT_get_alignment_len(acbs->gb_main, use);
411            free(use);
412        }
413
414        if (len == -1) { // no alignment -> uses dummy filter
415            GB_clear_error();
416        }
417        else { // have alignment
418            filter  = new AP_filter(filter_string, "0", len);
419            int sim = acbs->awr->awar(acbs->def_simplify)->read_int();
420            filter->enable_simplify((AWT_FILTER_SIMPLIFY)sim);
421            free(filter_string);
422        }
423
424        GB_pop_transaction(acbs->gb_main);
425    }
426
427    if (!filter) filter = new AP_filter(0); // empty dummy filter
428    return filter;
429}
430
431GB_ERROR awt_invalid_filter(AP_filter *filter) {
432    return filter->is_invalid();
433}
434
435void awt_destroy_filter(AP_filter *filter) {
436    delete filter;
437}
Note: See TracBrowser for help on using the repository browser.