source: tags/arb-6.0/ARB_GDE/GDE.cxx

Last change on this file was 12267, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 KB
Line 
1#include "GDE_extglob.h"
2#include "GDE_awars.h"
3
4#include <aw_window.hxx>
5#include <aw_msg.hxx>
6#include <aw_awar.hxx>
7#include <aw_file.hxx>
8#include <aw_root.hxx>
9#include <aw_awar_defs.hxx>
10#include <awt_sel_boxes.hxx>
11#include <awt_filter.hxx>
12
13#include <cmath>
14#include <arb_str.h>
15
16// AISC_MKPT_PROMOTE:#ifndef GDE_MENU_H
17// AISC_MKPT_PROMOTE:#include "GDE_menu.h"
18// AISC_MKPT_PROMOTE:#endif
19
20adfiltercbstruct *agde_filter = 0;
21
22Gmenu         menu[GDEMAXMENU];
23int           num_menus = 0;
24NA_Alignment *DataSet   = NULL;
25
26static char GDEBLANK[] = "\0";
27
28#define SLIDERWIDTH 5           // input field width for numbers
29
30struct gde_iteminfo {
31    GmenuItem *item;
32    int        idx;
33    gde_iteminfo(GmenuItem *item_, int idx_) : item(item_), idx(idx_) {}
34};
35
36static void GDE_showhelp_cb(AW_window *aw, GmenuItem *gmenuitem, AW_CL /* cd */) {
37    if (gmenuitem->help) {
38        AW_help_popup(aw, gmenuitem->help);
39    }
40    else {
41        aw_message("Sorry - no help available (please report to devel@arb-home.de)");
42    }
43}
44
45static char *GDE_makeawarname_in(GmenuItem *gmenuitem, long i, const char *awar_root) {
46    char *gmenu_label     = GBS_string_2_key(gmenuitem->parent_menu->label);
47    char *gmenuitem_label = GBS_string_2_key(gmenuitem->label);
48    char *arg             = GBS_string_2_key(gmenuitem->arg[i].symbol);
49
50    char *name = GBS_global_string_copy("%s/%s/%s/%s", awar_root, gmenu_label, gmenuitem_label, arg);
51
52    free(gmenu_label);
53    free(gmenuitem_label);
54    free(arg);
55
56    return name;
57}
58
59char *GDE_makeawarname(GmenuItem *gmenuitem, long i) { return GDE_makeawarname_in(gmenuitem, i, "gde"); }
60char *GDE_maketmpawarname(GmenuItem *gmenuitem, long i) { return GDE_makeawarname_in(gmenuitem, i, "tmp/gde"); }
61
62static void GDE_slide_awar_int_cb(AW_window *aws, AW_CL cl_awar_name, AW_CL cd_diff)
63{
64    int      diff = (int)cd_diff;
65    AW_awar *awar = aws->get_root()->awar((const char *)cl_awar_name);
66
67    awar->write_int(awar->read_int()+diff);
68}
69static void GDE_slide_awar_float_cb(AW_window *aws, AW_CL cl_awar_name, AW_CL cd_diff)
70{
71    double   diff    = *(double*)(char*)/*avoid aliasing problems*/cd_diff; 
72    AW_awar *awar    = aws->get_root()->awar((const char *)cl_awar_name);
73    double   new_val = awar->read_float()+diff;
74
75    if (fabs(new_val) < 0.0001) new_val = 0.0;
76    awar->write_float(new_val);
77
78    // do it again (otherwise internal awar-range correction sometimes leads to 1+eXX values)
79    new_val = awar->read_float();
80    if (fabs(new_val) < 0.0001) new_val = 0.0;
81    awar->write_float(new_val);
82}
83
84static void GDE_create_infieldwithpm(AW_window *aws, char *newawar, long width) {
85    aws->create_input_field(newawar, (int)width);
86    if (aws->get_root()->awar(newawar)->get_type() == AW_INT) {
87        aws->button_length(3);
88        char *awar = strdup(newawar);
89        aws->callback(GDE_slide_awar_int_cb, (AW_CL)awar, -1); aws->create_button(0, "-", "-");
90        aws->callback(GDE_slide_awar_int_cb, (AW_CL)awar, + 1); aws->create_button(0, "+", "+");
91    }
92    else if (aws->get_root()->awar(newawar)->get_type() == AW_FLOAT) {
93        aws->button_length(3);
94        char *awar = strdup(newawar);
95        aws->callback(GDE_slide_awar_float_cb, (AW_CL)awar, (AW_CL)new double(-0.1)); aws->create_button(0, "-", "-");
96        aws->callback(GDE_slide_awar_float_cb, (AW_CL)awar, (AW_CL)new double(+0.1)); aws->create_button(0, "+", "+");
97    }
98}
99
100static char *gde_filter_weights(GBDATA *gb_sai, AW_CL) {
101    char   *ali_name = GBT_get_default_alignment(GB_get_root(gb_sai));
102    GBDATA *gb_ali   = GB_entry(gb_sai, ali_name);
103    char   *result   = 0;
104
105    if (gb_ali) {
106        GBDATA *gb_type = GB_entry(gb_ali, "_TYPE");
107        if (gb_type) {
108            const char *type = GB_read_char_pntr(gb_type);
109
110            if (GBS_string_matches(type, "PV?:*", GB_MIND_CASE)) {
111                result = GBS_global_string_copy("%s: %s", GBT_read_name(gb_sai), type);
112            }
113
114        }
115    }
116
117    free(ali_name);
118    return result;
119
120}
121
122static AW_window *GDE_create_filename_browser_window(AW_root *aw_root, const char *awar_prefix, const char *title) {
123    AW_window_simple *aws = new AW_window_simple;
124
125    {
126        char *wid = GBS_string_2_key(awar_prefix);
127        aws->init(aw_root, wid, title);
128        free(wid);
129    }
130    aws->load_xfig("sel_box.fig");
131
132    aws->at("close");
133    aws->callback((AW_CB0) AW_POPDOWN);
134    aws->create_button("CLOSE", "CLOSE", "C");
135
136    AW_create_standard_fileselection(aws, awar_prefix);
137
138    return aws;
139}
140
141static void GDE_popup_filename_browser(AW_window *aw, AW_CL cl_iteminfo, AW_CL cl_title) {
142    gde_iteminfo *info         = (gde_iteminfo*)cl_iteminfo;
143    GmenuItem    *gmenuitem    = info->item;
144    int           idx          = info->idx;
145    char         *base_awar    = GDE_maketmpawarname(gmenuitem, idx);
146
147    static GB_HASH *popup_hash  = NULL;
148    if (!popup_hash) popup_hash = GBS_create_hash(20, GB_MIND_CASE);
149
150    AW_window *aw_browser = (AW_window*)GBS_read_hash(popup_hash, base_awar);
151    if (!aw_browser) {
152        const char *title = (const char *)cl_title;
153        aw_browser        = GDE_create_filename_browser_window(aw->get_root(), base_awar, title);
154        GBS_write_hash(popup_hash, base_awar, (long)aw_browser);
155    }
156    aw_browser->activate();
157    free(base_awar);
158}
159
160static AW_window *GDE_menuitem_cb(AW_root *aw_root, GmenuItem *gmenuitem) {
161#define BUFSIZE 200
162    char bf[BUFSIZE+1];
163    IF_ASSERTION_USED(int printed =)
164        sprintf(bf, "GDE / %s / %s", gmenuitem->parent_menu->label, gmenuitem->label);
165
166    gde_assert(printed<=BUFSIZE);
167    char seqtype = gmenuitem->seqtype;
168
169    if (gmenuitem->aws == NULL) {
170        AW_window_simple *aws = new AW_window_simple;
171        aws->init(aw_root, bf, bf);
172
173        switch (db_access.window_type) {
174            case GDE_WINDOWTYPE_DEFAULT: {
175                if (seqtype == '-') aws->load_xfig("gdeitem_simple.fig");
176                else                aws->load_xfig("gdeitem.fig");
177                break;
178            }
179            case GDE_WINDOWTYPE_EDIT4:
180                gde_assert(seqtype != '-');
181                aws->load_xfig("gde3item.fig");
182                break;
183        }
184
185        aws->set_window_size(1000, 2000);
186        aws->button_length(10);
187        aws->at(10, 10);
188        aws->auto_space(0, 10);
189
190        aws->at("help");
191        aws->callback((AW_CB2)GDE_showhelp_cb, (AW_CL)gmenuitem, 0);
192        aws->create_button("GDE_HELP", "HELP", "H");
193
194        aws->at("start");
195        aws->callback((AW_CB2)GDE_startaction_cb, (AW_CL)gmenuitem, 0);
196        aws->create_button("GO", "GO", "O");
197
198        aws->at("cancel");
199        aws->callback((AW_CB0)AW_POPDOWN);
200        aws->create_button("CLOSE", "CLOSE", "C");
201
202
203        if (gmenuitem->numinputs>0) {
204            switch (db_access.window_type) {
205                case GDE_WINDOWTYPE_DEFAULT: {
206                    if (seqtype != '-') { // '-' means "skip sequence export"
207                        aws->at("which_alignment");
208                        const char *ali_filter = seqtype == 'A' ? "pro=:ami=" : (seqtype == 'N' ? "dna=:rna=" : "*=");
209                        awt_create_selection_list_on_alignments(db_access.gb_main, (AW_window *)aws, AWAR_GDE_ALIGNMENT, ali_filter);
210
211                        aws->at("which_species");
212                        aws->create_toggle_field(AWAR_GDE_SPECIES);
213                        aws->insert_toggle("all", "a", 0);
214                        aws->insert_default_toggle("marked",   "m", 1);
215                        aws->update_toggle_field();
216
217                        if (seqtype != 'N') {
218                            aws->at("stop_codon");
219                            aws->label("Cut stop-codon");
220                            aws->create_toggle(AWAR_GDE_CUTOFF_STOPCODON);
221                        }
222                    }
223                    break;
224                }
225                case GDE_WINDOWTYPE_EDIT4:
226                    aws->at("topk"); aws->create_toggle("gde/top_area_kons");
227                    aws->at("middlek"); aws->create_toggle("gde/middle_area_kons");
228                    aws->at("topr"); aws->create_toggle("gde/top_area_remark");
229                    aws->at("middler"); aws->create_toggle("gde/middle_area_remark");
230                    aws->at("top"); aws->create_toggle("gde/top_area");
231                    aws->at("topsai"); aws->create_toggle("gde/top_area_sai");
232                    aws->at("toph"); aws->create_toggle("gde/top_area_helix");
233                    aws->at("middle"); aws->create_toggle("gde/middle_area");
234                    aws->at("middlesai"); aws->create_toggle("gde/middle_area_sai");
235                    aws->at("middleh"); aws->create_toggle("gde/middle_area_helix");
236                    break;
237            }
238
239            if (seqtype != '-') {
240                aws->at("compression");
241                aws->create_option_menu(AWAR_GDE_COMPRESSION, true);
242                aws->insert_option("none", "n", COMPRESS_NONE);
243                aws->insert_option("vertical gaps", "v", COMPRESS_VERTICAL_GAPS);
244                aws->insert_default_option("columns w/o info", "i", COMPRESS_NONINFO_COLUMNS);
245                aws->insert_option("all gaps", "g", COMPRESS_ALL);
246                aws->update_option_menu();
247
248                aws->button_length(12);
249                aws->at("filtername");
250                if (!agde_filter) { // create only one filter - used for all GDE calls
251                    agde_filter = awt_create_select_filter(aws->get_root(), db_access.gb_main, AWAR_GDE_FILTER_NAME);
252                }
253                aws->callback(makeCreateWindowCallback(awt_create_select_filter_win, agde_filter));
254                aws->create_button("SELECT_FILTER", AWAR_GDE_FILTER_NAME);
255            }
256
257            aws->at("paramsb");
258        }
259        else {
260            aws->at("paramsb");
261        }
262
263
264        int labellength = 1;
265        long i;
266        for (i=0; i<gmenuitem->numargs; i++) {
267            if (!(gmenuitem->arg[i].label)) gmenuitem->arg[i].label = GDEBLANK;
268
269            const char *label    = gmenuitem->arg[i].label;
270            const char *linefeed = strchr(label, '\n');
271
272            int lablen;
273            while (linefeed) {
274                lablen = linefeed-label;
275                if (lablen>labellength) {
276                    labellength = lablen;
277                }
278                label    = linefeed+1;
279                linefeed = strchr(label, '\n');
280            }
281
282            lablen = strlen(label);
283            if (lablen>labellength) {
284                labellength = lablen;
285            }
286        }
287        aws->label_length(labellength);
288        aws->auto_space(0, 0);
289
290        for (i=0; i<gmenuitem->numargs; i++) {
291            GmenuItemArg itemarg = gmenuitem->arg[i];
292
293            if (itemarg.type==SLIDER) {
294                char *newawar=GDE_makeawarname(gmenuitem, i);
295                if (int(itemarg.fvalue) == itemarg.fvalue &&
296                     int(itemarg.min) == itemarg.min &&
297                     int(itemarg.max) == itemarg.max) {
298                    aw_root->awar_int(newawar, (long)itemarg.fvalue, AW_ROOT_DEFAULT);
299                }
300                else {
301                    aw_root->awar_float(newawar, itemarg.fvalue, AW_ROOT_DEFAULT);
302                }
303                aw_root->awar(newawar)->set_minmax(itemarg.min, itemarg.max);
304                aws->label(itemarg.label);
305                aws->sens_mask(itemarg.active_mask);
306                GDE_create_infieldwithpm(aws, newawar, SLIDERWIDTH);
307                // maybe bound checking //
308                free(newawar);
309            }
310            else if (itemarg.type==CHOOSER) {
311                char    *defopt           = itemarg.choice[0].method;
312                char    *newawar          = GDE_makeawarname(gmenuitem, i);
313                AW_awar *curr_awar        = aw_root->awar_string(newawar, defopt, AW_ROOT_DEFAULT);
314                char    *curr_value       = curr_awar->read_string();
315                bool     curr_value_legal = false;
316
317                aws->label(itemarg.label);
318                aws->sens_mask(itemarg.active_mask);
319                if ((strcasecmp(itemarg.choice[0].label, "no") == 0) ||
320                    (strcasecmp(itemarg.choice[0].label, "yes") == 0))
321                {
322                    aws->create_toggle_field(newawar, 1);
323                }
324                else {
325                    aws->create_toggle_field(newawar);
326                }
327
328                for (long j=0; j<itemarg.numchoices; j++) {
329                    if (strcmp(itemarg.choice[j].method, curr_value) == 0) curr_value_legal = true;
330
331                    if (!j) {
332                        aws->insert_default_toggle(itemarg.choice[j].label, "1", itemarg.choice[j].method);
333                    }
334                    else {
335                        aws->insert_toggle(itemarg.choice[j].label, "1", itemarg.choice[j].method);
336                    }
337                }
338                if (!curr_value_legal) curr_awar->write_string(defopt); // if saved value no longer occurs in choice -> overwrite with default
339                free(curr_value);
340                aws->update_toggle_field();
341                free(newawar);
342            }
343            else if (itemarg.type==CHOICE_MENU) {
344                char    *defopt           = itemarg.choice[itemarg.ivalue].method;
345                char    *newawar          = GDE_makeawarname(gmenuitem, i);
346                AW_awar *curr_awar        = aw_root->awar_string(newawar, defopt, AW_ROOT_DEFAULT);
347                char    *curr_value       = curr_awar->read_string();
348                bool     curr_value_legal = false;
349
350                if (itemarg.label[0]) aws->label(itemarg.label);
351                aws->sens_mask(itemarg.active_mask);
352                aws->create_option_menu(newawar, true);
353
354                for (long j=0; j<itemarg.numchoices; j++) {
355                    if (strcmp(itemarg.choice[j].method, curr_value) == 0) curr_value_legal = true;
356                    aws->insert_option(itemarg.choice[j].label, "1", itemarg.choice[j].method);
357                }
358                if (!curr_value_legal) curr_awar->write_string(defopt); // if saved value no longer occurs in choice -> overwrite with default
359                free(curr_value);
360                aws->update_option_menu();
361                free(newawar);
362            }
363            else if (itemarg.type==TEXTFIELD) {
364                char *defopt  = itemarg.textvalue;
365                char *newawar = GDE_makeawarname(gmenuitem, i);
366                aw_root->awar_string(newawar, defopt, AW_ROOT_DEFAULT);
367                aws->label(itemarg.label);
368                aws->sens_mask(itemarg.active_mask);
369                aws->create_input_field(newawar, itemarg.textwidth);  // TEXTFIELDWIDTH
370                free(newawar);
371            }
372            else if (itemarg.type==FILE_SELECTOR) {
373                char *base_awar = GDE_maketmpawarname(gmenuitem, i);
374                char *name_awar = GBS_global_string_copy("%s/file_name", base_awar);
375
376                AW_create_fileselection_awars(aw_root, base_awar, "", itemarg.textvalue, "");
377
378                aws->label(itemarg.label);
379                aws->sens_mask(itemarg.active_mask);
380                aws->create_input_field(name_awar, 40);
381                aws->callback(GDE_popup_filename_browser, (AW_CL)new gde_iteminfo(gmenuitem, i), (AW_CL)strdup(itemarg.label));
382                aws->create_button("", "Browse");
383
384                free(name_awar);
385                free(base_awar);
386            }
387            else if (itemarg.type==CHOICE_TREE) {
388                char *defopt=itemarg.textvalue;
389                char *newawar=GDE_makeawarname(gmenuitem, i);
390                aw_root->awar_string(newawar, defopt, AW_ROOT_DEFAULT);
391                aws->sens_mask(itemarg.active_mask);
392                if (itemarg.label[0]) aws->create_button(NULL, itemarg.label);
393                awt_create_selection_list_on_trees(db_access.gb_main, aws, newawar, true);
394                free(newawar);
395            }
396            else if (itemarg.type==CHOICE_SAI) {
397                char *defopt=itemarg.textvalue;
398                char *newawar=GDE_makeawarname(gmenuitem, i);
399                aw_root->awar_string(newawar, defopt, AW_ROOT_DEFAULT);
400                aws->sens_mask(itemarg.active_mask);
401                if (itemarg.label[0]) aws->create_button(NULL, itemarg.label);
402                awt_create_selection_list_on_sai(db_access.gb_main, aws, newawar, true);
403                free(newawar);
404            }
405            else if (itemarg.type==CHOICE_WEIGHTS) {
406                char *defopt=itemarg.textvalue;
407                char *newawar=GDE_makeawarname(gmenuitem, i);
408                aw_root->awar_string(newawar, defopt, AW_ROOT_DEFAULT);
409                aws->sens_mask(itemarg.active_mask);
410                if (itemarg.label[0]) aws->create_button(NULL, itemarg.label);
411                AWT_sai_selection *id = awt_create_selection_list_on_sai(db_access.gb_main, aws, newawar, true, gde_filter_weights);
412                free(newawar);
413                aw_root->awar(AWAR_GDE_ALIGNMENT)->add_callback(makeRootCallback(awt_selection_list_on_sai_update_cb, id));
414            }
415
416            aws->at_newline();
417        }
418        aws->at_newline();
419        aws->window_fit();
420
421        gmenuitem->aws = aws;
422    }
423    return gmenuitem->aws;
424#undef BUFSIZE
425}
426
427
428
429
430void GDE_load_menu(AW_window *awm, AW_active /*mask*/, const char *menulabel) {
431    // Load GDE menu items.
432    //
433    // If 'menulabel' == NULL -> load all menus
434    // Else                   -> load specified menu
435    //
436    // Always loads complete menu(s).
437
438    gde_assert(db_access.gb_main); // forgot to call GDE_create_var() ?
439
440    char hotkey[]   = "x";
441    bool menuloaded = false;
442    bool itemloaded = false;
443
444    for (long nmenu = 0; nmenu<num_menus; nmenu++) {
445        {
446            const char *menuname = menu[nmenu].label;
447            if (menulabel) {
448                if (strcmp(menulabel, menuname)) {
449                    continue;
450                }
451            }
452            else {
453                hotkey[0] = menu[nmenu].meta;
454                awm->insert_sub_menu(menuname, hotkey, menu[nmenu].active_mask);
455            }
456        }
457
458        menuloaded = true;
459
460        long num_items = menu[nmenu].numitems;
461        for (long nitem=0; nitem<num_items; nitem++) {
462            GmenuItem *menuitem=&menu[nmenu].item[nitem];
463            itemloaded = true;
464            gde_assert(!menuitem->help || ARB_strBeginsWith(menuitem->help, "agde_"));
465            hotkey[0] = menuitem->meta;
466            awm->insert_menu_topic(menuitem->label, menuitem->label, hotkey,
467                                   menuitem->help, menuitem->active_mask,
468                                   AW_POPUP, (AW_CL)GDE_menuitem_cb, (AW_CL)menuitem);
469        }
470
471        if (!menulabel) {
472            awm->close_sub_menu();
473        }
474    }
475
476    if (!menuloaded && menulabel) {
477        fprintf(stderr, "GDE-Warning: Could not find requested menu '%s'\n", menulabel);
478    }
479}
480
481struct gde_database_access db_access = { NULL, GDE_WINDOWTYPE_DEFAULT, 0, NULL};
482
483GB_ERROR GDE_create_var(AW_root *aw_root, AW_default aw_def, GBDATA *gb_main, GDE_get_sequences_cb get_sequences, gde_window_type window_type, AW_CL client_data) {
484    db_access.get_sequences = get_sequences;
485    db_access.window_type   = window_type;
486    db_access.client_data   = client_data;
487    db_access.gb_main       = gb_main;
488
489    aw_root->awar_string(AWAR_GDE_ALIGNMENT, "", aw_def);
490
491    switch (db_access.window_type) {
492        case GDE_WINDOWTYPE_EDIT4:
493            aw_root->awar_int("gde/top_area_kons",      1, aw_def);
494            aw_root->awar_int("gde/top_area_remark",    1, aw_def);
495            aw_root->awar_int("gde/middle_area_kons",   1, aw_def);
496            aw_root->awar_int("gde/middle_area_remark", 1, aw_def);
497            aw_root->awar_int("gde/top_area",           1, aw_def);
498            aw_root->awar_int("gde/top_area_sai",       1, aw_def);
499            aw_root->awar_int("gde/top_area_helix",     1, aw_def);
500            aw_root->awar_int("gde/middle_area",        1, aw_def);
501            aw_root->awar_int("gde/middle_area_sai",    1, aw_def);
502            aw_root->awar_int("gde/middle_area_helix",  1, aw_def);
503            aw_root->awar_int("gde/bottom_area",        1, aw_def);
504            aw_root->awar_int("gde/bottom_area_sai",    1, aw_def);
505            aw_root->awar_int("gde/bottom_area_helix",  1, aw_def);
506            break;
507        case GDE_WINDOWTYPE_DEFAULT:
508            break;
509    }
510
511    aw_root->awar_string(AWAR_DEFAULT_ALIGNMENT, "", db_access.gb_main);
512   
513    aw_root->awar_string(AWAR_GDE_FILTER_NAME,      "", aw_def);
514    aw_root->awar_string(AWAR_GDE_FILTER_FILTER,    "", aw_def);
515    aw_root->awar_string(AWAR_GDE_FILTER_ALIGNMENT, "", aw_def);
516
517    aw_root->awar_int(AWAR_GDE_CUTOFF_STOPCODON, 0, aw_def);
518    aw_root->awar_int(AWAR_GDE_SPECIES,          1, aw_def);
519
520    aw_root->awar_int(AWAR_GDE_COMPRESSION, COMPRESS_NONINFO_COLUMNS, aw_def);
521
522    aw_root->awar(AWAR_GDE_ALIGNMENT)->map(AWAR_DEFAULT_ALIGNMENT);
523    aw_root->awar(AWAR_GDE_FILTER_ALIGNMENT)->map(AWAR_DEFAULT_ALIGNMENT);
524
525    DataSet = (NA_Alignment *) Calloc(1, sizeof(NA_Alignment));
526    DataSet->rel_offset = 0;
527    return LoadMenus();
528}
529
Note: See TracBrowser for help on using the repository browser.