source: tags/svn.1.5.4/ARB_GDE/GDE.cxx

Last change on this file was 8309, checked in by westram, 14 years ago
  • moved much code into static scope

(partly reverted by [8310])

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