source: branches/ali/ARB_GDE/GDE.cxx

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