source: tags/arb_5.2/GENOM/GEN_map.cxx

Last change on this file was 6100, checked in by westram, 15 years ago
  • fix warning "format not a string literal and no format arguments"
    • GB_export_error → GB_export_error/GB_export_errorf
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 70.6 KB
Line 
1/*********************************************************************************
2 *  Coded by Ralf Westram (coder@reallysoft.de) in 2001                          *
3 *  Institute of Microbiology (Technical University Munich)                      *
4 *  http://www.mikro.biologie.tu-muenchen.de/                                    *
5 *********************************************************************************/
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include <map>
12
13#include <arbdb.h>
14#include <arbdbt.h>
15
16#include <aw_root.hxx>
17#include <aw_device.hxx>
18#include <aw_window.hxx>
19#include <aw_preset.hxx>
20#include <aw_awars.hxx>
21#include <aw_question.hxx>
22#include <awt_canvas.hxx>
23#include <awt.hxx>
24#include <AW_rename.hxx>
25#include <awt_input_mask.hxx>
26
27#include "GEN_local.hxx"
28#include "GEN_gene.hxx"
29#include "GEN_graphic.hxx"
30#include "GEN_nds.hxx"
31#include "GEN_interface.hxx"
32#include "EXP.hxx"
33#include "EXP_interface.hxx"
34#include "EXP_local.hxx"
35#include "../NTREE/ad_spec.hxx" // needed for species query window
36
37using namespace std;
38
39extern GBDATA *GLOBAL_gb_main;
40
41// -----------------------------
42//      class GEN_map_window
43// -----------------------------
44class GEN_map_window: public AW_window_menu_modes {
45    int          window_nr;
46    GEN_graphic *gen_graphic;
47    AWT_canvas  *gen_canvas;
48
49    GEN_map_window(const GEN_map_window& other); // copying not allowed
50    GEN_map_window& operator = (const GEN_map_window& other); // assignment not allowed
51public:
52    GEN_map_window(int window_nr_)
53        : AW_window_menu_modes()
54        , window_nr(window_nr_)
55        , gen_graphic(0)
56        , gen_canvas(0)
57    { }
58
59    void init(AW_root *root);
60
61    GEN_graphic *get_graphic() const { gen_assert(gen_graphic); return gen_graphic; }
62    AWT_canvas *get_canvas() const { gen_assert(gen_canvas); return gen_canvas; }
63    int get_nr() const { return window_nr; }
64};
65
66// -------------------------------
67//      class GEN_map_manager
68// -------------------------------
69
70class GEN_map_manager {
71    static AW_root         *aw_root;
72    static GEN_map_manager *the_manager; // there can be only one!
73
74    int              window_counter;
75    GEN_map_window **windows;   // array of managed windows
76    int              windows_size; // size of 'windows' array
77
78    GEN_map_manager(const GEN_map_manager& other); // copying not allowed
79    GEN_map_manager& operator = (const GEN_map_manager& other); // assignment not allowed
80
81public:
82
83    GEN_map_manager();
84
85    static bool initialized() { return aw_root != 0; }
86    static void initialize(AW_root *aw_root_) { aw_root = aw_root_; }
87    static GEN_map_manager *get_map_manager();
88
89    GEN_map_window *get_map_window(int nr);
90
91    int no_of_managed_windows() { return window_counter; }
92
93    typedef void (*GMW_CB2)(GEN_map_window*, AW_CL, AW_CL);
94    typedef void (*GMW_CB1)(GEN_map_window*, AW_CL);
95    typedef void (*GMW_CB0)(GEN_map_window*);
96
97    static void with_all_mapped_windows(GMW_CB2 callback, AW_CL cd1, AW_CL cd2);
98    static void with_all_mapped_windows(GMW_CB1 callback, AW_CL cd) { with_all_mapped_windows((GMW_CB2)callback, cd, 0); }
99    static void with_all_mapped_windows(GMW_CB0 callback) { with_all_mapped_windows((GMW_CB2)callback, 0, 0); }
100};
101
102// ____________________________________________________________
103// start of implementation of class GEN_map_manager:
104
105AW_root         *GEN_map_manager::aw_root     = 0;
106GEN_map_manager *GEN_map_manager::the_manager = 0;
107
108GEN_map_manager::GEN_map_manager()
109    : window_counter(0)
110    , windows(new GEN_map_window *[5])
111    , windows_size(5)
112{
113    gen_assert(!the_manager);   // only one instance allowed
114    the_manager = this;
115}
116
117GEN_map_manager *GEN_map_manager::get_map_manager() {
118    if (!the_manager) {
119        gen_assert(aw_root);    // call initialize() before!
120        new GEN_map_manager();  // sets the manager
121        gen_assert(the_manager);
122    }
123    return the_manager;
124}
125
126void GEN_map_manager::with_all_mapped_windows(GMW_CB2 callback, AW_CL cd1, AW_CL cd2) {
127    GEN_map_manager *mm       = get_map_manager();
128    int              winCount = mm->no_of_managed_windows();
129    for (int nr = 0; nr<winCount; ++nr) {
130        callback(mm->get_map_window(nr), cd1, cd2);
131    }
132}
133
134GEN_map_window *GEN_map_manager::get_map_window(int nr)
135{
136    gen_assert(aw_root);
137    gen_assert(nr >= 0);
138    if (nr<window_counter) {
139        return windows[nr]; // window has already been created before
140    }
141
142    gen_assert(nr == window_counter); // increase nr sequentially!
143
144    window_counter++;
145    if (window_counter>windows_size) {
146        int             new_windows_size = windows_size+5;
147        GEN_map_window **new_windows      = new GEN_map_window*[new_windows_size];
148
149        for (int i = 0; i<windows_size; ++i) new_windows[i] = windows[i];
150
151        delete [] windows;
152        windows      = new_windows;
153        windows_size = new_windows_size;
154    }
155
156    gen_assert(nr<windows_size);
157
158    windows[nr] = new GEN_map_window(nr);
159    windows[nr]->init(aw_root);
160    return windows[nr];
161}
162
163// -end- of implementation of class GEN_map_manager.
164
165
166
167const char *GEN_window_local_awar_name(const char *awar_name, int window_nr) {
168    return GBS_global_string("%s_%i", awar_name, window_nr);
169}
170
171static void reinit_NDS_4_window(GEN_map_window *win) {
172    win->get_graphic()->get_gen_root()->reinit_NDS();
173}
174
175static void GEN_NDS_changed(GBDATA *, int *, gb_call_back_type) {
176    GEN_make_node_text_init(GLOBAL_gb_main);
177    GEN_map_manager::with_all_mapped_windows(reinit_NDS_4_window);
178
179    // GEN_GRAPHIC->gen_root->reinit_NDS();
180}
181
182struct gene_container_changed_cb_data {
183    AWT_canvas  *canvas;
184    GEN_graphic *graphic;
185    GBDATA      *gb_gene_data; // callback was installed for this gene_data
186
187    gene_container_changed_cb_data() : canvas(0), graphic(0), gb_gene_data(0) {}
188    gene_container_changed_cb_data(AWT_canvas *canvas_, GEN_graphic *graphic_, GBDATA *gb_gene_data_)
189        : canvas(canvas_)
190        , graphic(graphic_)
191        , gb_gene_data(gb_gene_data_)
192    {}
193};
194
195static void GEN_gene_container_changed_cb(GBDATA */*gb_gene_data*/, int *cl_cb_data, GB_CB_TYPE /*gb_type*/) {
196    gene_container_changed_cb_data *cb_data = (gene_container_changed_cb_data*)cl_cb_data;
197    cb_data->graphic->reinit_gen_root(cb_data->canvas, true);
198    cb_data->canvas->refresh();
199}
200
201static void GEN_gene_container_cb_installer(bool install, AWT_canvas *gmw, GEN_graphic *gg) {
202    typedef map<GEN_graphic*, gene_container_changed_cb_data> callback_dict;
203    static callback_dict                                      installed_callbacks;
204
205    callback_dict::iterator found = installed_callbacks.find(gg);
206    if (found == installed_callbacks.end()) {
207        gen_assert(install); // if !install then entry has to exist!
208        installed_callbacks[gg] = gene_container_changed_cb_data(gmw, gg, 0);
209        found                   = installed_callbacks.find(gg);
210        gen_assert(found != installed_callbacks.end());
211    }
212
213    gene_container_changed_cb_data *curr_cb_data = &(found->second);
214
215    if (install) {
216        gen_assert(curr_cb_data->gb_gene_data == 0); // 0 means : no callback installed
217        GBDATA         *gb_main    = gg->get_gb_main();
218        GB_transaction  ta(gb_main);
219        curr_cb_data->gb_gene_data = GEN_get_current_gene_data(gb_main, gg->get_aw_root());
220        // @@@ FIXME: get data of local genome!
221
222        if (curr_cb_data->gb_gene_data) {
223            GB_add_callback(curr_cb_data->gb_gene_data, (GB_CB_TYPE)(GB_CB_DELETE|GB_CB_CHANGED), GEN_gene_container_changed_cb, (int*)curr_cb_data);
224        }
225    }
226    else {
227        if (curr_cb_data->gb_gene_data) { // if callback is installed
228            GB_remove_callback(curr_cb_data->gb_gene_data, (GB_CB_TYPE)(GB_CB_DELETE|GB_CB_CHANGED), GEN_gene_container_changed_cb, (int*)curr_cb_data);
229            curr_cb_data->gb_gene_data = 0;
230        }
231    }
232}
233
234void GEN_jump_cb(AW_window *aww, AW_CL cl_force_center_if_fits) {
235    GEN_map_window *win                  = dynamic_cast<GEN_map_window*>(aww);
236    bool            force_center_if_fits = (bool)cl_force_center_if_fits; // center gene if gene fits into display
237    gen_assert(win);
238
239    AW_rectangle  screen;       // screen coordinates
240    AW_device    *device = win->get_graphic()->get_device();
241    device->get_area_size(&screen);
242#if defined(DEBUG)
243    printf("Window %i: screen is: %i/%i -> %i/%i\n", win->get_nr(), screen.l, screen.t, screen.r, screen.b);
244#endif // DEBUG
245
246    const GEN_root *gen_root = win->get_graphic()->get_gen_root();
247    if (gen_root) {
248        const AW_world& wrange = gen_root->get_selected_range();
249#if defined(DEBUG)
250        printf("Window %i: Draw world range of selected gene is: %f/%f -> %f/%f\n", win->get_nr(), wrange.l, wrange.t, wrange.r, wrange.b);
251#endif // DEBUG
252
253        AW_rectangle srange;
254        device->transform(int(wrange.l), int(wrange.t), srange.l, srange.t);
255        device->transform(int(wrange.r), int(wrange.b), srange.r, srange.b);
256#if defined(DEBUG)
257        printf("Window %i: Draw screen range of selected gene is: %i/%i -> %i/%i\n", win->get_nr(), srange.l, srange.t, srange.r, srange.b);
258#endif // DEBUG
259
260        // add padding :
261        // srange.t -= 2; srange.b += 2;
262        // srange.l -= 2; srange.r += 2;
263
264        AWT_canvas *canvas  = win->get_canvas();
265        int         scrollx = 0;
266        int         scrolly = 0;
267
268        if (srange.t < 0) {
269            scrolly = srange.t-2;
270        }
271        else if (srange.b > screen.b) {
272            scrolly = (srange.b-screen.b)+2;
273            // if (srange.t < scrolly) scrolly = srange.t; // avoid scrolling out top side of gene
274        }
275        if (srange.l < 0) {
276            scrollx = srange.l-2;
277        }
278        else if (srange.r > screen.r) {
279            scrollx = srange.r-screen.r+2;
280            // if (srange.l < scrollx) scrollx = srange.l; // avoid scrolling out left side of gene
281        }
282
283        if (force_center_if_fits) {
284            if (!scrollx) { // no scrolling needed, i.e. gene fits onto display horizontally
285                int gene_center_x   = (srange.l+srange.r)/2;
286                int screen_center_x = (screen.l+screen.r)/2;
287                scrollx             = gene_center_x-screen_center_x;
288#if defined(DEBUG)
289                printf("center x\n");
290#endif // DEBUG
291            }
292            if (!scrolly) { // no scrolling needed, i.e. gene fits onto display vertically
293                int gene_center_y   = (srange.t+srange.b)/2;
294                int screen_center_y = (screen.t+screen.b)/2;
295                scrolly             = gene_center_y-screen_center_y;
296#if defined(DEBUG)
297                printf("center y\n");
298#endif // DEBUG
299            }
300        }
301
302#if defined(DEBUG)
303        printf("scroll %i/%i\n", scrollx, scrolly);
304#endif // DEBUG
305
306        canvas->scroll(aww, scrollx, scrolly);
307    }
308    win->get_canvas()->refresh();
309}
310
311void GEN_jump_cb_auto(AW_root *root, GEN_map_window *win, bool force_refresh) {
312    int jump = root->awar(AWAR_GENMAP_AUTO_JUMP)->read_int();
313    if (jump) {
314        win->get_canvas()->refresh(); // needed to recalculate position
315        GEN_jump_cb(win, (AW_CL)false);
316    }
317    else if (force_refresh) win->get_canvas()->refresh();
318}
319
320void GEN_local_organism_or_gene_name_changed_cb(AW_root *awr, AW_CL cl_win) {
321    GEN_map_window *win = (GEN_map_window*)cl_win;
322    win->get_graphic()->reinit_gen_root(win->get_canvas(), false);
323    GEN_jump_cb_auto(awr, win, true);
324}
325
326// void GEN_gene_name_changed_cb(AW_root *awr, AWT_canvas *gmw) {
327//     GEN_GRAPHIC->reinit_gen_root(gmw);
328//     GEN_jump_cb_auto(awr, gmw);
329//     gmw->refresh();
330// }
331
332static void GEN_map_window_zoom_reset_and_refresh(GEN_map_window *gmw) {
333    AWT_canvas *canvas = gmw->get_canvas();
334    canvas->zoom_reset();
335    canvas->refresh();
336}
337// static void GEN_map_window_refresh(GEN_map_window *gmw) {
338    // AWT_canvas *canvas = gmw->get_canvas();
339    // canvas->refresh();
340// }
341
342#define DISPLAY_TYPE_BIT(disp_type) (1<<(disp_type))
343#define ALL_DISPLAY_TYPES           (DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLES)-1)
344
345static void GEN_map_window_refresh_if_display_type(GEN_map_window *win, AW_CL cl_display_type_mask) {
346    int display_type_mask = int(cl_display_type_mask);
347    int my_display_type   = win->get_graphic()->get_display_style();
348
349    if (display_type_mask & DISPLAY_TYPE_BIT(my_display_type)) {
350        AWT_canvas *canvas = win->get_canvas();
351        canvas->refresh();
352    }
353}
354
355static void GEN_update_unlocked_organism_and_gene_awars(GEN_map_window *win, AW_CL cl_organism, AW_CL cl_gene) {
356    AW_root *aw_root   = win->get_graphic()->get_aw_root();
357    int      window_nr = win->get_nr();
358    if (!aw_root->awar(AWAR_LOCAL_ORGANISM_LOCK(window_nr))->read_int()) {
359        aw_root->awar(AWAR_LOCAL_ORGANISM_NAME(window_nr))->write_string((const char*)cl_organism);
360    }
361    if (!aw_root->awar(AWAR_LOCAL_GENE_LOCK(window_nr))->read_int()) {
362        aw_root->awar(AWAR_LOCAL_GENE_NAME(window_nr))->write_string((const char*)cl_gene);
363    }
364}
365
366static void GEN_organism_or_gene_changed_cb(AW_root *awr) {
367    char *organism = awr->awar(AWAR_ORGANISM_NAME)->read_string();
368    char *gene     = awr->awar(AWAR_GENE_NAME)->read_string();
369
370    GEN_map_manager::with_all_mapped_windows(GEN_update_unlocked_organism_and_gene_awars, (AW_CL)organism, (AW_CL)gene);
371
372    free(gene);
373    free(organism);
374}
375
376
377static void GEN_local_lock_changed_cb(AW_root *awr, AW_CL cl_win, AW_CL cl_what_lock) {
378    int             what_lock = (int)cl_what_lock;
379    GEN_map_window *win       = (GEN_map_window*)cl_win;
380    int             window_nr = win->get_nr();
381
382    const char *local_awar_name      = 0;
383    const char *local_lock_awar_name = 0;
384    const char *global_awar_name     = 0;
385
386    if (what_lock == 0) { // organism
387        local_awar_name      = AWAR_LOCAL_ORGANISM_NAME(window_nr);
388        local_lock_awar_name = AWAR_LOCAL_ORGANISM_LOCK(window_nr);
389        global_awar_name     = AWAR_ORGANISM_NAME;
390    }
391    else { // gene
392        local_awar_name      = AWAR_LOCAL_GENE_NAME(window_nr);
393        local_lock_awar_name = AWAR_LOCAL_GENE_LOCK(window_nr);
394        global_awar_name     = AWAR_GENE_NAME;
395    }
396
397    AW_awar *local_awar  = awr->awar(local_awar_name);
398    AW_awar *global_awar = awr->awar(global_awar_name);
399
400    int lock_value = awr->awar(local_lock_awar_name)->read_int();
401    if (lock_value == 0) { // lock has been removed -> map to global awar
402        local_awar->map(global_awar);
403    }
404    else { // lock has been installed -> unmap from global awar
405        local_awar->unmap();
406        char *content = global_awar->read_string();
407        local_awar->write_string(content);
408        free(content);
409    }
410}
411
412// ------------------------------------
413//      display parameter change cb
414// ------------------------------------
415
416static void GEN_display_param_changed_cb(AW_root */*awr*/, AW_CL cl_display_type_mask) {
417    GEN_map_manager::with_all_mapped_windows(GEN_map_window_refresh_if_display_type, cl_display_type_mask);
418}
419inline void set_display_update_callback(AW_root *awr, const char *awar_name, int display_type_mask) {
420    awr->awar(awar_name)->add_callback(GEN_display_param_changed_cb, AW_CL(display_type_mask));
421}
422
423// -------------------------
424//      View-local AWARS
425// -------------------------
426
427static void GEN_create_genemap_local_awars(AW_root *aw_root,AW_default /*def*/, int window_nr) {
428    // awars local to each view
429
430    aw_root->awar_int(AWAR_GENMAP_DISPLAY_TYPE(window_nr), GEN_DISPLAY_STYLE_RADIAL); // @@@ FIXME: make local
431
432    aw_root->awar_string(AWAR_LOCAL_ORGANISM_NAME(window_nr), "");
433    aw_root->awar_string(AWAR_LOCAL_GENE_NAME(window_nr), "");
434
435    aw_root->awar_int(AWAR_LOCAL_ORGANISM_LOCK(window_nr), 0);
436    aw_root->awar_int(AWAR_LOCAL_GENE_LOCK(window_nr), 0);
437}
438
439static void GEN_add_local_awar_callbacks(AW_root *awr,AW_default /*def*/, GEN_map_window *win) {
440    int window_nr = win->get_nr();
441
442    awr->awar(AWAR_LOCAL_ORGANISM_NAME(window_nr))->add_callback(GEN_local_organism_or_gene_name_changed_cb, (AW_CL)win);
443    awr->awar(AWAR_LOCAL_GENE_NAME(window_nr))->add_callback(GEN_local_organism_or_gene_name_changed_cb, (AW_CL)win);
444
445    // awr->awar(AWAR_LOCAL_ORGANISM_NAME(window_nr))->map(AWAR_ORGANISM_NAME);
446    // awr->awar(AWAR_LOCAL_GENE_NAME(window_nr))->map(AWAR_GENE_NAME);
447
448    AW_awar *awar_lock_organism = awr->awar(AWAR_LOCAL_ORGANISM_LOCK(window_nr));
449    AW_awar *awar_lock_gene     = awr->awar(AWAR_LOCAL_GENE_LOCK(window_nr));
450
451    awar_lock_organism->add_callback(GEN_local_lock_changed_cb, (AW_CL)win, (AW_CL)0);
452    awar_lock_gene->add_callback(GEN_local_lock_changed_cb, (AW_CL)win, (AW_CL)1);
453
454    awar_lock_organism->touch();
455    awar_lock_gene->touch();
456}
457
458// ---------------------
459//      global AWARS
460// ---------------------
461
462static void GEN_create_genemap_global_awars(AW_root *aw_root,AW_default def) {
463
464    // layout options:
465
466    aw_root->awar_int(AWAR_GENMAP_ARROW_SIZE, 150);
467    aw_root->awar_int(AWAR_GENMAP_SHOW_HIDDEN, 0);
468    aw_root->awar_int(AWAR_GENMAP_SHOW_ALL_NDS, 0);
469
470    aw_root->awar_int(AWAR_GENMAP_BOOK_BASES_PER_LINE, 15000);
471    aw_root->awar_float(AWAR_GENMAP_BOOK_WIDTH_FACTOR, 0.1);
472    aw_root->awar_int(AWAR_GENMAP_BOOK_LINE_HEIGHT, 20);
473    aw_root->awar_int(AWAR_GENMAP_BOOK_LINE_SPACE, 5);
474
475    aw_root->awar_float(AWAR_GENMAP_VERTICAL_FACTOR_X, 1.0);
476    aw_root->awar_float(AWAR_GENMAP_VERTICAL_FACTOR_Y, 0.3);
477
478    aw_root->awar_float(AWAR_GENMAP_RADIAL_INSIDE, 50);
479    aw_root->awar_float(AWAR_GENMAP_RADIAL_OUTSIDE, 4);
480
481    // other options:
482
483    aw_root->awar_int(AWAR_GENMAP_AUTO_JUMP, 1);
484
485    GEN_create_nds_vars(aw_root, def, GLOBAL_gb_main, GEN_NDS_changed);
486}
487
488static void GEN_add_global_awar_callbacks(AW_root *awr) {
489    set_display_update_callback(awr, AWAR_GENMAP_ARROW_SIZE,          ALL_DISPLAY_TYPES^DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_BOOK));
490    set_display_update_callback(awr, AWAR_GENMAP_SHOW_HIDDEN,         ALL_DISPLAY_TYPES);
491    set_display_update_callback(awr, AWAR_GENMAP_SHOW_ALL_NDS,        ALL_DISPLAY_TYPES);
492
493    set_display_update_callback(awr, AWAR_GENMAP_BOOK_BASES_PER_LINE, DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_BOOK));
494    set_display_update_callback(awr, AWAR_GENMAP_BOOK_WIDTH_FACTOR,   DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_BOOK));
495    set_display_update_callback(awr, AWAR_GENMAP_BOOK_LINE_HEIGHT,    DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_BOOK));
496    set_display_update_callback(awr, AWAR_GENMAP_BOOK_LINE_SPACE,     DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_BOOK));
497
498    set_display_update_callback(awr, AWAR_GENMAP_VERTICAL_FACTOR_X,   DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_VERTICAL));
499    set_display_update_callback(awr, AWAR_GENMAP_VERTICAL_FACTOR_Y,   DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_VERTICAL));
500
501    set_display_update_callback(awr, AWAR_GENMAP_RADIAL_INSIDE,       DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_RADIAL));
502    set_display_update_callback(awr, AWAR_GENMAP_RADIAL_OUTSIDE,      DISPLAY_TYPE_BIT(GEN_DISPLAY_STYLE_RADIAL));
503
504    awr->awar(AWAR_ORGANISM_NAME)->add_callback(GEN_organism_or_gene_changed_cb);
505    awr->awar(AWAR_GENE_NAME)->add_callback(GEN_organism_or_gene_changed_cb);
506}
507
508
509// --------------------------------------------------------------------------------
510
511void GEN_mode_event( AW_window *aws, AW_CL cl_win, AW_CL cl_mode) {
512    GEN_map_window   *win  = (GEN_map_window*)cl_win;
513    AWT_COMMAND_MODE  mode = (AWT_COMMAND_MODE)cl_mode;
514    const char       *text = 0;
515    switch (mode) {
516        case AWT_MODE_SELECT: {
517            text="SELECT MODE  LEFT: click to select";
518            break;
519        }
520        case AWT_MODE_ZOOM: {
521            text="ZOOM MODE    LEFT: drag to zoom   RIGHT: zoom out";
522            break;
523        }
524        case AWT_MODE_MOD: {
525            text="INFO MODE    LEFT: click for info";
526            break;
527        }
528        default: {
529            gen_assert(0);
530            break;
531        }
532    }
533
534    gen_assert(strlen(text) < AWAR_FOOTER_MAX_LEN); // text too long!
535
536    aws->get_root()->awar(AWAR_FOOTER)->write_string( text);
537    AWT_canvas *canvas = win->get_canvas();
538    canvas->set_mode(mode);
539    canvas->refresh();
540}
541
542void GEN_undo_cb(AW_window *, AW_CL undo_type) {
543    GB_ERROR error = GB_undo(GLOBAL_gb_main,(GB_UNDO_TYPE)undo_type);
544    if (error) {
545        aw_message(error);
546    }
547    else{
548        GB_begin_transaction(GLOBAL_gb_main);
549        GB_commit_transaction(GLOBAL_gb_main);
550        // ntw->refresh();
551    }
552}
553
554AW_window *GEN_create_options_window(AW_root *awr) {
555    static AW_window_simple *aws = 0;
556    if (!aws) {
557
558        aws = new AW_window_simple;
559        aws->init( awr, "GEN_OPTIONS", "GENE MAP OPTIONS");
560        aws->load_xfig("gene_options.fig");
561
562        aws->at("close");aws->callback((AW_CB0)AW_POPDOWN);
563        aws->create_button("CLOSE","CLOSE","C");
564
565        aws->at("help");aws->callback(AW_POPUP_HELP,(AW_CL)"gene_options.hlp");
566        aws->create_button("HELP","HELP","H");
567
568        aws->at("button");
569        aws->auto_space(10,10);
570        aws->label_length(30);
571
572        aws->label("Auto jump to selected gene");
573        aws->create_toggle(AWAR_GENMAP_AUTO_JUMP);
574        aws->at_newline();
575    }
576    return aws;
577}
578
579AW_window *GEN_create_layout_window(AW_root *awr) {
580    static AW_window_simple *aws = 0;
581
582    if (!aws) {
583        aws = new AW_window_simple;
584
585        aws->init(awr, "GENE_LAYOUT", "Gene Map Layout");
586        aws->load_xfig("gene_layout.fig");
587
588        aws->callback((AW_CB0)AW_POPDOWN);
589        aws->at("close");
590        aws->create_button("CLOSE", "CLOSE", "C");
591
592        aws->callback( AW_POPUP_HELP,(AW_CL)"gen_layout.hlp");
593        aws->at("help");
594        aws->create_button("HELP","HELP","H");
595
596        aws->at("base_pos");        aws->create_input_field(AWAR_GENMAP_BOOK_BASES_PER_LINE, 15);
597        aws->at("width_factor");    aws->create_input_field(AWAR_GENMAP_BOOK_WIDTH_FACTOR, 7);
598        aws->at("line_height");     aws->create_input_field(AWAR_GENMAP_BOOK_LINE_HEIGHT, 5);
599        aws->at("line_space");      aws->create_input_field(AWAR_GENMAP_BOOK_LINE_SPACE, 5);
600
601        aws->at("factor_x");        aws->create_input_field(AWAR_GENMAP_VERTICAL_FACTOR_X, 5);
602        aws->at("factor_y");        aws->create_input_field(AWAR_GENMAP_VERTICAL_FACTOR_Y, 5);
603
604        aws->at("inside");          aws->create_input_field(AWAR_GENMAP_RADIAL_INSIDE, 5);
605        aws->at("outside");         aws->create_input_field(AWAR_GENMAP_RADIAL_OUTSIDE, 5);
606
607        aws->at("arrow_size");      aws->create_input_field(AWAR_GENMAP_ARROW_SIZE, 5);
608
609        aws->at("show_hidden");
610        aws->label("Show hidden genes");
611        aws->create_toggle(AWAR_GENMAP_SHOW_HIDDEN);
612
613        aws->at("show_all");
614        aws->label("Show NDS for all genes");
615        aws->create_toggle(AWAR_GENMAP_SHOW_ALL_NDS);
616    }
617    return aws;
618}
619
620typedef enum  {
621    GEN_PERFORM_ALL_ORGANISMS,
622    GEN_PERFORM_CURRENT_ORGANISM,
623    GEN_PERFORM_ALL_BUT_CURRENT_ORGANISM,
624    GEN_PERFORM_MARKED_ORGANISMS, 
625
626    GEN_PERFORM_MODES, // counter
627} GEN_PERFORM_MODE;
628
629const char *GEN_PERFORM_MODE_id[GEN_PERFORM_MODES] = {
630    "org_all", 
631    "org_current", 
632    "org_butcur", 
633    "org_marked", 
634};
635
636inline string performmode_relative_id(const char *id, GEN_PERFORM_MODE pmode) {
637    return GBS_global_string("%s_%s", GEN_PERFORM_MODE_id[pmode], id);
638}
639
640typedef enum  {
641    GEN_MARK,
642    GEN_UNMARK,
643    GEN_INVERT_MARKED,
644    GEN_COUNT_MARKED,
645
646    //     GEN_MARK_COLORED,              done by awt_colorize_marked now
647    //     GEN_UNMARK_COLORED,
648    //     GEN_INVERT_COLORED,
649    //     GEN_COLORIZE_MARKED,
650
651    GEN_EXTRACT_MARKED,
652
653    GEN_MARK_HIDDEN,
654    GEN_MARK_VISIBLE,
655    GEN_UNMARK_HIDDEN,
656    GEN_UNMARK_VISIBLE
657} GEN_MARK_MODE;
658
659typedef enum  {
660    GEN_HIDE_ALL,
661    GEN_UNHIDE_ALL,
662    GEN_INVERT_HIDE_ALL,
663
664    GEN_HIDE_MARKED,
665    GEN_UNHIDE_MARKED,
666    GEN_INVERT_HIDE_MARKED
667} GEN_HIDE_MODE;
668
669// --------------------------------------------------------------------------------
670
671inline bool nameIsUnique(const char *short_name, GBDATA *gb_species_data) {
672    return GBT_find_species_rel_species_data(gb_species_data, short_name)==0;
673}
674
675static GB_ERROR GEN_species_add_entry(GBDATA *gb_pseudo, const char *key, const char *value) {
676    GB_ERROR  error = 0;
677    GB_clear_error();
678    GBDATA   *gbd   = GB_entry(gb_pseudo, key);
679
680    if (!gbd) { // key does not exist yet -> create
681        gbd             = GB_create(gb_pseudo, key, GB_STRING);
682        if (!gbd) error = GB_await_error();
683    }
684    else { // key exists
685        if (GB_read_type(gbd) != GB_STRING) { // test correct key type
686            error = GB_export_errorf("field '%s' exists and has wrong type", key);
687        }
688    }
689
690    if (!error) error = GB_write_string(gbd, value);
691
692    return error;
693}
694
695static AW_repeated_question *ask_about_existing_gene_species = 0;
696static AW_repeated_question *ask_to_overwrite_alignment      = 0;
697
698struct EG2PS_data {
699    // used for status:
700    int count;
701    int marked_genes;
702   
703    GBDATA             *gb_species_data;
704    char               *ali;
705    UniqueNameDetector  existing;
706    GB_HASH            *pseudo_hash;
707
708    int  duplicateSpecies;      // counts created gene-species with identical ACC
709    bool nameProblem;           // nameserver and DB disagree about names
710
711    EG2PS_data(const char *ali_, GBDATA *gb_species_data_, int marked_genes_)
712        : count(0)
713        , marked_genes(marked_genes_)
714        , gb_species_data(gb_species_data_)
715        , ali(strdup(ali_))
716        , existing(gb_species_data, marked_genes)
717        , duplicateSpecies(0)
718        , nameProblem(false)
719    {
720        pseudo_hash = GEN_create_pseudo_species_hash(GB_get_root(gb_species_data), marked_genes);
721    }
722
723    ~EG2PS_data() {
724        if (duplicateSpecies>0) {
725            aw_message(GBS_global_string("There are %i duplicated gene-species (with identical sequence and accession number)\n"
726                                         "Duplicated gene-species got names with numerical postfixes ('.1', '.2', ...)"
727                                         , duplicateSpecies));
728        }
729        if (nameProblem) {
730            aw_message("Naming problems occurred.\nYou have to call 'Generate new names'!");
731        }
732        GBS_free_hash(pseudo_hash);
733        free(ali);
734    }
735};
736
737static const char* readACC(GBDATA *gb_species_data, const char *name) {
738    const char *other_acc    = 0;
739    GBDATA *gb_other_species = GBT_find_species_rel_species_data(gb_species_data, name);
740    if (gb_other_species) {
741        GBDATA *gb_other_acc = GB_entry(gb_other_species, "acc");
742        if (gb_other_acc) other_acc = GB_read_char_pntr(gb_other_acc);
743    }
744    return other_acc;
745}
746
747static void gen_extract_gene_2_pseudoSpecies(GBDATA *gb_species, GBDATA *gb_gene, EG2PS_data *eg2ps) {
748    const char *gene_name         = GBT_read_name(gb_gene);
749    const char *species_name      = GBT_read_name(gb_species);
750    const char *full_species_name = GBT_read_char_pntr(gb_species, "full_name");
751
752    if (!full_species_name) full_species_name = species_name;
753
754    char     *full_name = GBS_global_string_copy("%s [%s]", full_species_name, gene_name);
755    char     *sequence  = GBT_read_gene_sequence(gb_gene, GB_TRUE, 0);
756    GB_ERROR  error     = 0;
757
758    if (!sequence) error = GB_await_error();
759    else {
760        const char *ali = eg2ps->ali;
761        long        id  = GBS_checksum(sequence, 1, ".-");
762        char        acc[100];
763
764        sprintf(acc, "ARB_GENE_%lX", id);
765
766        // test if this gene has been already extracted to a gene-species
767
768        GBDATA   *gb_exist_geneSpec       = GEN_find_pseudo_species(GLOBAL_gb_main, species_name, gene_name, eg2ps->pseudo_hash);
769        bool      create_new_gene_species = true;
770        char     *short_name              = 0;
771
772        if (gb_exist_geneSpec) {
773            const char *existing_name = GBT_read_name(gb_exist_geneSpec);
774
775            gen_assert(ask_about_existing_gene_species);
776            gen_assert(ask_to_overwrite_alignment);
777
778            char *question = GBS_global_string_copy("Already have a gene-species for %s/%s ('%s')", species_name, gene_name, existing_name);
779            int   answer   = ask_about_existing_gene_species->get_answer(question, "Overwrite species,Insert new alignment,Skip,Create new", "all", true);
780
781            create_new_gene_species = false;
782
783            switch (answer) {
784                case 0: {   // Overwrite species
785                    // @@@ FIXME:  delete species needed here
786                    create_new_gene_species = true;
787                    short_name              = strdup(existing_name);
788                    break;
789                }
790                case 1: {     // Insert new alignment or overwrite alignment
791                    GBDATA     *gb_ali = GB_entry(gb_exist_geneSpec, ali);
792                    if (gb_ali) { // the alignment already exists
793                        char *question2        = GBS_global_string_copy("Gene-species '%s' already has data in '%s'", existing_name, ali);
794                        int   overwrite_answer = ask_to_overwrite_alignment->get_answer(question2, "Overwrite data,Skip", "all", true);
795
796                        if (overwrite_answer == 1) error      = GBS_global_string("Skipped gene-species '%s' (already had data in alignment)", existing_name); // Skip
797                        else if (overwrite_answer == 2) error = "Aborted."; // Abort
798                        // @@@ FIXME: overwrite data is missing
799
800                        free(question2);
801                    }
802                    break;
803                }
804                case 2: {       // Skip existing ones
805                    error = GBS_global_string("Skipped gene-species '%s'", existing_name);
806                    break;
807                }
808                case 3: {   // Create with new name
809                    create_new_gene_species = true;
810                    break;
811                }
812                case 4: {   // Abort
813                    error = "Aborted.";
814                    break;
815                }
816                default : gen_assert(0);
817            }
818            free(question);
819        }
820
821        if (!error) {
822            if (create_new_gene_species) {
823                if (!short_name) { // create a new name
824                    error = AWTC_generate_one_name(GLOBAL_gb_main, full_name, acc, 0, short_name, false, false);
825                    if (!error) { // name has been created
826                        if (eg2ps->existing.name_known(short_name)) { // nameserver-generated name is already in use
827                            const char *other_acc    = readACC(eg2ps->gb_species_data, short_name);
828                            if (other_acc) {
829                                if (strcmp(acc, other_acc) == 0) { // duplicate (gene-)species -> generate postfixed name
830                                    char *newName = 0;
831                                    for (int postfix = 1; ; ++postfix) {
832                                        newName = GBS_global_string_copy("%s.%i", short_name, postfix);
833                                        if (!eg2ps->existing.name_known(newName)) {
834                                            eg2ps->duplicateSpecies++;
835                                            break;
836                                        }
837
838                                        other_acc = readACC(eg2ps->gb_species_data, newName);
839                                        if (!other_acc || strcmp(acc, other_acc) != 0) {
840                                            eg2ps->nameProblem = true;
841                                            error              = GBS_global_string("Unexpected acc-mismatch for '%s'", newName);
842                                            break;
843                                        }
844                                    }
845
846                                    if (!error) freeset(short_name, newName);
847                                    else free(newName);
848                                }
849                                else { // different acc, but uses name generated by nameserver
850                                    eg2ps->nameProblem = true;
851                                    error              = GBS_global_string("acc of '%s' differs from acc stored in nameserver", short_name);
852                                }
853                            }
854                            else { // can't detect acc of existing species
855                                eg2ps->nameProblem = true;
856                                error       = GBS_global_string("can't detect acc of species '%s'", short_name);
857                            }
858                        }
859                    }
860                    if (error) {            // try to make a random name
861                        const char *msg = GBS_global_string("%s\nGenerating a random name instead.", error);
862                        aw_message(msg);
863                        error      = 0;
864
865                        short_name = AWTC_generate_random_name(eg2ps->existing);
866                        if (!short_name) error = GBS_global_string("Failed to create a new name for pseudo gene-species '%s'", full_name);
867                    }
868                }
869
870                if (!error) { // create the species
871                    gen_assert(short_name);
872                    gb_exist_geneSpec = GBT_find_or_create_species(GLOBAL_gb_main, short_name);
873                    if (!gb_exist_geneSpec) error = GB_export_errorf("Failed to create pseudo-species '%s'", short_name);
874                    else eg2ps->existing.add_name(short_name);
875                }
876            }
877            else {
878                gen_assert(gb_exist_geneSpec); // do not generate new or skip -> should only occur when gene-species already existed
879            }
880
881            if (!error) { // write sequence data
882                GBDATA *gb_data     = GBT_add_data(gb_exist_geneSpec, ali, "data", GB_STRING);
883                if (!gb_data) error = GB_await_error();
884                else {
885                    size_t sequence_length = strlen(sequence);
886                    error                  = GBT_write_sequence(gb_data, ali, sequence_length, sequence);
887                }
888            }
889
890            // write other entries:
891            if (!error) error = GEN_species_add_entry(gb_exist_geneSpec, "full_name", full_name);
892            if (!error) error = GEN_species_add_entry(gb_exist_geneSpec, "ARB_origin_species", species_name);
893            if (!error) error = GEN_species_add_entry(gb_exist_geneSpec, "ARB_origin_gene", gene_name);
894            if (!error) GEN_add_pseudo_species_to_hash(gb_exist_geneSpec, eg2ps->pseudo_hash);
895            if (!error) error = GEN_species_add_entry(gb_exist_geneSpec, "acc", acc);
896
897            // copy codon_start and transl_table :
898            const char *codon_start  = 0;
899            const char *transl_table = 0;
900
901            {
902                GBDATA *gb_codon_start  = GB_entry(gb_gene, "codon_start");
903                GBDATA *gb_transl_table = GB_entry(gb_gene, "transl_table");
904
905                if (gb_codon_start)  codon_start  = GB_read_char_pntr(gb_codon_start);
906                if (gb_transl_table) transl_table = GB_read_char_pntr(gb_transl_table);
907            }
908
909            if (!error && codon_start)  error = GEN_species_add_entry(gb_exist_geneSpec, "codon_start", codon_start);
910            if (!error && transl_table) error = GEN_species_add_entry(gb_exist_geneSpec, "transl_table", transl_table);
911        }
912
913        free(short_name);
914        free(sequence);
915    }
916    if (error) aw_message(error);
917
918    free(full_name);
919}
920
921static long gen_count_marked_genes = 0; // used to count marked genes
922
923static void do_mark_command_for_one_species(int imode, GBDATA *gb_species, AW_CL cl_user) {
924    GEN_MARK_MODE mode  = (GEN_MARK_MODE)imode;
925    GB_ERROR      error = 0;
926
927    for (GBDATA *gb_gene = GEN_first_gene(gb_species);
928         !error && gb_gene;
929         gb_gene = GEN_next_gene(gb_gene))
930    {
931        bool mark_flag     = GB_read_flag(gb_gene) != 0;
932        bool org_mark_flag = mark_flag;
933        //         int wantedColor;
934
935        switch (mode) {
936            case GEN_MARK:              mark_flag = 1; break;
937            case GEN_UNMARK:            mark_flag = 0; break;
938            case GEN_INVERT_MARKED:     mark_flag = !mark_flag; break;
939
940            case GEN_COUNT_MARKED:     {
941                if (mark_flag) ++gen_count_marked_genes;
942                break;
943            }
944            case GEN_EXTRACT_MARKED: {
945                if (mark_flag) {
946                    EG2PS_data *eg2ps = (EG2PS_data*)cl_user;
947                    gen_extract_gene_2_pseudoSpecies(gb_species, gb_gene, eg2ps);
948                    if ((++eg2ps->count)%10 == 0) {
949                        aw_status(eg2ps->count/double(eg2ps->marked_genes));
950                    }
951                }
952                break;
953            }
954                //             case GEN_COLORIZE_MARKED:  {
955                //                 if (mark_flag) error = AW_set_color_group(gb_gene, wantedColor);
956                //                 break;
957                //             }
958            default: {
959                GBDATA *gb_hidden = GB_entry(gb_gene, ARB_HIDDEN);
960                bool    hidden    = gb_hidden ? GB_read_byte(gb_hidden) != 0 : false;
961                //                 long    myColor   = AW_find_color_group(gb_gene, true);
962
963                switch (mode) {
964                    //                     case GEN_MARK_COLORED:      if (myColor == wantedColor) mark_flag = 1; break;
965                    //                     case GEN_UNMARK_COLORED:    if (myColor == wantedColor) mark_flag = 0; break;
966                    //                     case GEN_INVERT_COLORED:    if (myColor == wantedColor) mark_flag = !mark_flag; break;
967
968                    case GEN_MARK_HIDDEN:       if (hidden) mark_flag = 1; break;
969                    case GEN_UNMARK_HIDDEN:     if (hidden) mark_flag = 0; break;
970                    case GEN_MARK_VISIBLE:      if (!hidden) mark_flag = 1; break;
971                    case GEN_UNMARK_VISIBLE:    if (!hidden) mark_flag = 0; break;
972                    default: gen_assert(0); break;
973                }
974            }
975        }
976
977        if (mark_flag != org_mark_flag) {
978            error = GB_write_flag(gb_gene, mark_flag?1:0);
979        }
980    }
981
982    if (error) aw_message(error);
983}
984
985static void do_hide_command_for_one_species(int imode, GBDATA *gb_species, AW_CL /*cl_user*/) {
986    GEN_HIDE_MODE mode = (GEN_HIDE_MODE)imode;
987
988    for (GBDATA *gb_gene = GEN_first_gene(gb_species);
989         gb_gene;
990         gb_gene = GEN_next_gene(gb_gene))
991    {
992        bool marked = GB_read_flag(gb_gene) != 0;
993
994        GBDATA *gb_hidden  = GB_entry(gb_gene, ARB_HIDDEN);
995        bool    hidden     = gb_hidden ? (GB_read_byte(gb_hidden) != 0) : false;
996        bool    org_hidden = hidden;
997
998        switch (mode) {
999            case GEN_HIDE_ALL:              hidden = true; break;
1000            case GEN_UNHIDE_ALL:            hidden = false; break;
1001            case GEN_INVERT_HIDE_ALL:       hidden = !hidden; break;
1002            case GEN_HIDE_MARKED:           if (marked) hidden = true; break;
1003            case GEN_UNHIDE_MARKED:         if (marked) hidden = false; break;
1004            case GEN_INVERT_HIDE_MARKED:    if (marked) hidden = !hidden; break;
1005            default: gen_assert(0); break;
1006        }
1007
1008        if (hidden != org_hidden) {
1009            if (!gb_hidden) gb_hidden = GB_create(gb_gene, ARB_HIDDEN, GB_BYTE);
1010            GB_write_byte(gb_hidden, hidden ? 1 : 0); // change gene visibility
1011        }
1012    }
1013}
1014
1015static void  GEN_perform_command(AW_window *aww, GEN_PERFORM_MODE pmode,
1016                                 void (*do_command)(int cmode, GBDATA *gb_species, AW_CL cl_user), int mode, AW_CL cl_user) {
1017    GB_ERROR error = 0;
1018
1019    GB_begin_transaction(GLOBAL_gb_main);
1020
1021    switch (pmode) {
1022        case GEN_PERFORM_ALL_ORGANISMS: {
1023            for (GBDATA *gb_organism = GEN_first_organism(GLOBAL_gb_main);
1024                 gb_organism;
1025                 gb_organism = GEN_next_organism(gb_organism))
1026            {
1027                do_command(mode, gb_organism, cl_user);
1028            }
1029            break;
1030        }
1031        case GEN_PERFORM_MARKED_ORGANISMS: {
1032            for (GBDATA *gb_organism = GEN_first_marked_organism(GLOBAL_gb_main);
1033                 gb_organism;
1034                 gb_organism = GEN_next_marked_organism(gb_organism))
1035            {
1036                do_command(mode, gb_organism, cl_user);
1037            }
1038            break;
1039        }
1040        case GEN_PERFORM_ALL_BUT_CURRENT_ORGANISM: {
1041            AW_root *aw_root          = aww->get_root();
1042            GBDATA  *gb_curr_organism = GEN_get_current_organism(GLOBAL_gb_main, aw_root);
1043
1044            for (GBDATA *gb_organism = GEN_first_organism(GLOBAL_gb_main);
1045                 gb_organism;
1046                 gb_organism = GEN_next_organism(gb_organism))
1047            {
1048                if (gb_organism != gb_curr_organism) do_command(mode, gb_organism, cl_user);
1049            }
1050            break;
1051        }
1052        case GEN_PERFORM_CURRENT_ORGANISM: {
1053            AW_root *aw_root     = aww->get_root();
1054            GBDATA  *gb_organism = GEN_get_current_organism(GLOBAL_gb_main, aw_root);
1055
1056            if (!gb_organism) {
1057                error = "First you have to select a species.";
1058            }
1059            else {
1060                do_command(mode, gb_organism, cl_user);
1061            }
1062            break;
1063        }
1064        default: {
1065            gen_assert(0);
1066            break;
1067        }
1068    }
1069
1070    GB_end_transaction_show_error(GLOBAL_gb_main, error, aw_message);
1071}
1072
1073static void GEN_hide_command(AW_window *aww, AW_CL cl_pmode, AW_CL cl_hmode) {
1074    GEN_perform_command(aww, (GEN_PERFORM_MODE)cl_pmode, do_hide_command_for_one_species, cl_hmode, 0);
1075}
1076static void GEN_mark_command(AW_window *aww, AW_CL cl_pmode, AW_CL cl_mmode) {
1077    gen_count_marked_genes = 0;
1078    GEN_perform_command(aww, (GEN_PERFORM_MODE)cl_pmode, do_mark_command_for_one_species, cl_mmode, 0);
1079
1080    if ((GEN_MARK_MODE)cl_mmode == GEN_COUNT_MARKED) {
1081        const char *where = 0;
1082
1083        switch ((GEN_PERFORM_MODE)cl_pmode) {
1084            case GEN_PERFORM_CURRENT_ORGANISM:         where = "the current species"; break;
1085            case GEN_PERFORM_MARKED_ORGANISMS:         where = "all marked species"; break;
1086            case GEN_PERFORM_ALL_ORGANISMS:            where = "all species"; break;
1087            case GEN_PERFORM_ALL_BUT_CURRENT_ORGANISM: where = "all but the current species"; break;
1088            default: gen_assert(0); break;
1089        }
1090        aw_message(GBS_global_string("There are %li marked genes in %s", gen_count_marked_genes, where));
1091    }
1092}
1093
1094void gene_extract_cb(AW_window *aww, AW_CL cl_pmode){
1095    char     *ali   = aww->get_root()->awar(AWAR_GENE_EXTRACT_ALI)->read_string();
1096    GB_ERROR  error = GBT_check_alignment_name(ali);
1097
1098    if (!error) {
1099        GB_transaction  dummy(GLOBAL_gb_main);
1100        GBDATA         *gb_ali = GBT_get_alignment(GLOBAL_gb_main, ali);
1101
1102        if (!gb_ali && !GBT_create_alignment(GLOBAL_gb_main,ali,0,0,0,"dna")) {
1103            error = GB_await_error();
1104        }
1105    }
1106
1107    if (error) {
1108        aw_message(error);
1109    }
1110    else {
1111        ask_about_existing_gene_species = new AW_repeated_question();
1112        ask_to_overwrite_alignment      = new AW_repeated_question();
1113
1114        aw_openstatus("Extracting pseudo-species");
1115        {
1116            EG2PS_data *eg2ps = 0;
1117            {
1118                gen_count_marked_genes = 0;
1119                GEN_perform_command(aww, (GEN_PERFORM_MODE)cl_pmode, do_mark_command_for_one_species, GEN_COUNT_MARKED, 0);
1120               
1121                GB_transaction  ta(GLOBAL_gb_main);
1122                GBDATA         *gb_species_data = GB_search(GLOBAL_gb_main, "species_data",  GB_CREATE_CONTAINER);
1123                eg2ps                           = new EG2PS_data(ali, gb_species_data, gen_count_marked_genes);
1124            }
1125
1126            PersistantNameServerConnection stayAlive;
1127
1128            GEN_perform_command(aww, (GEN_PERFORM_MODE)cl_pmode, do_mark_command_for_one_species, GEN_EXTRACT_MARKED, (AW_CL)eg2ps);
1129            delete eg2ps;
1130        }
1131        aw_closestatus();
1132
1133        delete ask_to_overwrite_alignment;
1134        delete ask_about_existing_gene_species;
1135        ask_to_overwrite_alignment      = 0;
1136        ask_about_existing_gene_species = 0;
1137    }
1138    free(ali);
1139}
1140
1141#if 0 // currently unused
1142GBDATA *GEN_find_pseudo(GBDATA *gb_organism, GBDATA *gb_gene) {
1143    // Warning : This functions is very SLOW!
1144
1145    GBDATA     *gb_species_data = GB_get_father(gb_organism);
1146    const char *organism_name   = GBT_read_name(gb_organism);
1147    const char *gene_name       = GBT_read_name(gb_gene);
1148    GBDATA     *gb_pseudo       = 0;
1149
1150    for (GBDATA *gb_species = GBT_first_species_rel_species_data(gb_species_data);
1151         gb_species;
1152         gb_species = GBT_next_species(gb_species))
1153    {
1154        const char *this_organism_name = GEN_origin_organism(gb_species);
1155
1156        if (this_organism_name && strcmp(this_organism_name, organism_name) == 0)
1157        {
1158            if (strcmp(GEN_origin_gene(gb_species), gene_name) == 0)
1159            {
1160                gb_pseudo = gb_species;
1161                break;
1162            }
1163        }
1164    }
1165
1166    return gb_pseudo;
1167}
1168#endif
1169
1170static void mark_organisms(AW_window */*aww*/, AW_CL cl_mark, AW_CL cl_canvas) {
1171    // cl_mark == 0 -> unmark
1172    // cl_mark == 1 -> mark
1173    // cl_mark == 2 -> invert mark
1174    // cl_mark == 3 -> mark organisms, unmark rest
1175    GB_transaction dummy(GLOBAL_gb_main);
1176    int            mark = (int)cl_mark;
1177
1178    if (mark == 3) {
1179        GBT_mark_all(GLOBAL_gb_main, 0); // unmark all species
1180        mark = 1;
1181    }
1182
1183    for (GBDATA *gb_org = GEN_first_organism(GLOBAL_gb_main);
1184         gb_org;
1185         gb_org = GEN_next_organism(gb_org))
1186    {
1187        if (mark == 2) {
1188            GB_write_flag(gb_org, !GB_read_flag(gb_org)); // invert mark of organism
1189        }
1190        else {
1191            GB_write_flag(gb_org, mark); // mark/unmark organism
1192        }
1193    }
1194
1195    AWT_canvas *canvas = (AWT_canvas*)cl_canvas;
1196    if (canvas) canvas->refresh();
1197}
1198
1199
1200static void mark_gene_species(AW_window */*aww*/, AW_CL cl_mark, AW_CL cl_canvas) {
1201    //  cl_mark == 0 -> unmark
1202    //  cl_mark == 1 -> mark
1203    //  cl_mark == 2 -> invert mark
1204    //  cl_mark == 3 -> mark gene-species, unmark rest
1205    GB_transaction dummy(GLOBAL_gb_main);
1206    int            mark = (int)cl_mark;
1207
1208    if (mark == 3) {
1209        GBT_mark_all(GLOBAL_gb_main, 0); // unmark all species
1210        mark = 1;
1211    }
1212
1213    for (GBDATA *gb_pseudo = GEN_first_pseudo_species(GLOBAL_gb_main);
1214         gb_pseudo;
1215         gb_pseudo = GEN_next_pseudo_species(gb_pseudo))
1216    {
1217        if (mark == 2) {
1218            GB_write_flag(gb_pseudo, !GB_read_flag(gb_pseudo)); // invert mark of pseudo-species
1219        }
1220        else {
1221            GB_write_flag(gb_pseudo, mark); // mark/unmark gene-species
1222        }
1223    }
1224
1225    AWT_canvas *canvas = (AWT_canvas*)cl_canvas;
1226    if (canvas) canvas->refresh();
1227}
1228
1229static void mark_gene_species_of_marked_genes(AW_window */*aww*/, AW_CL cl_canvas, AW_CL) {
1230    GB_transaction dummy(GLOBAL_gb_main);
1231
1232    GB_HASH *organism_hash = GBT_create_organism_hash(GLOBAL_gb_main);
1233   
1234    for (GBDATA *gb_pseudo = GEN_first_pseudo_species(GLOBAL_gb_main);
1235         gb_pseudo;
1236         gb_pseudo = GEN_next_pseudo_species(gb_pseudo))
1237    {
1238        GBDATA *gb_gene = GEN_find_origin_gene(gb_pseudo, organism_hash);
1239        if (GB_read_flag(gb_gene)) {
1240            GB_write_flag(gb_pseudo, 1); // mark pseudo
1241        }
1242    }
1243   
1244    GBS_free_hash(organism_hash);
1245    AWT_canvas *canvas = (AWT_canvas*)cl_canvas;
1246    if (canvas) canvas->refresh();
1247}
1248
1249
1250
1251static void mark_organisms_with_marked_genes(AW_window */*aww*/, AW_CL /*cl_canvas*/, AW_CL) {
1252    GB_transaction dummy(GLOBAL_gb_main);
1253
1254    for (GBDATA *gb_species = GEN_first_organism(GLOBAL_gb_main);
1255         gb_species;
1256         gb_species = GEN_next_organism(gb_species))
1257    {
1258        for (GBDATA *gb_gene = GEN_first_gene(gb_species);
1259             gb_gene;
1260             gb_gene = GEN_next_gene(gb_gene))
1261        {
1262            if (GB_read_flag(gb_gene)) {
1263                GB_write_flag(gb_species, 1);
1264                break; // continue with next organism
1265            }
1266        }
1267    }
1268}
1269static void mark_gene_species_using_current_alignment(AW_window */*aww*/, AW_CL /*cl_canvas*/, AW_CL) {
1270    GB_transaction  dummy(GLOBAL_gb_main);
1271    char           *ali = GBT_get_default_alignment(GLOBAL_gb_main);
1272
1273    for (GBDATA *gb_pseudo = GEN_first_pseudo_species(GLOBAL_gb_main);
1274         gb_pseudo;
1275         gb_pseudo = GEN_next_pseudo_species(gb_pseudo))
1276    {
1277        GBDATA *gb_ali = GB_entry(gb_pseudo, ali);
1278        if (gb_ali) {
1279            GBDATA *gb_data = GB_entry(gb_ali, "data");
1280            if (gb_data) {
1281                GB_write_flag(gb_pseudo, 1);
1282            }
1283        }
1284    }
1285}
1286static void mark_genes_of_marked_gene_species(AW_window */*aww*/, AW_CL, AW_CL) {
1287    GB_transaction  dummy(GLOBAL_gb_main);
1288    GB_HASH        *organism_hash = GBT_create_organism_hash(GLOBAL_gb_main);
1289
1290    for (GBDATA *gb_pseudo = GEN_first_pseudo_species(GLOBAL_gb_main);
1291         gb_pseudo;
1292         gb_pseudo = GEN_next_pseudo_species(gb_pseudo))
1293    {
1294        if (GB_read_flag(gb_pseudo)) {
1295            GBDATA *gb_gene = GEN_find_origin_gene(gb_pseudo, organism_hash);
1296            GB_write_flag(gb_gene, 1); // mark gene
1297        }
1298    }
1299
1300    GBS_free_hash(organism_hash);
1301}
1302
1303AW_window *create_gene_extract_window(AW_root *root, AW_CL cl_pmode)
1304{
1305    AW_window_simple *aws       = new AW_window_simple;
1306    string            window_id = performmode_relative_id("EXTRACT_GENE", GEN_PERFORM_MODE(cl_pmode));
1307
1308    aws->init(root, window_id.c_str(), "Extract genes to alignment");
1309    aws->load_xfig("ad_al_si.fig");
1310
1311    aws->callback( (AW_CB0)AW_POPDOWN);
1312    aws->at("close");
1313    aws->create_button("CLOSE","CLOSE","C");
1314
1315    aws->at("label");
1316    aws->create_autosize_button(0,"Please enter the name\nof the alignment to extract to");
1317
1318    aws->at("input");
1319    aws->create_input_field(AWAR_GENE_EXTRACT_ALI,15);
1320
1321    aws->at("ok");
1322    aws->callback(gene_extract_cb, cl_pmode);
1323
1324    aws->create_button("GO", "GO", "G");
1325
1326    return aws;
1327}
1328
1329#define AWMIMT awm->insert_menu_topic
1330
1331void GEN_insert_extract_submenu(AW_window_menu_modes *awm, const char *macro_prefix, const char *submenu_name, const char *hot_key, const char *help_file) {
1332    awm->insert_sub_menu(submenu_name, hot_key);
1333
1334    char macro_name_buffer[50];
1335
1336    sprintf(macro_name_buffer, "%s_of_current", macro_prefix);
1337    AWMIMT(macro_name_buffer, "of current species...", "c", help_file, AWM_ALL, AW_POPUP, (AW_CL)create_gene_extract_window, (AW_CL)GEN_PERFORM_CURRENT_ORGANISM);
1338
1339    sprintf(macro_name_buffer, "%s_of_marked", macro_prefix);
1340    AWMIMT(macro_name_buffer, "of marked species...", "m", help_file, AWM_ALL, AW_POPUP, (AW_CL)create_gene_extract_window, (AW_CL)GEN_PERFORM_MARKED_ORGANISMS);
1341
1342    sprintf(macro_name_buffer, "%s_of_all", macro_prefix);
1343    AWMIMT(macro_name_buffer, "of all species...", "a", help_file, AWM_ALL, AW_POPUP, (AW_CL)create_gene_extract_window, (AW_CL)GEN_PERFORM_ALL_ORGANISMS);
1344
1345    awm->close_sub_menu();
1346}
1347
1348void GEN_insert_multi_submenu(AW_window_menu_modes *awm, const char *macro_prefix, const char *submenu_name, const char *hot_key,
1349                              const char *help_file, void (*command)(AW_window*, AW_CL, AW_CL), AW_CL command_mode)
1350{
1351    awm->insert_sub_menu(submenu_name, hot_key);
1352
1353    char macro_name_buffer[50];
1354
1355    sprintf(macro_name_buffer, "%s_of_current", macro_prefix);
1356    AWMIMT(macro_name_buffer, "of current species", "c", help_file, AWM_ALL, command, GEN_PERFORM_CURRENT_ORGANISM, command_mode);
1357
1358    sprintf(macro_name_buffer, "%s_of_all_but_current", macro_prefix);
1359    AWMIMT(macro_name_buffer, "of all but current species", "b", help_file, AWM_ALL, command, GEN_PERFORM_ALL_BUT_CURRENT_ORGANISM, command_mode);
1360
1361    sprintf(macro_name_buffer, "%s_of_marked", macro_prefix);
1362    AWMIMT(macro_name_buffer, "of marked species", "m", help_file, AWM_ALL, command, GEN_PERFORM_MARKED_ORGANISMS, command_mode);
1363
1364    sprintf(macro_name_buffer, "%s_of_all", macro_prefix);
1365    AWMIMT(macro_name_buffer, "of all species", "a", help_file, AWM_ALL, command, GEN_PERFORM_ALL_ORGANISMS, command_mode);
1366
1367    awm->close_sub_menu();
1368}
1369void GEN_insert_mark_submenu(AW_window_menu_modes *awm, const char *macro_prefix, const char *submenu_name, const char *hot_key,
1370                             const char *help_file, GEN_MARK_MODE mark_mode)
1371{
1372    GEN_insert_multi_submenu(awm, macro_prefix, submenu_name, hot_key, help_file, GEN_mark_command, (AW_CL)mark_mode);
1373}
1374void GEN_insert_hide_submenu(AW_window_menu_modes *awm, const char *macro_prefix, const char *submenu_name, const char *hot_key,
1375                             const char *help_file, GEN_HIDE_MODE hide_mode) {
1376    GEN_insert_multi_submenu(awm, macro_prefix, submenu_name, hot_key, help_file, GEN_hide_command, (AW_CL)hide_mode);
1377}
1378
1379#if defined(DEBUG)
1380AW_window *GEN_create_awar_debug_window(AW_root *aw_root) {
1381    static AW_window_simple *aws = 0;
1382    if (!aws) {
1383        aws = new AW_window_simple;
1384
1385        aws->init(aw_root, "DEBUG_AWARS", "DEBUG AWARS");
1386        aws->at(10, 10);
1387        aws->auto_space(10,10);
1388
1389        const int width = 50;
1390
1391        ;                  aws->label("AWAR_SPECIES_NAME            "); aws->create_input_field(AWAR_SPECIES_NAME, width);
1392        aws->at_newline(); aws->label("AWAR_ORGANISM_NAME           "); aws->create_input_field(AWAR_ORGANISM_NAME, width);
1393        aws->at_newline(); aws->label("AWAR_GENE_NAME               "); aws->create_input_field(AWAR_GENE_NAME, width);
1394        aws->at_newline(); aws->label("AWAR_COMBINED_GENE_NAME      "); aws->create_input_field(AWAR_COMBINED_GENE_NAME, width);
1395        aws->at_newline(); aws->label("AWAR_EXPERIMENT_NAME         "); aws->create_input_field(AWAR_EXPERIMENT_NAME, width);
1396        aws->at_newline(); aws->label("AWAR_COMBINED_EXPERIMENT_NAME"); aws->create_input_field(AWAR_COMBINED_EXPERIMENT_NAME, width);
1397        aws->at_newline(); aws->label("AWAR_PROTEOM_NAME            "); aws->create_input_field(AWAR_PROTEOM_NAME, width);
1398        aws->at_newline(); aws->label("AWAR_PROTEIN_NAME            "); aws->create_input_field(AWAR_PROTEIN_NAME, width);
1399
1400        aws->window_fit();
1401    }
1402    return aws;
1403}
1404#endif // DEBUG
1405
1406// --------------------------
1407//      user mask section
1408// --------------------------
1409
1410class GEN_item_type_species_selector : public awt_item_type_selector {
1411public:
1412    GEN_item_type_species_selector() : awt_item_type_selector(AWT_IT_GENE) {}
1413    virtual ~GEN_item_type_species_selector() {}
1414
1415    virtual const char *get_self_awar() const {
1416        return AWAR_COMBINED_GENE_NAME;
1417    }
1418    virtual size_t get_self_awar_content_length() const {
1419        return 12 + 1 + 40; // species-name+'/'+gene_name
1420    }
1421    virtual void add_awar_callbacks(AW_root *root, void (*f)(AW_root*, AW_CL), AW_CL cl_mask) const { // add callbacks to awars
1422        root->awar(get_self_awar())->add_callback(f, cl_mask);
1423    }
1424    virtual void remove_awar_callbacks(AW_root *root, void (*f)(AW_root*, AW_CL), AW_CL cl_mask) const  {
1425        root->awar(get_self_awar())->remove_callback(f, cl_mask);
1426    }
1427    virtual GBDATA *current(AW_root *root) const { // give the current item
1428        char   *species_name = root->awar(AWAR_ORGANISM_NAME)->read_string();
1429        char   *gene_name   = root->awar(AWAR_GENE_NAME)->read_string();
1430        GBDATA *gb_gene      = 0;
1431
1432        if (species_name[0] && gene_name[0]) {
1433            GB_transaction dummy(GLOBAL_gb_main);
1434            GBDATA *gb_species = GBT_find_species(GLOBAL_gb_main,species_name);
1435            if (gb_species) {
1436                gb_gene = GEN_find_gene(gb_species, gene_name);
1437            }
1438        }
1439
1440        free(gene_name);
1441        free(species_name);
1442
1443        return gb_gene;
1444    }
1445    virtual const char *getKeyPath() const { // give the keypath for items
1446        return CHANGE_KEY_PATH_GENES;
1447    }
1448};
1449
1450static GEN_item_type_species_selector item_type_gene;
1451
1452static void GEN_open_mask_window(AW_window *aww, AW_CL cl_id, AW_CL) {
1453    int                              id         = int(cl_id);
1454    const awt_input_mask_descriptor *descriptor = AWT_look_input_mask(id);
1455    gen_assert(descriptor);
1456    if (descriptor) AWT_initialize_input_mask(aww->get_root(), GLOBAL_gb_main, &item_type_gene, descriptor->get_internal_maskname(), descriptor->is_local_mask());
1457}
1458
1459static void GEN_create_mask_submenu(AW_window_menu_modes *awm) {
1460    AWT_create_mask_submenu(awm, AWT_IT_GENE, GEN_open_mask_window);
1461}
1462
1463static AW_window *GEN_create_gene_colorize_window(AW_root *aw_root) {
1464    return awt_create_item_colorizer(aw_root, GLOBAL_gb_main, &GEN_item_selector);
1465}
1466
1467static AW_window *GEN_create_organism_colorize_window(AW_root *aw_root) {
1468    return awt_create_item_colorizer(aw_root, GLOBAL_gb_main, &AWT_organism_selector);
1469}
1470
1471// used to avoid that the organisms info window is stored in a menu (or with a button)
1472void GEN_popup_organism_window(AW_window *aww, AW_CL, AW_CL) {
1473    AW_window *aws = NT_create_organism_window(aww->get_root());
1474    aws->activate();
1475}
1476void GEN_create_organism_submenu(AW_window_menu_modes *awm, bool submenu/*, AWT_canvas *ntree_canvas*/) {
1477    const char *title  = "Organisms";
1478    const char *hotkey = "O";
1479
1480    if (submenu) awm->insert_sub_menu(title, hotkey);
1481    else awm->create_menu(title, hotkey, "no.hlp", AWM_ALL);
1482
1483    {
1484        AWMIMT( "organism_info", "Organism information", "i", "organism_info.hlp", AWM_ALL,GEN_popup_organism_window,  0, 0);
1485//         AWMIMT( "organism_info", "Organism information", "i", "organism_info.hlp", AWM_ALL,AW_POPUP,   (AW_CL)NT_create_organism_window,  0 );
1486
1487        awm->insert_separator();
1488
1489        AWMIMT("mark_organisms",             "Mark All organisms",              "A", "organism_mark.hlp", AWM_ALL, mark_organisms, 1, 0);
1490        AWMIMT("mark_organisms_unmark_rest", "Mark all organisms, unmark Rest", "R", "organism_mark.hlp", AWM_ALL, mark_organisms, 3, 0);
1491        AWMIMT("unmark_organisms",           "Unmark all organisms",            "U", "organism_mark.hlp", AWM_ALL, mark_organisms, 0, 0);
1492        AWMIMT("invmark_organisms",          "Invert marks of all organisms",   "v", "organism_mark.hlp", AWM_ALL, mark_organisms, 2, 0);
1493        awm->insert_separator();
1494        AWMIMT("mark_organisms_with_marked_genes", "Mark organisms with marked Genes", "G", "organism_mark.hlp", AWM_ALL, mark_organisms_with_marked_genes, 0, 0);
1495        awm->insert_separator();
1496        AWMIMT( "organism_colors",  "Colors ...",           "C",    "mark_colors.hlp", AWM_ALL,AW_POPUP,   (AW_CL)GEN_create_organism_colorize_window, 0);
1497    }
1498    if (submenu) awm->close_sub_menu();
1499}
1500
1501void GEN_create_gene_species_submenu(AW_window_menu_modes *awm, bool submenu/*, AWT_canvas *ntree_canvas*/) {
1502    const char *title  = "Gene-Species";
1503    const char *hotkey = "S";
1504
1505    if (submenu) awm->insert_sub_menu(title, hotkey);
1506    else awm->create_menu(title, hotkey, "no.hlp", AWM_ALL);
1507
1508    {
1509        AWMIMT("mark_gene_species",             "Mark All gene-species",              "A", "gene_species_mark.hlp", AWM_ALL, mark_gene_species, 1, 0);
1510        AWMIMT("mark_gene_species_unmark_rest", "Mark all gene-species, unmark Rest", "R", "gene_species_mark.hlp", AWM_ALL, mark_gene_species, 3, 0);
1511        AWMIMT("unmark_gene_species",           "Unmark all gene-species",            "U", "gene_species_mark.hlp", AWM_ALL, mark_gene_species, 0, 0);
1512        AWMIMT("invmark_gene_species",          "Invert marks of all gene-species",   "I", "gene_species_mark.hlp", AWM_ALL, mark_gene_species, 2, 0);
1513        awm->insert_separator();
1514        AWMIMT("mark_gene_species_of_marked_genes", "Mark gene-species of marked genes",             "M", "gene_species_mark.hlp", AWM_ALL, mark_gene_species_of_marked_genes,         0, 0);
1515        AWMIMT("mark_gene_species_curr_ali",        "Mark all gene-species using Current alignment", "C", "gene_species_mark.hlp", AWM_ALL, mark_gene_species_using_current_alignment, 0, 0);
1516    }
1517
1518    if (submenu) awm->close_sub_menu();
1519}
1520
1521struct GEN_update_info {
1522    AWT_canvas *canvas1;        // just canvasses of different windows (needed for updates)
1523    AWT_canvas *canvas2;
1524};
1525
1526void GEN_create_genes_submenu(AW_window_menu_modes *awm, bool for_ARB_NTREE/*, AWT_canvas *ntree_canvas*/) {
1527    // gen_assert(ntree_canvas != 0);
1528
1529    awm->create_menu("Genome", "G", "no.hlp",    AWM_ALL);
1530    {
1531#if defined(DEBUG)
1532        AWMIMT("debug_awars", "[DEBUG] Show main AWARs", "", "no.hlp", AWM_ALL, AW_POPUP, (AW_CL)GEN_create_awar_debug_window, 0);
1533        awm->insert_separator();
1534#endif // DEBUG
1535
1536        if (for_ARB_NTREE) {
1537            AWMIMT( "gene_map", "Gene Map", "p", "gene_map.hlp", AWM_ALL, AW_POPUP, (AW_CL)GEN_map_first, 0 /*(AW_CL)ntree_canvas*/); // initial gene map
1538            awm->insert_separator();
1539
1540            GEN_create_gene_species_submenu(awm, true); // Gene-species
1541            GEN_create_organism_submenu    (awm, true); // Organisms
1542            EXP_create_experiments_submenu (awm, true); // Experiments
1543            awm->insert_separator();
1544        }
1545
1546        AWMIMT("gene_info",   "Gene information", "i", "gene_info.hlp",   AWM_ALL, AW_POPUP, (AW_CL)GEN_create_gene_window,       0);
1547        AWMIMT("gene_search", "Search and Query", "Q", "gene_search.hlp", AWM_ALL, AW_POPUP, (AW_CL)GEN_create_gene_query_window, 0);
1548
1549        GEN_create_mask_submenu(awm);
1550
1551        awm->insert_separator();
1552
1553        GEN_insert_mark_submenu(awm, "gene_mark_all", "Mark all genes", "M", "gene_mark.hlp",  GEN_MARK);
1554        GEN_insert_mark_submenu(awm, "gene_unmark_all", "Unmark all genes", "U", "gene_mark.hlp", GEN_UNMARK);
1555        GEN_insert_mark_submenu(awm, "gene_invert_marked", "Invert marked genes", "v", "gene_mark.hlp", GEN_INVERT_MARKED);
1556        GEN_insert_mark_submenu(awm, "gene_count_marked", "Count marked genes", "C", "gene_mark.hlp", GEN_COUNT_MARKED);
1557
1558        AWMIMT( "gene_colors",  "Colors ...", "l",    "mark_colors.hlp", AWM_ALL,AW_POPUP,   (AW_CL)GEN_create_gene_colorize_window, 0);
1559
1560        awm->insert_separator();
1561
1562        AWMIMT("mark_genes_of_marked_gene_species", "Mark genes of marked gene-species", "g", "gene_mark.hlp", AWM_ALL, mark_genes_of_marked_gene_species, 0, 0);
1563
1564        awm->insert_separator();
1565
1566        GEN_insert_extract_submenu(awm, "gene_extract_marked", "Extract marked genes", "E", "gene_extract.hlp");
1567
1568        if (!for_ARB_NTREE) {   // only in ARB_GENE_MAP:
1569            awm->insert_separator();
1570            GEN_insert_mark_submenu(awm, "gene_mark_hidden", "Mark hidden genes", "", "gene_hide.hlp", GEN_MARK_HIDDEN);
1571            GEN_insert_mark_submenu(awm, "gene_mark_visible", "Mark visible genes", "", "gene_hide.hlp", GEN_MARK_VISIBLE);
1572
1573            awm->insert_separator();
1574            GEN_insert_mark_submenu(awm, "gene_unmark_hidden", "Unmark hidden genes", "", "gene_hide.hlp", GEN_UNMARK_HIDDEN);
1575            GEN_insert_mark_submenu(awm, "gene_unmark_visible", "Unmark visible genes", "", "gene_hide.hlp", GEN_UNMARK_VISIBLE);
1576        }
1577    }
1578}
1579
1580#undef AWMIMT
1581
1582void GEN_create_hide_submenu(AW_window_menu_modes *awm) {
1583    awm->create_menu("Hide","H","no.hlp", AWM_ALL);
1584    {
1585        GEN_insert_hide_submenu(awm, "gene_hide_marked", "Hide marked genes", "H", "gene_hide.hlp", GEN_HIDE_MARKED);
1586        GEN_insert_hide_submenu(awm, "gene_unhide_marked", "Unhide marked genes", "U", "gene_hide.hlp", GEN_UNHIDE_MARKED);
1587        GEN_insert_hide_submenu(awm, "gene_invhide_marked", "Invert-hide marked genes", "v", "gene_hide.hlp", GEN_INVERT_HIDE_MARKED);
1588
1589        awm->insert_separator();
1590        GEN_insert_hide_submenu(awm, "gene_hide_all", "Hide all genes", "", "gene_hide.hlp", GEN_HIDE_ALL);
1591        GEN_insert_hide_submenu(awm, "gene_unhide_all", "Unhide all genes", "", "gene_hide.hlp", GEN_UNHIDE_ALL);
1592        GEN_insert_hide_submenu(awm, "gene_invhide_all", "Invert-hide all genes", "", "gene_hide.hlp", GEN_INVERT_HIDE_ALL);
1593    }
1594}
1595
1596void GEN_set_display_style(AW_window *aww, AW_CL cl_style) {
1597    GEN_DisplayStyle  style = (GEN_DisplayStyle)cl_style;
1598    GEN_map_window   *win   = dynamic_cast<GEN_map_window*>(aww);
1599    gen_assert(win);
1600
1601    win->get_root()->awar(AWAR_GENMAP_DISPLAY_TYPE(win->get_nr()))->write_int(style);
1602    win->get_graphic()->set_display_style(style);
1603    GEN_map_window_zoom_reset_and_refresh(win);
1604}
1605
1606// ____________________________________________________________
1607// start of implementation of class GEN_map_window::
1608
1609void GEN_map_window::init(AW_root *awr) {
1610    {
1611        char *windowName = (window_nr == 0) ? strdup("ARB Gene Map") : GBS_global_string_copy("ARB Gene Map %i", window_nr);
1612        AW_window_menu_modes::init(awr, "ARB_GENE_MAP", windowName, 200, 200);
1613        free(windowName);
1614    }
1615
1616    GEN_create_genemap_local_awars(awr, AW_ROOT_DEFAULT, window_nr);
1617
1618    gen_graphic = new GEN_graphic(awr, GLOBAL_gb_main, GEN_gene_container_cb_installer, window_nr);
1619
1620    AW_gc_manager aw_gc_manager;
1621    gen_canvas = new AWT_canvas(GLOBAL_gb_main, this, gen_graphic, aw_gc_manager, AWAR_SPECIES_NAME);
1622
1623    GEN_add_local_awar_callbacks(awr, AW_ROOT_DEFAULT, this);
1624
1625    {
1626        GB_transaction ta(GLOBAL_gb_main);
1627        gen_graphic->reinit_gen_root(gen_canvas, false);
1628    }
1629
1630    gen_canvas->recalc_size();
1631    gen_canvas->refresh();
1632    gen_canvas->set_mode(AWT_MODE_SELECT); // Default-Mode
1633
1634    // --------------
1635    //      menus
1636    // --------------
1637
1638    // File Menu
1639    create_menu("File", "F", "no.hlp",  AWM_ALL );
1640    insert_menu_topic( "close", "Close", "C","quit.hlp", AWM_ALL, (AW_CB)AW_POPDOWN, 0, 0);
1641    insert_menu_topic( "new_view", "New view", "v","new_view.hlp", AWM_ALL, AW_POPUP, (AW_CL)GEN_map,(AW_CL)window_nr+1);
1642
1643    GEN_create_genes_submenu(this, false/*, ntree_canvas*/); // Genes
1644    GEN_create_gene_species_submenu(this, false/*, ntree_canvas*/); // Gene-species
1645    GEN_create_organism_submenu(this, false/*, ntree_canvas*/); // Organisms
1646
1647    EXP_create_experiments_submenu(this, false); // Experiments
1648
1649    GEN_create_hide_submenu(this); // Hide Menu
1650
1651    // Properties Menu
1652    create_menu("Properties","r","no.hlp", AWM_ALL);
1653    insert_menu_topic("gene_props_menu",   "Menu: Colors and Fonts ...",   "M","props_frame.hlp",  AWM_ALL, AW_POPUP, (AW_CL)AW_preset_window, 0 );
1654    // @@@ FIXME: replace AW_preset_window by local function returning same window for all mapped views
1655    insert_menu_topic("gene_props",        "GENEMAP: Colors and Fonts ...","C","gene_props_data.hlp",AWM_ALL, AW_POPUP, (AW_CL)AW_create_gc_window, (AW_CL)aw_gc_manager );
1656    // @@@ FIXME: replace AW_create_gc_window by local function returning same window for all mapped views
1657    insert_menu_topic("gene_layout",       "Layout",   "L", "gene_layout.hlp", AWM_ALL, AW_POPUP, (AW_CL)GEN_create_layout_window, 0);
1658    insert_menu_topic("gene_options",      "Options",  "O", "gene_options.hlp", AWM_ALL, AW_POPUP, (AW_CL)GEN_create_options_window, 0);
1659    insert_menu_topic("gene_nds",          "NDS ( Select Gene Information ) ...",      "N","props_nds.hlp",    AWM_ALL, AW_POPUP, (AW_CL)GEN_open_nds_window, (AW_CL)GLOBAL_gb_main );
1660    insert_menu_topic("gene_save_props",   "Save Defaults (in ~/.arb_prop/ntree.arb)", "D","savedef.hlp",  AWM_ALL, (AW_CB) AW_save_defaults, 0, 0 );
1661
1662    // ---------------------
1663    //      mode buttons
1664    // ---------------------
1665
1666    create_mode("select.bitmap", "gen_mode.hlp", AWM_ALL, GEN_mode_event, (AW_CL)this, (AW_CL)AWT_MODE_SELECT);
1667    create_mode("pzoom.bitmap",  "gen_mode.hlp", AWM_ALL, GEN_mode_event, (AW_CL)this, (AW_CL)AWT_MODE_ZOOM);
1668    create_mode("info.bitmap",   "gen_mode.hlp", AWM_ALL, GEN_mode_event, (AW_CL)this, (AW_CL)AWT_MODE_MOD);
1669
1670    // ------------------
1671    //      info area
1672    // ------------------
1673
1674    set_info_area_height( 250 );
1675    at(11,2);
1676    auto_space(2,-2);
1677    shadow_width(1);
1678
1679    // close + undo button, info area, define line y-positions:
1680
1681    int cur_x, cur_y, start_x, first_line_y, second_line_y, third_line_y;
1682    get_at_position( &start_x,&first_line_y);
1683    button_length(6);
1684
1685    at(start_x, first_line_y);
1686    help_text("quit.hlp");
1687    callback((AW_CB0)AW_POPDOWN);
1688    create_button("Close", "Close");
1689
1690    get_at_position( &cur_x,&cur_y );
1691
1692    int gene_x = cur_x;
1693    at_newline();
1694    get_at_position( &cur_x,&second_line_y);
1695
1696    at(start_x, second_line_y);
1697    help_text("undo.hlp");
1698    callback(GEN_undo_cb,(AW_CL)GB_UNDO_UNDO);
1699    create_button("Undo", "Undo");
1700
1701    at_newline();
1702    get_at_position( &cur_x,&third_line_y);
1703
1704    button_length(AWAR_FOOTER_MAX_LEN);
1705    create_button(0,AWAR_FOOTER);
1706
1707    at_newline();
1708    get_at_position( &cur_x,&cur_y );
1709    set_info_area_height( cur_y+6 );
1710
1711    // gene+species buttons:
1712    button_length(20);
1713
1714    at(gene_x, first_line_y);
1715    help_text("organism_search.hlp");
1716    callback( AW_POPUP, (AW_CL)ad_create_query_window, 0); // @@@ hier sollte eine Art "Organism-Search" verwendet werden (AWT_organism_selector anpassen)
1717    create_button("SEARCH_ORGANISM", AWAR_LOCAL_ORGANISM_NAME(window_nr));
1718
1719    at(gene_x, second_line_y);
1720    help_text("gene_search.hlp");
1721    callback( AW_POPUP, (AW_CL)GEN_create_gene_query_window, 0);
1722    create_button("SEARCH_GENE",AWAR_LOCAL_GENE_NAME(window_nr));
1723
1724    get_at_position( &cur_x,&cur_y );
1725    int lock_x = cur_x;
1726
1727    at(lock_x, first_line_y);
1728    create_toggle(AWAR_LOCAL_ORGANISM_LOCK(window_nr));
1729
1730    at(lock_x, second_line_y);
1731    create_toggle(AWAR_LOCAL_GENE_LOCK(window_nr));
1732
1733    get_at_position( &cur_x,&cur_y );
1734    int dtype_x1 = cur_x;
1735
1736    // display type buttons:
1737
1738    button_length(4);
1739
1740    at(dtype_x1, first_line_y);
1741    help_text("gen_disp_radial.hlp");
1742    callback(GEN_set_display_style,(AW_CL)GEN_DISPLAY_STYLE_RADIAL);
1743    create_button("RADIAL_DISPLAY_TYPE", "#gen_radial.bitmap",0);
1744
1745    help_text("gen_disp_book.hlp");
1746    callback(GEN_set_display_style,(AW_CL)GEN_DISPLAY_STYLE_BOOK);
1747    create_button("BOOK_DISPLAY_TYPE", "#gen_book.bitmap",0);
1748
1749    get_at_position( &cur_x,&cur_y );
1750    int jump_x = cur_x;
1751
1752    at(dtype_x1, second_line_y);
1753    help_text("gen_disp_vertical.hlp");
1754    callback(GEN_set_display_style,(AW_CL)GEN_DISPLAY_STYLE_VERTICAL);
1755    create_button("VERTICAL_DISPLAY_TYPE", "#gen_vertical.bitmap",0);
1756
1757    // jump button:
1758
1759    button_length(0);
1760
1761    at(jump_x, first_line_y);
1762    help_text("gen_jump.hlp");
1763    callback(GEN_jump_cb, (AW_CL)true);
1764    create_button("Jump", "Jump");
1765
1766    // help buttons:
1767
1768    get_at_position( &cur_x,&cur_y );
1769    int help_x = cur_x;
1770
1771    at(help_x, first_line_y);
1772    help_text("help.hlp");
1773    callback(AW_POPUP_HELP,(AW_CL)"gene_map.hlp");
1774    create_button("HELP", "HELP","H");
1775
1776    at(help_x, second_line_y);
1777    callback( AW_help_entry_pressed );
1778    create_button(0,"?");
1779
1780}
1781
1782// -end- of implementation of class GEN_map_window:.
1783
1784
1785AW_window *GEN_map(AW_root *aw_root, int window_number) {
1786    // window_number shall be 0 for first window (called from ARB_NTREE)
1787    // additional views are always created by the previous window created with GEN_map
1788
1789    GEN_map_manager *manager = 0;
1790    if (!GEN_map_manager::initialized()) { // first call
1791        gen_assert(window_number == 0); // has to be 0 for first call
1792
1793        GEN_map_manager::initialize(aw_root);
1794        manager = GEN_map_manager::get_map_manager(); // creates the manager
1795
1796        // global initialization (AWARS etc.) done here :
1797
1798        GEN_create_genemap_global_awars(aw_root, AW_ROOT_DEFAULT);
1799        GEN_add_global_awar_callbacks(aw_root);
1800        {
1801            GB_transaction dummy(GLOBAL_gb_main);
1802            GEN_make_node_text_init(GLOBAL_gb_main);
1803        }
1804    }
1805    else {
1806        manager = GEN_map_manager::get_map_manager();
1807    }
1808
1809    GEN_map_window *gmw = manager->get_map_window(window_number);
1810    return gmw;
1811
1812#if 0
1813    static AW_window *aw_gen = 0;
1814
1815    if (!aw_gen) {              // do not open window twice
1816        {
1817            GB_transaction dummy(gb_main);
1818            GEN_make_node_text_init(gb_main);
1819        }
1820
1821        aw_gen = GEN_map_create_main_window(aw_root, nt_canvas);
1822        if (!aw_gen) {
1823            aw_message("Couldn't start Gene-Map");
1824            return 0;
1825        }
1826
1827    }
1828
1829    aw_gen->show();
1830    return aw_gen;
1831#endif
1832}
1833
1834AW_window *GEN_map_first(AW_root *aw_root) {
1835    return GEN_map(aw_root, 0);
1836}
Note: See TracBrowser for help on using the repository browser.