source: branches/lib/GENOM/EXP_interface.cxx

Last change on this file was 19504, checked in by westram, 8 months ago
  • also add buttons to experiment and genes search.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.5 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 <item_sel_list.h>
22#include <info_window.h>
23
24#include <awt_prompt.hxx>
25#include <awt_sel_boxes.hxx>
26
27#include <aw_awar_defs.hxx>
28#include <aw_root.hxx>
29#include <aw_msg.hxx>
30#include <aw_question.hxx>
31
32using namespace std;
33
34#define AD_F_ALL AWM_ALL
35
36static GBDATA* get_current_experiment_data(GBDATA *gb_main) {
37    GBDATA *gb_species         = GEN_get_current_organism(gb_main);
38    GBDATA *gb_experiment_data = NULp;
39
40    if (gb_species) gb_experiment_data = EXP_get_experiment_data(gb_species);
41
42    return gb_experiment_data;
43}
44
45static void EXP_select_experiment(GBDATA* /* gb_main */, AW_root *aw_root, const char *item_name) {
46    char *name  = ARB_strdup(item_name);
47    char *slash = strchr(name, '/');
48
49    if (slash) {
50        slash[0] = 0;
51        aw_root->awar(AWAR_ORGANISM_NAME)->write_string(name);
52        aw_root->awar(AWAR_EXPERIMENT_NAME)->write_string(slash+1);
53    }
54    free(name);
55}
56
57static char *EXP_get_experiment_id(GBDATA * /* gb_main */, GBDATA *gb_experiment) {
58    GBDATA *gb_species = GB_get_grandfather(gb_experiment);
59    return GBS_global_string_copy("%s/%s", GBT_get_name_or_description(gb_species), GBT_get_name_or_description(gb_experiment));
60}
61
62static GBDATA *EXP_find_experiment_by_id(GBDATA *gb_main, const char *id) {
63    char   *organism = ARB_strdup(id);
64    char   *exp      = strchr(organism, '/');
65    GBDATA *result   = NULp;
66
67    if (exp) {
68        *exp++ = 0;
69        GBDATA *gb_organism = GEN_find_organism(gb_main, organism);
70        if (gb_organism) {
71            result = EXP_find_experiment(gb_organism, exp);
72        }
73    }
74
75    free(organism);
76    return result;
77}
78
79static char *old_species_marks = NULp; // configuration storing marked species
80
81inline void exp_restore_old_species_marks(GBDATA *gb_main) {
82    if (old_species_marks) {
83        GBT_restore_marked_species(gb_main, old_species_marks);
84        freenull(old_species_marks);
85    }
86}
87
88static GBDATA *EXP_get_first_experiment_data(GBDATA *gb_main, AW_root *aw_root, QUERY_RANGE range) {
89    GBDATA   *gb_organism = NULp;
90    GB_ERROR  error       = NULp;
91
92    gen_assert(!old_species_marks); // old_species_marks may be out of date (better call EXP_get_(first|next)_experiment_data until it returns NULp!)
93    exp_restore_old_species_marks(gb_main);
94
95    switch (range) {
96        case QUERY_CURRENT_ITEM: {
97            char *species_name = aw_root->awar(AWAR_ORGANISM_NAME)->read_string();
98            gb_organism         = GBT_find_species(gb_main, species_name);
99            free(species_name);
100            break;
101        }
102        case QUERY_MARKED_ITEMS: {
103            GBDATA *gb_pseudo = GEN_first_marked_pseudo_species(gb_main);
104
105            if (gb_pseudo) {    // there are marked pseudo-species..
106                old_species_marks = GBT_store_marked_species(gb_main, true); // store and unmark marked species
107                error             = GBT_with_stored_species(gb_main, old_species_marks, GEN_mark_organism_or_corresponding_organism, NULp); // mark organisms related with stored
108
109                if (!error) {
110                    gb_organism = GEN_first_marked_organism(gb_main);
111                    if (!gb_organism) exp_restore_old_species_marks(gb_main); // got all -> clean up
112                }
113            }
114            else {
115                gb_organism = GEN_first_marked_organism(gb_main);
116            }
117            break;
118        }
119        case QUERY_ALL_ITEMS: {
120            gb_organism = GBT_first_species(gb_main);
121            break;
122        }
123        default: {
124            gen_assert(0);
125            break;
126        }
127    }
128
129    if (error) GB_export_error(error);
130    return gb_organism ? EXP_get_experiment_data(gb_organism) : NULp;
131}
132
133static GBDATA *EXP_get_next_experiment_data(GBDATA *gb_experiment_data, QUERY_RANGE range) {
134    GBDATA *gb_organism = NULp;
135    switch (range) {
136        case QUERY_CURRENT_ITEM: {
137            break;
138        }
139        case QUERY_MARKED_ITEMS: {
140            GBDATA *gb_last_species = GB_get_father(gb_experiment_data);
141            gb_organism             = GEN_next_marked_organism(gb_last_species);
142
143            if (!gb_organism) exp_restore_old_species_marks(GB_get_root(gb_experiment_data)); // got all -> clean up
144            break;
145        }
146        case QUERY_ALL_ITEMS: {
147            GBDATA *gb_last_species = GB_get_father(gb_experiment_data);
148            gb_organism             = GBT_next_species(gb_last_species);
149            break;
150        }
151        default: {
152            gen_assert(0);
153            break;
154        }
155    }
156
157    return gb_organism ? EXP_get_experiment_data(gb_organism) : NULp;
158}
159
160static GBDATA *EXP_get_current_experiment(GBDATA *gb_main, AW_root *aw_root) {
161    GBDATA *gb_organism   = GEN_get_current_organism(gb_main);
162    GBDATA *gb_experiment = NULp;
163
164    if (gb_organism) {
165        char *experiment_name = aw_root->awar(AWAR_EXPERIMENT_NAME)->read_string();
166        gb_experiment         = EXP_find_experiment(gb_organism, experiment_name);
167        free(experiment_name);
168    }
169
170    return gb_experiment;
171}
172
173static void add_selected_experiment_changed_cb(AW_root *aw_root, const RootCallback& cb) {
174    aw_root->awar(AWAR_EXPERIMENT_NAME)->add_callback(cb);
175    ORGANISM_get_selector().add_selection_changed_cb(aw_root, cb);
176}
177
178static GBDATA *first_experiment_in_range(GBDATA *gb_experiment_data, QUERY_RANGE range) {
179    GBDATA *gb_first = NULp;
180    switch (range) {
181        case QUERY_ALL_ITEMS:    gb_first = EXP_first_experiment_rel_exp_data(gb_experiment_data); break;
182        case QUERY_MARKED_ITEMS: gb_first = GB_first_marked(gb_experiment_data, "experiment"); break;
183        case QUERY_CURRENT_ITEM: gb_first = EXP_get_current_experiment(GB_get_root(gb_experiment_data), AW_root::SINGLETON); break;
184    }
185    return gb_first;
186}
187static GBDATA *next_experiment_in_range(GBDATA *gb_prev, QUERY_RANGE range) {
188    GBDATA *gb_next = NULp;
189    switch (range) {
190        case QUERY_ALL_ITEMS:    gb_next = EXP_next_experiment(gb_prev); break;
191        case QUERY_MARKED_ITEMS: gb_next = GB_next_marked(gb_prev, "experiment"); break;
192        case QUERY_CURRENT_ITEM: gb_next = NULp; break;
193    }
194    return gb_next;
195}
196
197static void refresh_displayed_experiments() {} // nothing todo here
198
199static struct MutableItemSelector EXP_item_selector = { // @@@ move to SL/ITEMS
200    QUERY_ITEM_EXPERIMENTS,
201    EXP_select_experiment,
202    EXP_get_experiment_id,
203    EXP_find_experiment_by_id,
204    experiment_field_selection_list_update_cb,
205    -1, // unknown
206    CHANGE_KEY_PATH_EXPERIMENTS,
207    "experiment",
208    "experiments",
209    "name",
210    EXP_get_first_experiment_data,
211    EXP_get_next_experiment_data,
212    first_experiment_in_range,
213    next_experiment_in_range,
214    EXP_get_current_experiment,
215    add_selected_experiment_changed_cb,
216    &ORGANISM_get_selector(), GB_get_grandfather,
217    refresh_displayed_experiments,
218};
219
220ItemSelector& EXP_get_selector() { return EXP_item_selector; }
221
222static QUERY::DbQuery *GLOBAL_experiment_query = NULp;
223
224AW_window *EXP_create_experiment_query_window(AW_root *aw_root, GBDATA *gb_main) { // @@@ move to SL/DB_UI
225    static AW_window_simple_menu *aws = NULp;
226    if (!aws) {
227        aws = new AW_window_simple_menu;
228        aws->init(aw_root, "EXPERIMENT_QUERY", "Experiment SEARCH and QUERY");
229        aws->create_menu("More functions", "f");
230        aws->load_xfig("ad_query.fig");
231
232        QUERY::query_spec awtqs(EXP_get_selector());
233
234        awtqs.gb_main              = gb_main;
235        awtqs.species_name         = AWAR_SPECIES_NAME;
236        awtqs.tree_name            = AWAR_TREE;
237        awtqs.select_bit           = GB_USERFLAG_QUERY;
238        awtqs.use_menu             = 1;
239        awtqs.ere_pos_fig          = "ere3";
240        awtqs.where_pos_fig        = "where3";
241        awtqs.by_pos_fig           = "by3";
242        awtqs.qbox_pos_fig         = "qbox";
243        awtqs.key_pos_fig          = NULp;
244        awtqs.query_pos_fig        = "content";
245        awtqs.result_pos_fig       = "result";
246        awtqs.count_pos_fig        = "count";
247        awtqs.do_query_pos_fig     = "doquery";
248        awtqs.config_pos_fig       = "doconfig";
249        awtqs.do_mark_pos_fig      = "domark";
250        awtqs.do_unmark_pos_fig    = "dounmark";
251        awtqs.do_mark_nt_pos_fig   = "domark_nt";
252        awtqs.do_unmark_nt_pos_fig = "dounmark_nt";
253        awtqs.do_delete_pos_fig    = "dodelete";
254        awtqs.do_set_pos_fig       = "doset";
255        awtqs.do_refresh_pos_fig   = "dorefresh";
256        awtqs.open_parser_pos_fig  = "openparser";
257        awtqs.popup_info_window    = EXP_popup_experiment_window;
258
259        QUERY::DbQuery *query   = create_query_box(aws, &awtqs, "exp");
260        GLOBAL_experiment_query = query;
261
262        aws->create_menu("More search",     "s");
263        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));
264        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));
265
266        aws->button_length(7);
267
268        aws->at("close");
269        aws->callback(AW_POPDOWN);
270        aws->create_button("CLOSE", "CLOSE", "C");
271
272        aws->at("help");
273        aws->callback(makeHelpCallback("experiment_search.hlp"));
274        aws->create_button("HELP", "HELP", "H");
275    }
276    return aws;
277}
278
279static void experiment_delete_cb(AW_window *aww, GBDATA *gb_main) {
280    if (aw_ask_sure("experiment_delete", "Are you sure to delete the experiment")) {
281        GB_transaction  ta(gb_main);
282        GBDATA         *gb_experiment = EXP_get_current_experiment(gb_main, aww->get_root());
283
284        GB_ERROR error = gb_experiment ? GB_delete(gb_experiment) : "Please select a experiment first";
285        if (error) {
286            error = ta.close(error);
287            aw_message(error);
288        }
289    }
290}
291
292static GB_ERROR experiment_create_handler(const char *dest, GBDATA *gb_main) {
293    GB_ERROR error = GB_begin_transaction(gb_main);
294
295    if (!error) {
296        AW_root *aw_root            = AW_root::SINGLETON;
297        GBDATA  *gb_experiment_data = get_current_experiment_data(gb_main);
298
299        if (!gb_experiment_data) error = "Please select an organism";
300        else {
301            GBDATA *gb_dest = EXP_find_experiment_rel_exp_data(gb_experiment_data, dest);
302            if (gb_dest) {
303                error  = GBS_global_string("Experiment '%s' already exists", dest);
304            }
305            else {
306                gb_dest             = EXP_find_or_create_experiment_rel_exp_data(gb_experiment_data, dest);
307                if (!gb_dest) error = GB_await_error();
308                else aw_root->awar(AWAR_EXPERIMENT_NAME)->write_string(dest);
309            }
310        }
311    }
312
313    error = GB_end_transaction(gb_main, error);
314    return error;
315}
316static GB_ERROR experiment_rename_handler(const char *dest, GBDATA *gb_main) {
317    AW_root    *awr    = AW_root::SINGLETON;
318    const char *source = awr->awar(AWAR_EXPERIMENT_NAME)->read_char_pntr();
319    GB_ERROR    error  = NULp;
320
321    if (strcmp(source, dest) != 0) {
322        error = GB_begin_transaction(gb_main);
323        if (!error) {
324            GBDATA *gb_experiment_data = get_current_experiment_data(gb_main);
325
326            if (!gb_experiment_data) error = "Please select an organism";
327            else {
328                GBDATA *gb_source = EXP_find_experiment_rel_exp_data(gb_experiment_data, source);
329                GBDATA *gb_dest   = EXP_find_experiment_rel_exp_data(gb_experiment_data, dest);
330
331                if (!gb_source) error   = "Please select an experiment";
332                else if (gb_dest) error = GB_export_errorf("Experiment '%s' already exists", dest);
333                else {
334                    GBDATA *gb_name     = GB_search(gb_source, "name", GB_STRING);
335                    if (!gb_name) error = GB_await_error();
336                    else {
337                        error = GB_write_string(gb_name, dest);
338                        if (!error) awr->awar(AWAR_EXPERIMENT_NAME)->write_string(dest);
339                    }
340                }
341            }
342        }
343        error = GB_end_transaction(gb_main, error);
344    }
345
346    return error;
347}
348static GB_ERROR experiment_copy_handler(const char *dest, GBDATA *gb_main) {
349    AW_root    *awr    = AW_root::SINGLETON;
350    const char *source = awr->awar(AWAR_EXPERIMENT_NAME)->read_char_pntr();
351    GB_ERROR    error  = GB_begin_transaction(gb_main);
352
353    if (!error) {
354        GBDATA *gb_experiment_data = get_current_experiment_data(gb_main);
355
356        if (!gb_experiment_data) error = "Please select an organism";
357        else {
358            GBDATA *gb_source = EXP_find_experiment_rel_exp_data(gb_experiment_data, source);
359            GBDATA *gb_dest   = EXP_find_experiment_rel_exp_data(gb_experiment_data, dest);
360
361            if (!gb_source) error   = "Please select an experiment";
362            else if (gb_dest) error = GB_export_errorf("Experiment '%s' already exists", dest);
363            else {
364                gb_dest             = GB_create_container(gb_experiment_data, "experiment");
365                if (!gb_dest) error = GB_await_error();
366                else error          = GB_copy_dropProtectMarksAndTempstate(gb_dest, gb_source);
367
368                if (!error) {
369                    error = GBT_write_string(gb_dest, "name", dest);
370                    if (!error) awr->awar(AWAR_EXPERIMENT_NAME)->write_string(dest);
371                }
372            }
373        }
374    }
375
376    error = GB_end_transaction(gb_main, error);
377    return error;
378}
379static void experiment_create_cb(AW_window *aww, GBDATA *gb_main) {
380    ResultHandler  handler = makeResultHandler(experiment_create_handler, gb_main);
381    const char    *source  = aww->get_root()->awar(AWAR_EXPERIMENT_NAME)->read_char_pntr();
382    AWT_activate_prompt("Create experiment", "Enter name of new experiment:", source, "Create", handler);
383}
384static void experiment_rename_cb(AW_window *aww, GBDATA *gb_main) {
385    ResultHandler  handler = makeResultHandler(experiment_rename_handler, gb_main);
386    const char    *source  = aww->get_root()->awar(AWAR_EXPERIMENT_NAME)->read_char_pntr();
387    AWT_activate_prompt("Rename experiment", "Enter new experiment name:", source, "Rename", handler);
388}
389static void experiment_copy_cb(AW_window *aww, GBDATA *gb_main) {
390    ResultHandler  handler = makeResultHandler(experiment_copy_handler, gb_main);
391    const char    *source  = aww->get_root()->awar(AWAR_EXPERIMENT_NAME)->read_char_pntr();
392    AWT_activate_prompt("Copy experiment", "Enter name of new experiment:", source, "Copy", handler);
393}
394
395static void EXP_create_field_items(AW_window *aws, GBDATA *gb_main) {
396    static BoundItemSel *bis = new BoundItemSel(gb_main, EXP_get_selector());
397    exp_assert(bis->gb_main == gb_main);
398
399    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));
400    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));
401    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));
402    aws->sep______________();
403    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));
404    aws->insert_menu_topic("exp_refresh_fields", "Refresh fields",         "f", "scandb.hlp", AD_F_ALL, makeWindowCallback(experiment_field_selection_list_update_cb,     gb_main));
405}
406
407static AW_window *popup_new_experiment_window(AW_root *aw_root, GBDATA *gb_main, int detach_id);
408
409static void popup_detached_experiment_window(AW_window *aw_parent, const InfoWindow *infoWin) {
410    const InfoWindow *reusable = InfoWindowRegistry::infowin.find_reusable_of_same_type_as(*infoWin);
411    if (reusable) {
412        reusable->reuse();
413    }
414    else { // create a new window if none is reusable
415        popup_new_experiment_window(aw_parent->get_root(),
416                                    infoWin->get_gbmain(),
417                                    InfoWindowRegistry::infowin.allocate_detach_id(*infoWin));
418    }
419}
420
421static AW_window *popup_new_experiment_window(AW_root *aw_root, GBDATA *gb_main, int detach_id) { // INFO_WINDOW_CREATOR
422    AW_window_simple_menu *aws      = new AW_window_simple_menu;
423    const ItemSelector&    itemType = EXP_get_selector();
424
425    DBUI::init_info_window(aw_root, aws, itemType, detach_id);
426    aws->load_xfig("ad_spec.fig");
427
428    aws->button_length(8);
429
430    aws->at("close");
431    aws->callback(AW_POPDOWN);
432    aws->create_button("CLOSE", "CLOSE", "C");
433
434    aws->at("search");
435    aws->callback(makeCreateWindowCallback(EXP_create_experiment_query_window, gb_main));
436    aws->create_button("SEARCH", "SEARCH", "S", "+");
437
438    aws->at("help");
439    aws->callback(makeHelpCallback("experiment_info.hlp"));
440    aws->create_button("HELP", "HELP", "H");
441
442    DbScanner *scanner = DbScanner::create(gb_main,
443                                           InfoWindowRegistry::localize_scanner_id("experiment", detach_id),
444                                           aws, "box", "field", "enable", DB_KEYVIEWER, "mark", itemType);
445
446    const InfoWindow& infoWin = InfoWindowRegistry::infowin.registerInfoWindow(aws, scanner, detach_id);
447
448    if (infoWin.is_maininfo()) {
449        aws->create_menu("EXPERIMENT", "E", AD_F_ALL);
450        aws->insert_menu_topic("experiment_delete", "Delete",     "D", "spa_delete.hlp", AD_F_ALL, makeWindowCallback(experiment_delete_cb, gb_main));
451        aws->insert_menu_topic("experiment_rename", "Rename ...", "R", "spa_rename.hlp", AD_F_ALL, makeWindowCallback(experiment_rename_cb, gb_main));
452        aws->insert_menu_topic("experiment_copy",   "Copy ...",   "y", "spa_copy.hlp",   AD_F_ALL, makeWindowCallback(experiment_copy_cb,   gb_main));
453        aws->insert_menu_topic("experiment_create", "Create ...", "C", "spa_create.hlp", AD_F_ALL, makeWindowCallback(experiment_create_cb, gb_main));
454    }
455
456    aws->create_menu("FIELDS", "F", AD_F_ALL);
457    EXP_create_field_items(aws, gb_main);
458
459    aws->at("detach");
460    infoWin.add_detach_area(popup_detached_experiment_window);
461
462    aws->show();
463    infoWin.attach_selected_item();
464
465    return aws;
466}
467
468void EXP_popup_experiment_window(AW_root *aw_root, GBDATA *gb_main) { // @@@ move to SL/DB_UI
469    static AW_window *aws = NULp;
470    if (!aws) {
471        aws = popup_new_experiment_window(aw_root, gb_main, InfoWindow::MAIN_WINDOW);
472    }
473    else {
474        InfoWindowRegistry::reactivate(aws);
475    }
476}
Note: See TracBrowser for help on using the repository browser.