source: tags/arb_5.5/ARB_GDE/GDE_event.cxx

Last change on this file was 5940, checked in by westram, 15 years ago
  • removed class AWwindowinfo
  • directly linked each GmenuItem? to its parent Gmenu
  • provide GmenuItem? as callback client data (instead of AWwindowinfo)
  • this avoids
    • unneccessary allocation of class AWwindowinfo
    • multiple AWwindowinfo's if a GDE menuitems is added multiple (most of the are added multiple times).
    • the callbacks bound to the menu-topics can be identified as identical (patch using that will follow)
  • Popup windows opened by GDE menuitem callbacks are stored in GmenuItem?. Calling the same menuitem from different menus now re-uses the window.
  • removed prototypes from GDE.cxx (and include GDE_proto.h)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.8 KB
Line 
1#include <unistd.h>
2#include <netdb.h>
3#include <sys/time.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9//#include <xview/xview.h>
10//#include <xview/panel.h>
11#include <arbdb.h>
12#include <arbdbt.h>
13// #include <malloc.h>
14#include <aw_root.hxx>
15#include <aw_device.hxx>
16#include <aw_window.hxx>
17#include <awt.hxx>
18#include <awt_tree.hxx>
19#include <awt_sel_boxes.hxx>
20#include <gde.hxx>
21#include "GDE_menu.h"
22#include "GDE_def.h"
23#include "GDE_extglob.h"
24#include "GDE_awars.h"
25
26#include <string>
27#include <set>
28
29using namespace std;
30
31#define DEFAULT_COLOR 8
32extern adfiltercbstruct *agde_filtercd;
33
34/*
35  ReplaceArgs():
36  Replace all command line arguements with the appropriate values
37  stored for the chosen menu item.
38
39  Copyright (c) 1989-1990, University of Illinois board of trustees.  All
40  rights reserved.  Written by Steven Smith at the Center for Prokaryote Genome
41  Analysis.  Design and implementation guidance by Dr. Gary Olsen and Dr.
42  Carl Woese.
43
44  Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
45  All rights reserved.
46
47*/
48
49
50static char *ReplaceArgs(AW_root *awr,char *Action,GmenuItem *gmenuitem,int number)
51{
52    /*
53     *  The basic idea is to replace all of the symbols in the method
54     *  string with the values picked in the dialog box.  The method
55     *  is the general command line structure.  All arguements have three
56     *  parts, a label, a method, and a value.  The method never changes, and
57     *  is used to represent '-flag's for a given function.  Values are the
58     *  associated arguements that some flags require.  All symbols that
59     *  require argvalue replacement should have a '$' infront of the symbol
60     *  name in the itemmethod definition.  All symbols without the '$' will
61     *  be replaced by their argmethod.  There is currently no way to do a label
62     *  replacement, as the label is considered to be for use in the dialog
63     *  box only.  An example command line replacement would be:
64     *
65     *       itemmethod=>        "lpr arg1 $arg1 $arg2"
66     *
67     *       arglabel arg1=>     "To printer?"
68     *       argmethod arg1=>    "-P"
69     *       argvalue arg1=>     "lw"
70     *
71     *       arglabel arg2=>     "File name?"
72     *       argvalue arg2=>     "foobar"
73     *       argmethod arg2=>    ""
74     *
75     *   final command line:
76     *
77     *       lpr -P lw foobar
78     *
79     *   At this point, the chooser dialog type only supports the arglabel and
80     *   argmethod field.  So if an argument is of type chooser, and
81     *   its symbol is "this", then "$this" has no real meaning in the
82     *   itemmethod definition.  Its format in the .GDEmenu file is slighty
83     *   different as well.  A choice from a chooser field looks like:
84     *
85     *       argchoice:Argument_label:Argument_method
86     *
87     *
88     */
89    const char *symbol=0;
90    char *method=0;
91    char *textvalue=0;
92    char *temp;
93    int i,newlen,type;
94    symbol = gmenuitem->arg[number].symbol;
95    //method = gmenuitem->arg[number]->method;
96    //textvalue = gmenuitem->arg[number]->textvalue;
97    type = gmenuitem->arg[number].type;
98    if( (type == SLIDER) )
99    {
100        char *awarname = GDE_makeawarname(gmenuitem,number);
101        textvalue      = (char*)malloc(GBUFSIZ);
102        char *awalue   = awr->awar(awarname)->read_as_string();
103        sprintf(textvalue,"%s",awalue);
104        free(awalue);
105    }
106    else if((type == CHOOSER) ||
107            (type == CHOICE_TREE) ||
108            (type == CHOICE_SAI) ||
109            (type == CHOICE_MENU) ||
110            (type == CHOICE_LIST) ||
111            (type == CHOICE_WEIGHTS) ||
112            (type == TEXTFIELD))
113    {
114        char *awarname=GDE_makeawarname(gmenuitem,number);
115        method=awr->awar(awarname)->read_string();
116        textvalue=awr->awar(awarname)->read_string();
117    }
118
119    if(textvalue == NULL)   textvalue=(char *)calloc(1,sizeof(char));
120    if(method == NULL)      method=(char *)calloc(1,sizeof(char));
121    if(symbol == NULL)      symbol="";
122
123    set<string>warned_about;
124    int conversion_warning        = 0;
125    int j                         = 0;
126
127    for(; (i=Find2(Action+j,symbol)) != -1;)
128    {
129        i += j;
130        ++j;
131        if(i>0 && Action[i-1] == '$' )
132        {
133            newlen = strlen(Action)-strlen(symbol)
134                +strlen(textvalue);
135            temp = (char *)calloc(newlen,1);
136            if (temp == NULL)
137                Error("ReplaceArgs():Error in calloc");
138            strncat(temp,Action,i-1);
139            strncat(temp,textvalue,strlen(textvalue));
140            strcat( temp,&(Action[i+strlen(symbol)]) );
141            freeset(Action, temp);
142        }
143        else {
144            if (warned_about.find(symbol) == warned_about.end()) {
145                fprintf(stderr,
146                        "old arb version converted '%s' to '%s' (now only '$%s' is converted)\n",
147                        symbol, textvalue, symbol);
148                conversion_warning++;
149                warned_about.insert(symbol);
150            }
151        }
152    }
153
154    if (conversion_warning) {
155        fprintf(stderr,
156                "Conversion warnings occurred in Action:\n'%s'\n",
157                Action);
158    }
159
160    free(textvalue);
161    free(method);
162    return(Action);
163}
164
165
166
167static long LMAX(long a,long b)
168{
169    if(a>b) return a;
170    return b;
171}
172
173static void GDE_free(void **p) {
174    freeset(*p, NULL);
175}
176
177static char *ReplaceFile(char *Action,GfileFormat file)
178{
179    char *symbol,*method,*temp;
180    int i,newlen;
181    symbol = file.symbol;
182    method = file.name;
183
184    for(; (i=Find2(Action,symbol)) != -1;)
185    {
186        newlen = strlen(Action)-strlen(symbol) + strlen(method)+1;
187        temp = (char *)calloc(newlen,1);
188        if (temp == NULL)
189            Error("ReplaceFile():Error in calloc");
190        strncat(temp,Action,i);
191        strncat(temp,method,strlen(method));
192        strcat( temp,&(Action[i+strlen(symbol)]) );
193        freeset(Action, temp);
194    }
195    return(Action);
196}
197
198static char *ReplaceString(char *Action,const char *old,const char *news)
199{
200    const char *symbol;
201    const char *method;
202    char *temp;
203    int i,newlen;
204
205    symbol = old;
206    method = news;
207
208    for(; (i=Find2(Action,symbol)) != -1;)
209    {
210        newlen = strlen(Action)-strlen(symbol) + strlen(method)+1;
211        temp = (char *)calloc(newlen,1);
212        if (temp == NULL)
213            Error("ReplaceFile():Error in calloc");
214        strncat(temp,Action,i);
215        strncat(temp,method,strlen(method));
216        strcat( temp,&(Action[i+strlen(symbol)]) );
217        freeset(Action, temp);
218    }
219    return(Action);
220}
221
222
223static void GDE_freesequ(NA_Sequence *sequ) {
224    if (sequ) {
225        GDE_free((void**)&sequ->comments);
226        GDE_free((void**)&sequ->cmask);
227        GDE_free((void**)&sequ->baggage);
228        GDE_free((void**)&sequ->sequence);
229    }
230}
231
232static void GDE_freeali(NA_Alignment *dataset) {
233    if (dataset) {
234        GDE_free((void**)&dataset->id);
235        GDE_free((void**)&dataset->description);
236        GDE_free((void**)&dataset->authority);
237        GDE_free((void**)&dataset->cmask);
238        GDE_free((void**)&dataset->selection_mask);
239        GDE_free((void**)&dataset->alignment_name);
240
241        for (unsigned long i=0;i<dataset->numelements;i++) {
242            GDE_freesequ(dataset->element+i);
243        }
244    }
245}
246
247static void GDE_export(NA_Alignment *dataset, char *align, long oldnumelements) {
248    GB_ERROR error = GB_begin_transaction(GLOBAL_gb_main);
249   
250    long maxalignlen    = GBT_get_alignment_len(GLOBAL_gb_main, align);
251    long isdefaultalign = 0;
252
253    if (maxalignlen <= 0 && !error) {
254        align             = GBT_get_default_alignment(GLOBAL_gb_main);
255        if (!align) error = GB_await_error();
256        else {
257            isdefaultalign = 1;
258            maxalignlen    = GBT_get_alignment_len(GLOBAL_gb_main, align);
259        }
260    }
261
262    long lotyp = 0;
263    if (!error) {
264        GB_alignment_type at = GBT_get_alignment_type(GLOBAL_gb_main, align);
265
266        switch (at) {
267            case GB_AT_DNA:     lotyp = DNA;     break;
268            case GB_AT_RNA:     lotyp = RNA;     break;
269            case GB_AT_AA:      lotyp = PROTEIN; break;
270            case GB_AT_UNKNOWN: lotyp = DNA;     break;
271        }
272    }
273
274    unsigned long i;
275    int           load_all = 0;
276
277    for (i = oldnumelements; !error && i < dataset->numelements; i++) {
278        NA_Sequence *sequ = dataset->element+i;
279        int seqtyp, issame = 0;
280
281        seqtyp = sequ->elementtype;
282        if ((seqtyp == lotyp) || ((seqtyp == DNA) && (lotyp == RNA)) || ((seqtyp == RNA) && (lotyp == DNA))) {
283            issame = 1;
284        }
285        else {
286            aw_message(GBS_global_string("Warning: sequence type of species '%s' changed", sequ->short_name));
287        }
288
289        if (sequ->tmatrix) {
290            for (long j = 0; j < sequ->seqlen; j++) {
291                sequ->sequence[j] = (char)sequ->tmatrix[sequ->sequence[j]];
292            }
293        }
294
295        char *savename = GBS_string_2_key(sequ->short_name);
296
297        sequ->gb_species = 0;
298
299        if (!issame) {          /* save as extended */
300            GBDATA *gb_extended = GBT_find_or_create_SAI(GLOBAL_gb_main, savename);
301
302            if (!gb_extended) error = GB_await_error();
303            else {
304                sequ->gb_species    = gb_extended;
305                GBDATA *gb_data     = GBT_add_data(gb_extended, align, "data", GB_STRING);
306                if (!gb_data) error = GB_await_error();
307                else    error       = GBT_write_sequence(gb_data, align, maxalignlen, (char *)sequ->sequence);
308            }
309        }
310        else {                  /* save as sequence */
311            GBDATA *gb_species_data     = GB_search(GLOBAL_gb_main, "species_data", GB_CREATE_CONTAINER);
312            if (!gb_species_data) error = GB_await_error();
313            else {
314                GBDATA *gb_species = GBT_find_species_rel_species_data(gb_species_data, savename);
315
316                GB_push_my_security(GLOBAL_gb_main);
317
318                if (gb_species) {   /* new element that already exists !!!! */
319                    int select_mode;
320                    const char *msg =
321                        GBS_global_string("You are (re-)importing a species '%s'.\n"
322                                          "That species already exists in your database!\n"
323                                          "\n"
324                                          "Possible actions:\n"
325                                          "\n"
326                                          "       - delete and overwrite the existing species\n"
327                                          "       - skip - don't change the species\n"
328                                          "       - reimport only the sequence of the existing species\n"
329                                          "       - reimport all sequences (don't ask again)\n"
330                                          "\n"
331                                          "Note: After aligning it's recommended to choose 'reimport all'.",
332                                          savename);
333
334                    if (!load_all) {
335                        select_mode = aw_question(msg,
336                                                  "delete existing,"   // 0
337                                                  "skip,"              // 1
338                                                  "reimport sequence," // 2
339                                                  "reimport all"       // 3
340                                                  );
341
342                        if (select_mode == 3) {     // load all sequences
343                            load_all = 1;
344                        }
345                    }
346
347                    if (load_all) select_mode = 2;    // reimport sequence
348                    gde_assert(select_mode >= 0 && select_mode <= 2);
349
350                    switch (select_mode) {
351                        case 1:    // skip
352                            gb_species = 0;
353                            break;       // continue with next species
354
355                        case 0:    // delete existing species
356                            GB_delete(gb_species);
357                            // fall-through!
358                        case 2:    // reimport sequence
359                            gb_species = GBT_find_or_create_species_rel_species_data(gb_species_data, savename);
360                            break;
361                    }
362                }
363                else {
364                    gb_species = GBT_find_or_create_species_rel_species_data(gb_species_data, savename);
365                }
366                if (gb_species) {
367                    sequ->gb_species = gb_species;
368
369                    GBDATA *gb_data     = GBT_add_data(gb_species, align, "data", GB_STRING); // does only add if not already existing
370                    if (!gb_data) error = GB_await_error();
371                    else {
372                        GBDATA *gb_old_data = GBT_read_sequence(gb_species, align);
373                        if (gb_old_data) {  // we already have data -> compare checksums
374                            const char *old_seq      = GB_read_char_pntr(gb_old_data);
375                            long        old_checksum = GBS_checksum(old_seq, 1, "-.");
376                            long        new_checksum = GBS_checksum((char *)sequ->sequence, 1, "-.");
377
378                            if (old_checksum != new_checksum) {
379                                aw_message(GBS_global_string("Warning: Sequence checksum for '%s' differs", savename));
380                            }
381                        }
382                        error = GBT_write_sequence(gb_data, align, maxalignlen, (char *)sequ->sequence);
383                    }
384                }
385                GB_pop_my_security(GLOBAL_gb_main);
386            }
387        }
388        free(savename);
389    }
390
391    /* colormasks */
392    for (i = 0; !error && i < dataset->numelements; i++) {
393        NA_Sequence *sequ = &(dataset->element[i]);
394
395        if (sequ->cmask) {
396            maxalignlen     = LMAX(maxalignlen, sequ->seqlen);
397            char *resstring = (char *)calloc((unsigned int)maxalignlen + 1, sizeof(char));
398            char *dummy     = resstring;
399
400            for (long j = 0; j < maxalignlen - sequ->seqlen; j++) *resstring++ = DEFAULT_COLOR;
401            for (long k = 0; k < sequ->seqlen; k++)               *resstring++ = (char)sequ->cmask[i];
402            *resstring = '\0';
403
404            GBDATA *gb_ali     = GB_search(sequ->gb_species, align, GB_CREATE_CONTAINER);
405            if (!gb_ali) error = GB_await_error();
406            else {
407                GBDATA *gb_color     = GB_search(gb_ali, "colmask", GB_BYTES);
408                if (!gb_color) error = GB_await_error();
409                else    error        = GB_write_bytes(gb_color, dummy, maxalignlen);
410            }
411            free(dummy);
412        }
413    }
414
415    if (!error && dataset->cmask) {
416        maxalignlen     = LMAX(maxalignlen, dataset->cmask_len);
417        char *resstring = (char *)calloc((unsigned int)maxalignlen + 1, sizeof(char));
418        char *dummy     = resstring;
419        long  k;
420
421        for (k = 0; k < maxalignlen - dataset->cmask_len; k++) *resstring++ = DEFAULT_COLOR;
422        for (k = 0; k < dataset->cmask_len; k++)               *resstring++ = (char)dataset->cmask[k];
423        *resstring = '\0';
424
425        GBDATA *gb_extended     = GBT_find_or_create_SAI(GLOBAL_gb_main, "COLMASK");
426        if (!gb_extended) error = GB_await_error();
427        else {
428            GBDATA *gb_color     = GBT_add_data(gb_extended, align, "colmask", GB_BYTES);
429            if (!gb_color) error = GB_await_error();
430            else    error        = GB_write_bytes(gb_color, dummy, maxalignlen);
431        }
432
433        free(dummy);
434    }
435
436    GB_end_transaction_show_error(GLOBAL_gb_main, error, aw_message);
437    if (isdefaultalign) free(align);
438}
439
440static char *preCreateTempfile(const char *name) {
441    // creates a tempfile and returns heapcopy of fullpath
442    // exits in case of error
443    char *fullname = GB_create_tempfile(name);
444
445    if (!fullname) Error(GBS_global_string("preCreateTempfile: %s", GB_await_error())); // exits
446    return fullname;
447}
448
449void GDE_startaction_cb(AW_window *aw,GmenuItem *gmenuitem,AW_CL cd)
450{
451    long oldnumelements=0;
452    AWUSE(cd);
453    AW_root *aw_root=aw->get_root();
454
455    GapCompression  compress          = static_cast<GapCompression>(aw_root->awar(AWAR_GDE_COMPRESSION)->read_int());
456    AP_filter      *filter2           = awt_get_filter(aw_root,agde_filtercd);
457    char           *filter_name       = 0; /* aw_root->awar(AWAR_GDE_FILTER_NAME)->read_string() */
458    char           *alignment_name    = strdup("ali_unknown");
459    bool            marked            = (aw_root->awar(AWAR_GDE_SPECIES)->read_int() != 0);
460    long            cutoff_stop_codon = aw_root->awar(AWAR_GDE_CUTOFF_STOPCODON)->read_int();
461
462    GmenuItem *current_item;
463    current_item=gmenuitem;
464
465    aw_openstatus(current_item->label);
466    aw_status((double)0);
467
468    int   j;
469    bool  flag;
470    char *Action,buffer[GBUFSIZ];
471
472    static int fileindx    = 0;
473    int        select_mode = 0;
474    int        stop        = 0;
475
476    if (current_item->numinputs>0) {
477        DataSet->gb_main = GLOBAL_gb_main;
478        GB_begin_transaction(DataSet->gb_main);
479        freeset(DataSet->alignment_name, GBT_get_default_alignment(DataSet->gb_main));
480        freedup(alignment_name, DataSet->alignment_name);
481
482        aw_status("reading database");
483        if (gde_cgss.get_sequences) {
484            stop = ReadArbdb2(DataSet, filter2, compress, cutoff_stop_codon);
485        }
486        else {
487            stop = ReadArbdb(DataSet, marked, filter2, compress, cutoff_stop_codon);
488        }
489        GB_commit_transaction(DataSet->gb_main);
490
491        if (!stop && DataSet->numelements==0) {
492            aw_message("no sequences selected");
493            stop = 1;
494        }
495    }
496
497    if (!stop) {
498        flag = false;
499        for(j=0;j<current_item->numinputs;j++) {
500            if(current_item->input[j].format != STATUS_FILE) {
501                flag = true;
502            }
503        }
504        if(flag && DataSet) select_mode = ALL; // TestSelection();
505
506        int pid = getpid();
507
508        for(j=0;j<current_item->numinputs;j++) {
509            GfileFormat& gfile = current_item->input[j];
510
511            sprintf(buffer,"gde%d_%d", pid, fileindx++);
512            gfile.name = preCreateTempfile(buffer);
513
514            switch(gfile.format) {
515                case COLORMASK:   WriteCMask  (DataSet, gfile.name, select_mode, gfile.maskable); break;
516                case GENBANK:     WriteGen    (DataSet, gfile.name, select_mode, gfile.maskable); break;
517                case NA_FLAT:     WriteNA_Flat(DataSet, gfile.name, select_mode, gfile.maskable); break;
518                case STATUS_FILE: WriteStatus (DataSet, gfile.name, select_mode)                ; break;
519                case GDE:         WriteGDE    (DataSet, gfile.name, select_mode, gfile.maskable); break;
520                default: break;
521            }
522        }
523
524        for(j=0;j<current_item->numoutputs;j++) {
525            sprintf(buffer,"gde%d_%d", pid, fileindx++);
526            current_item->output[j].name = preCreateTempfile(buffer);
527        }
528
529        /*
530         *  Create the command line for external the function call
531         */
532        Action = (char*)strdup(current_item->method);
533        if(Action == NULL) Error("DO(): Error in duplicating method string");
534
535        while (1) {
536            char *oldAction = strdup(Action);
537
538            for(j=0;j<current_item->numargs;j++) Action = ReplaceArgs(aw_root,Action,gmenuitem,j);
539            bool changed = strcmp(oldAction, Action) != 0;
540            free(oldAction);
541
542            if (!changed) break;
543        }
544
545        for(j=0;j<current_item->numinputs;j++) Action = ReplaceFile(Action,current_item->input[j]);
546        for(j=0;j<current_item->numoutputs;j++) Action = ReplaceFile(Action,current_item->output[j]);
547
548        filter_name = AWT_get_combined_filter_name(aw_root, "gde");
549        Action = ReplaceString(Action,"$FILTER",filter_name);
550
551        /*
552         *  call and go...
553         */
554
555        aw_status("calling external program");
556        printf("Action: %s\n",Action);
557        system(Action);
558        free(Action);
559
560        oldnumelements=DataSet->numelements;
561
562        BlockInput = false;
563
564        for(j=0;j<current_item->numoutputs;j++)
565        {
566            if(current_item->output[j].overwrite)
567            {
568                if(current_item->output[j].format == GDE)
569                    OVERWRITE = true;
570                else
571                    Warning("Overwrite mode only available for GDE format");
572            }
573            switch(current_item->output[j].format)
574            {
575                /*
576                 *     The LoadData routine must be reworked so that
577                 *     OpenFileName uses it, and so I can remove the
578                 *     major kluge in OpenFileName().
579                 */
580                case GENBANK:
581                case NA_FLAT:
582                case GDE:
583                    /*ARB-change:*/
584                    /*OpenFileName(current_item->output[j].name,NULL);*/
585                    LoadData(current_item->output[j].name);
586                    break;
587                case COLORMASK:
588                    ReadCMask(current_item->output[j].name);
589                    break;
590                case STATUS_FILE:
591                    ReadStatus(current_item->output[j].name);
592                    break;
593                default:
594                    break;
595            }
596            OVERWRITE = false;
597        }
598        for(j=0;j<current_item->numoutputs;j++)
599        {
600            if(!current_item->output[j].save)
601            {
602                unlink(current_item->output[j].name);
603            }
604        }
605
606        for(j=0;j<current_item->numinputs;j++)
607        {
608            if(!current_item->input[j].save)
609            {
610                unlink(current_item->input[j].name);
611            }
612        }
613
614        aw_closestatus();
615        GDE_export(DataSet,alignment_name,oldnumelements);
616    }
617    else {
618        aw_closestatus();
619    }
620
621    free(alignment_name);
622    delete filter2;
623    free(filter_name);
624
625    GDE_freeali(DataSet);
626    freeset(DataSet, (NA_Alignment *)Calloc(1,sizeof(NA_Alignment)));
627    DataSet->rel_offset = 0;
628}
629
Note: See TracBrowser for help on using the repository browser.