source: tags/cvs_2_svn/GENOM/GEN_map.cxx

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