source: branches/port5/ARB_GDE/GDE.cxx

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