source: tags/ms_r17q2/GENOM/EXP_interface.cxx

Last change on this file was 16021, checked in by westram, 7 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.9 KB
Line 
1//  ==================================================================== //
2//                                                                       //
3//    File      : EXP_interface.cxx                                      //
4//    Purpose   :                                                        //
5//                                                                       //
6//                                                                       //
7//  Coded by Ralf Westram (coder@reallysoft.de) in September 2001        //
8//  Copyright Department of Microbiology (Technical University Munich)   //
9//                                                                       //
10//  Visit our web site at: http://www.arb-home.de/                       //
11//                                                                       //
12//                                                                       //
13//  ==================================================================== //
14
15#include "EXP_local.hxx"
16#include "GEN_local.hxx"
17
18#include <db_query.h>
19#include <db_scanner.hxx>
20#include <dbui.h>
21#include <awt_sel_boxes.hxx>
22#include <item_sel_list.h>
23#include <aw_awar_defs.hxx>
24#include <aw_root.hxx>
25#include <aw_msg.hxx>
26#include <aw_question.hxx>
27#include <arbdbt.h>
28#include <info_window.h>
29
30using namespace std;
31
32#define AD_F_ALL AWM_ALL
33
34static GBDATA* EXP_get_current_experiment_data(GBDATA *gb_main, AW_root *aw_root) {
35    GBDATA *gb_species         = GEN_get_current_organism(gb_main, aw_root);
36    GBDATA *gb_experiment_data = 0;
37
38    if (gb_species) gb_experiment_data = EXP_get_experiment_data(gb_species);
39
40    return gb_experiment_data;
41}
42
43static void EXP_select_experiment(GBDATA* /* gb_main */, AW_root *aw_root, const char *item_name) {
44    char *name  = ARB_strdup(item_name);
45    char *slash = strchr(name, '/');
46
47    if (slash) {
48        slash[0] = 0;
49        aw_root->awar(AWAR_ORGANISM_NAME)->write_string(name);
50        aw_root->awar(AWAR_EXPERIMENT_NAME)->write_string(slash+1);
51    }
52    free(name);
53}
54
55static char *EXP_get_experiment_id(GBDATA * /* gb_main */, GBDATA *gb_experiment) {
56    GBDATA *gb_species = GB_get_grandfather(gb_experiment);
57    return GBS_global_string_copy("%s/%s", GBT_read_name(gb_species), GBT_read_name(gb_experiment));
58}
59
60static GBDATA *EXP_find_experiment_by_id(GBDATA *gb_main, const char *id) {
61    char   *organism = ARB_strdup(id);
62    char   *exp     = strchr(organism, '/');
63    GBDATA *result   = 0;
64
65    if (exp) {
66        *exp++ = 0;
67        GBDATA *gb_organism = GEN_find_organism(gb_main, organism);
68        if (gb_organism) {
69            result = EXP_find_experiment(gb_organism, exp);
70        }
71    }
72
73    free(organism);
74    return result;
75}
76
77static char *old_species_marks = 0; // configuration storing marked species
78
79inline void exp_restore_old_species_marks(GBDATA *gb_main) {
80    if (old_species_marks) {
81        GBT_restore_marked_species(gb_main, old_species_marks);
82        freenull(old_species_marks);
83    }
84}
85
86static GBDATA *EXP_get_first_experiment_data(GBDATA *gb_main, AW_root *aw_root, QUERY_RANGE range) {
87    GBDATA   *gb_organism = 0;
88    GB_ERROR  error      = 0;
89
90    gen_assert(!old_species_marks); // old_species_marks may be out of date (better call EXP_get_(first|next)_experiment_data until it returns NULL!)
91    exp_restore_old_species_marks(gb_main);
92
93    switch (range) {
94        case QUERY_CURRENT_ITEM: {
95            char *species_name = aw_root->awar(AWAR_ORGANISM_NAME)->read_string();
96            gb_organism         = GBT_find_species(gb_main, species_name);
97            free(species_name);
98            break;
99        }
100        case QUERY_MARKED_ITEMS: {
101            GBDATA *gb_pseudo = GEN_first_marked_pseudo_species(gb_main);
102
103            if (gb_pseudo) {    // there are marked pseudo-species..
104                old_species_marks = GBT_store_marked_species(gb_main, true); // store and unmark marked species
105                error             = GBT_with_stored_species(gb_main, old_species_marks, GEN_mark_organism_or_corresponding_organism, 0); // mark organisms related with stored
106
107                if (!error) {
108                    gb_organism = GEN_first_marked_organism(gb_main);
109                    if (!gb_organism) exp_restore_old_species_marks(gb_main); // got all -> clean up
110                }
111            }
112            else {
113                gb_organism = GEN_first_marked_organism(gb_main);
114            }
115            break;
116        }
117        case QUERY_ALL_ITEMS: {
118            gb_organism = GBT_first_species(gb_main);
119            break;
120        }
121        default: {
122            gen_assert(0);
123            break;
124        }
125    }
126
127    if (error) GB_export_error(error);
128    return gb_organism ? EXP_get_experiment_data(gb_organism) : 0;
129}
130
131static GBDATA *EXP_get_next_experiment_data(GBDATA *gb_experiment_data, QUERY_RANGE range) {
132    GBDATA *gb_organism = 0;
133    switch (range) {
134        case QUERY_CURRENT_ITEM: {
135            break;
136        }
137        case QUERY_MARKED_ITEMS: {
138            GBDATA *gb_last_species = GB_get_father(gb_experiment_data);
139            gb_organism             = GEN_next_marked_organism(gb_last_species);
140
141            if (!gb_organism) exp_restore_old_species_marks(GB_get_root(gb_experiment_data)); // got all -> clean up
142            break;
143        }
144        case QUERY_ALL_ITEMS: {
145            GBDATA *gb_last_species = GB_get_father(gb_experiment_data);
146            gb_organism             = GBT_next_species(gb_last_species);
147            break;
148        }
149        default: {
150            gen_assert(0);
151            break;
152        }
153    }
154
155    return gb_organism ? EXP_get_experiment_data(gb_organism) : 0;
156}
157
158static GBDATA *EXP_get_current_experiment(GBDATA *gb_main, AW_root *aw_root) {
159    GBDATA *gb_organism    = GEN_get_current_organism(gb_main, aw_root);
160    GBDATA *gb_experiment = 0;
161
162    if (gb_organism) {
163        char *experiment_name = aw_root->awar(AWAR_EXPERIMENT_NAME)->read_string();
164        gb_experiment         = EXP_find_experiment(gb_organism, experiment_name);
165        free(experiment_name);
166    }
167
168    return gb_experiment;
169}
170
171static void add_selected_experiment_changed_cb(AW_root *aw_root, const RootCallback& cb) {
172    aw_root->awar(AWAR_EXPERIMENT_NAME)->add_callback(cb);
173    ORGANISM_get_selector().add_selection_changed_cb(aw_root, cb);
174}
175
176static GBDATA *first_experiment_in_range(GBDATA *gb_experiment_data, QUERY_RANGE range) {
177    GBDATA *gb_first = NULL;
178    switch (range) {
179        case QUERY_ALL_ITEMS:    gb_first = EXP_first_experiment_rel_exp_data(gb_experiment_data); break;
180        case QUERY_MARKED_ITEMS: gb_first = GB_first_marked(gb_experiment_data, "experiment"); break;
181        case QUERY_CURRENT_ITEM: gb_first = EXP_get_current_experiment(GB_get_root(gb_experiment_data), AW_root::SINGLETON); break;
182    }
183    return gb_first;
184}
185static GBDATA *next_experiment_in_range(GBDATA *gb_prev, QUERY_RANGE range) {
186    GBDATA *gb_next = NULL;
187    switch (range) {
188        case QUERY_ALL_ITEMS:    gb_next = EXP_next_experiment(gb_prev); break;
189        case QUERY_MARKED_ITEMS: gb_next = GB_next_marked(gb_prev, "experiment"); break;
190        case QUERY_CURRENT_ITEM: gb_next = NULL; break;
191    }
192    return gb_next;
193}
194
195static void refresh_displayed_experiments() {} // nothing todo here
196
197#if defined(WARN_TODO)
198#warning move EXP_item_selector to SL/ITEMS
199#endif
200
201static struct MutableItemSelector EXP_item_selector = {
202    QUERY_ITEM_EXPERIMENTS,
203    EXP_select_experiment,
204    EXP_get_experiment_id,
205    EXP_find_experiment_by_id,
206    experiment_field_selection_list_update_cb,
207    -1, // unknown
208    CHANGE_KEY_PATH_EXPERIMENTS,
209    "experiment",
210    "experiments",
211    "name",
212    EXP_get_first_experiment_data,
213    EXP_get_next_experiment_data,
214    first_experiment_in_range,
215    next_experiment_in_range,
216    EXP_get_current_experiment,
217    add_selected_experiment_changed_cb,
218    &ORGANISM_get_selector(), GB_get_grandfather,
219    refresh_displayed_experiments,
220};
221
222ItemSelector& EXP_get_selector() { return EXP_item_selector; }
223
224static QUERY::DbQuery *GLOBAL_experiment_query = 0;
225
226#if defined(WARN_TODO)
227#warning move EXP_create_experiment_query_window to SL/DB_UI
228#endif
229
230AW_window *EXP_create_experiment_query_window(AW_root *aw_root, GBDATA *gb_main) {
231    static AW_window_simple_menu *aws = 0;
232    if (!aws) {
233        aws = new AW_window_simple_menu;
234        aws->init(aw_root, "EXPERIMENT_QUERY", "Experiment SEARCH and QUERY");
235        aws->create_menu("More functions", "f");
236        aws->load_xfig("ad_query.fig");
237
238        QUERY::query_spec awtqs(EXP_get_selector());
239
240        awtqs.gb_main             = gb_main;
241        awtqs.species_name        = AWAR_SPECIES_NAME;
242        awtqs.tree_name           = AWAR_TREE;
243        awtqs.select_bit          = GB_USERFLAG_QUERY;
244        awtqs.use_menu            = 1;
245        awtqs.ere_pos_fig         = "ere3";
246        awtqs.where_pos_fig       = "where3";
247        awtqs.by_pos_fig          = "by3";
248        awtqs.qbox_pos_fig        = "qbox";
249        awtqs.key_pos_fig         = 0;
250        awtqs.query_pos_fig       = "content";
251        awtqs.result_pos_fig      = "result";
252        awtqs.count_pos_fig       = "count";
253        awtqs.do_query_pos_fig    = "doquery";
254        awtqs.config_pos_fig      = "doconfig";
255        awtqs.do_mark_pos_fig     = "domark";
256        awtqs.do_unmark_pos_fig   = "dounmark";
257        awtqs.do_delete_pos_fig   = "dodelete";
258        awtqs.do_set_pos_fig      = "doset";
259        awtqs.do_refresh_pos_fig  = "dorefresh";
260        awtqs.open_parser_pos_fig = "openparser";
261        awtqs.popup_info_window   = EXP_popup_experiment_window;
262
263        QUERY::DbQuery *query   = create_query_box(aws, &awtqs, "exp");
264        GLOBAL_experiment_query = query;
265
266        aws->create_menu("More search",     "s");
267        aws->insert_menu_topic("exp_search_equal_fields_within_db", "Search For Equal Fields and Mark Duplicates",              "E", "search_duplicates.hlp", AWM_ALL, makeWindowCallback(QUERY::search_duplicated_field_content, query, false));
268        aws->insert_menu_topic("exp_search_equal_words_within_db", "Search For Equal Words Between Fields and Mark Duplicates", "W", "search_duplicates.hlp", AWM_ALL, makeWindowCallback(QUERY::search_duplicated_field_content, query, true));
269
270        aws->button_length(7);
271
272        aws->at("close");
273        aws->callback(AW_POPDOWN);
274        aws->create_button("CLOSE", "CLOSE", "C");
275
276        aws->at("help");
277        aws->callback(makeHelpCallback("experiment_search.hlp"));
278        aws->create_button("HELP", "HELP", "H");
279    }
280    return aws;
281}
282
283static void experiment_delete_cb(AW_window *aww, GBDATA *gb_main) {
284    if (aw_ask_sure("experiment_delete", "Are you sure to delete the experiment")) {
285        GB_transaction  ta(gb_main);
286        GBDATA         *gb_experiment = EXP_get_current_experiment(gb_main, aww->get_root());
287
288        GB_ERROR error = gb_experiment ? GB_delete(gb_experiment) : "Please select a experiment first";
289        if (error) {
290            error = ta.close(error);
291            aw_message(error);
292        }
293    }
294}
295
296static void experiment_create_cb(AW_window *aww, GBDATA *gb_main) {
297    GB_ERROR error = GB_begin_transaction(gb_main);
298
299    if (!error) {
300        AW_root *aw_root            = aww->get_root();
301        GBDATA  *gb_experiment_data = EXP_get_current_experiment_data(gb_main, aw_root);
302
303        if (!gb_experiment_data) {
304            error = "Please select an organism";
305        }
306        else {
307            char   *dest    = aw_root->awar(AWAR_EXPERIMENT_DEST)->read_string();
308            GBDATA *gb_dest = EXP_find_experiment_rel_exp_data(gb_experiment_data, dest);
309
310            if (gb_dest) {
311                error  = GBS_global_string("Experiment '%s' already exists", dest);
312            }
313            else {
314                gb_dest             = EXP_find_or_create_experiment_rel_exp_data(gb_experiment_data, dest);
315                if (!gb_dest) error = GB_await_error();
316                else aww->get_root()->awar(AWAR_EXPERIMENT_NAME)->write_string(dest);
317            }
318            free(dest);
319        }
320    }
321
322    GB_end_transaction_show_error(gb_main, error, aw_message);
323}
324
325static void experiment_rename_cb(AW_window *aww, GBDATA *gb_main) {
326    AW_root *aw_root = aww->get_root();
327    char    *source  = aw_root->awar(AWAR_EXPERIMENT_NAME)->read_string();
328    char    *dest    = aw_root->awar(AWAR_EXPERIMENT_DEST)->read_string();
329
330    if (strcmp(source, dest) != 0) {
331        GB_ERROR error = GB_begin_transaction(gb_main);
332
333        if (!error) {
334            GBDATA *gb_experiment_data = EXP_get_current_experiment_data(gb_main, aww->get_root());
335
336            if (!gb_experiment_data) error = "Please select a species first";
337            else {
338                GBDATA *gb_source = EXP_find_experiment_rel_exp_data(gb_experiment_data, source);
339                GBDATA *gb_dest   = EXP_find_experiment_rel_exp_data(gb_experiment_data, dest);
340
341                if (!gb_source) error   = "Please select an experiment";
342                else if (gb_dest) error = GB_export_errorf("Experiment '%s' already exists", dest);
343                else {
344                    GBDATA *gb_name     = GB_search(gb_source, "name", GB_STRING);
345                    if (!gb_name) error = GB_await_error();
346                    else {
347                        error = GB_write_string(gb_name, dest);
348                        if (!error) aww->get_root()->awar(AWAR_EXPERIMENT_NAME)->write_string(dest);
349                    }
350                }
351            }
352        }
353        error = GB_end_transaction(gb_main, error);
354        aww->hide_or_notify(error);
355    }
356
357    free(source);
358    free(dest);
359}
360
361static void experiment_copy_cb(AW_window *aww, GBDATA *gb_main) {
362    char     *source = aww->get_root()->awar(AWAR_EXPERIMENT_NAME)->read_string();
363    char     *dest   = aww->get_root()->awar(AWAR_EXPERIMENT_DEST)->read_string();
364    GB_ERROR  error  = GB_begin_transaction(gb_main);
365
366    if (!error) {
367        GBDATA *gb_experiment_data = EXP_get_current_experiment_data(gb_main, aww->get_root());
368
369        if (!gb_experiment_data) {
370            error = "Please select a species first.";
371        }
372        else {
373            GBDATA *gb_source = EXP_find_experiment_rel_exp_data(gb_experiment_data, source);
374            GBDATA *gb_dest   = EXP_find_experiment_rel_exp_data(gb_experiment_data, dest);
375
376            if (!gb_source) error   = "Please select a experiment";
377            else if (gb_dest) error = GB_export_errorf("Experiment '%s' already exists", dest);
378            else {
379                gb_dest             = GB_create_container(gb_experiment_data, "experiment");
380                if (!gb_dest) error = GB_await_error();
381                else error          = GB_copy(gb_dest, gb_source);
382
383                if (!error) {
384                    error = GBT_write_string(gb_dest, "name", dest);
385                    if (!error) aww->get_root()->awar(AWAR_EXPERIMENT_NAME)->write_string(dest);
386                }
387            }
388        }
389    }
390
391    error = GB_end_transaction(gb_main, error);
392    aww->hide_or_notify(error);
393
394    free(source);
395    free(dest);
396}
397
398static AW_window *create_experiment_rename_window(AW_root *root, GBDATA *gb_main) {
399    AW_window_simple *aws = new AW_window_simple;
400    aws->init(root, "RENAME_EXPERIMENT", "EXPERIMENT RENAME");
401    aws->load_xfig("ad_al_si.fig");
402
403    aws->at("close");
404    aws->callback(AW_POPDOWN);
405    aws->create_button("CLOSE", "CLOSE", "C");
406
407    aws->at("label");
408    aws->create_autosize_button(0, "Please enter the new name\nof the experiment");
409
410    aws->at("input");
411    aws->create_input_field(AWAR_EXPERIMENT_DEST, 15);
412    aws->at("ok");
413    aws->callback(makeWindowCallback(experiment_rename_cb, gb_main));
414    aws->create_button("GO", "GO", "G");
415
416    return aws;
417}
418
419static AW_window *create_experiment_copy_window(AW_root *root, GBDATA *gb_main) {
420    AW_window_simple *aws = new AW_window_simple;
421    aws->init(root, "COPY_EXPERIMENT", "EXPERIMENT COPY");
422    aws->load_xfig("ad_al_si.fig");
423
424    aws->at("close");
425    aws->callback(AW_POPDOWN);
426    aws->create_button("CLOSE", "CLOSE", "C");
427
428    aws->at("label");
429    aws->create_autosize_button(0, "Please enter the name\nof the new experiment");
430
431    aws->at("input");
432    aws->create_input_field(AWAR_EXPERIMENT_DEST, 15);
433
434    aws->at("ok");
435    aws->callback(makeWindowCallback(experiment_copy_cb, gb_main));
436    aws->create_button("GO", "GO", "G");
437
438    return aws;
439}
440
441static AW_window *create_experiment_create_window(AW_root *root, GBDATA *gb_main) {
442    AW_window_simple *aws = new AW_window_simple;
443    aws->init(root, "CREATE_EXPERIMENT", "EXPERIMENT CREATE");
444    aws->load_xfig("ad_al_si.fig");
445
446    aws->at("close");
447    aws->callback(AW_POPDOWN);
448    aws->create_button("CLOSE", "CLOSE", "C");
449
450    aws->at("label"); aws->create_autosize_button(0, "Please enter the name\nof the new experiment");
451    aws->at("input"); aws->create_input_field(AWAR_EXPERIMENT_DEST, 15);
452
453    aws->at("ok");
454    aws->callback(makeWindowCallback(experiment_create_cb, gb_main));
455    aws->create_button("GO", "GO", "G");
456
457    return aws;
458}
459
460static void EXP_create_field_items(AW_window *aws, GBDATA *gb_main) {
461    static BoundItemSel *bis = new BoundItemSel(gb_main, EXP_get_selector());
462    exp_assert(bis->gb_main == gb_main);
463
464    aws->insert_menu_topic(aws->local_id("exp_reorder_fields"), "Reorder fields ...",    "R", "spaf_reorder.hlp", AD_F_ALL, makeCreateWindowCallback(DBUI::create_fields_reorder_window, bis));
465    aws->insert_menu_topic(aws->local_id("exp_delete_field"),   "Delete/Hide Field ...", "D", "spaf_delete.hlp",  AD_F_ALL, makeCreateWindowCallback(DBUI::create_field_delete_window, bis));
466    aws->insert_menu_topic(aws->local_id("exp_create_field"),   "Create fields ...",     "C", "spaf_create.hlp",  AD_F_ALL, makeCreateWindowCallback(DBUI::create_field_create_window, bis));
467    aws->sep______________();
468    aws->insert_menu_topic("exp_unhide_fields",  "Show all hidden fields", "S", "scandb.hlp", AD_F_ALL, makeWindowCallback(experiment_field_selection_list_unhide_all_cb, gb_main));
469    aws->insert_menu_topic("exp_refresh_fields", "Refresh fields",         "f", "scandb.hlp", AD_F_ALL, makeWindowCallback(experiment_field_selection_list_update_cb,     gb_main));
470}
471
472#if defined(WARN_TODO)
473#warning move EXP_create_experiment_window to SL/DB_UI
474#endif
475
476static AW_window *popup_new_experiment_window(AW_root *aw_root, GBDATA *gb_main, int detach_id);
477
478static void popup_detached_experiment_window(AW_window *aw_parent, const InfoWindow *infoWin) {
479    const InfoWindow *reusable = InfoWindowRegistry::infowin.find_reusable_of_same_type_as(*infoWin);
480    if (reusable) {
481        reusable->reuse();
482    }
483    else { // create a new window if none is reusable
484        popup_new_experiment_window(aw_parent->get_root(),
485                                    infoWin->get_gbmain(),
486                                    InfoWindowRegistry::infowin.allocate_detach_id(*infoWin));
487    }
488}
489
490static AW_window *popup_new_experiment_window(AW_root *aw_root, GBDATA *gb_main, int detach_id) { // INFO_WINDOW_CREATOR
491    AW_window_simple_menu *aws      = new AW_window_simple_menu;
492    const ItemSelector&    itemType = EXP_get_selector();
493
494    DBUI::init_info_window(aw_root, aws, itemType, detach_id);
495    aws->load_xfig("ad_spec.fig");
496
497    aws->button_length(8);
498
499    aws->at("close");
500    aws->callback(AW_POPDOWN);
501    aws->create_button("CLOSE", "CLOSE", "C");
502
503    aws->at("search");
504    aws->callback(makeCreateWindowCallback(EXP_create_experiment_query_window, gb_main));
505    aws->create_button("SEARCH", "SEARCH", "S", "+");
506
507    aws->at("help");
508    aws->callback(makeHelpCallback("experiment_info.hlp"));
509    aws->create_button("HELP", "HELP", "H");
510
511    DbScanner *scanner = DbScanner::create(gb_main,
512                                           InfoWindowRegistry::localize_scanner_id("experiment", detach_id),
513                                           aws, "box", "field", "enable", DB_VIEWER, "mark", itemType);
514
515    const InfoWindow& infoWin = InfoWindowRegistry::infowin.registerInfoWindow(aws, scanner, detach_id);
516
517    if (infoWin.is_maininfo()) {
518        aws->create_menu("EXPERIMENT", "E", AD_F_ALL);
519        aws->insert_menu_topic("experiment_delete", "Delete",     "D", "spa_delete.hlp", AD_F_ALL, makeWindowCallback      (experiment_delete_cb,            gb_main));
520        aws->insert_menu_topic("experiment_rename", "Rename ...", "R", "spa_rename.hlp", AD_F_ALL, makeCreateWindowCallback(create_experiment_rename_window, gb_main));
521        aws->insert_menu_topic("experiment_copy",   "Copy ...",   "y", "spa_copy.hlp",   AD_F_ALL, makeCreateWindowCallback(create_experiment_copy_window,   gb_main));
522        aws->insert_menu_topic("experiment_create", "Create ...", "C", "spa_create.hlp", AD_F_ALL, makeCreateWindowCallback(create_experiment_create_window, gb_main));
523    }
524
525    aws->create_menu("FIELDS", "F", AD_F_ALL);
526    EXP_create_field_items(aws, gb_main);
527
528    aws->at("detach");
529    infoWin.add_detach_area(popup_detached_experiment_window);
530
531    aws->show();
532    infoWin.attach_selected_item();
533
534    return aws;
535}
536
537void EXP_popup_experiment_window(AW_root *aw_root, GBDATA *gb_main) {
538    static AW_window *aws = 0;
539    if (!aws) {
540        aws = popup_new_experiment_window(aw_root, gb_main, InfoWindow::MAIN_WINDOW);
541    }
542    else {
543        InfoWindowRegistry::reactivate(aws);
544    }
545}
Note: See TracBrowser for help on using the repository browser.