source: tags/ms_r16q4/SL/GUI_ALIVIEW/AWT_filter.cxx

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