source: tags/svn.1.5.4/GENOM/GEN_map.cxx

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