source: tags/ms_r18q1/NTREE/ad_ext.cxx

Last change on this file was 16763, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : ad_ext.cxx                                        //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "NT_local.h"
12#include <db_scanner.hxx>
13#include <awt_sel_boxes.hxx>
14#include <aw_awars.hxx>
15#include <aw_msg.hxx>
16#include <aw_root.hxx>
17#include <aw_select.hxx>
18#include <arbdbt.h>
19#include <arb_strarray.h>
20#include <arb_sort.h>
21
22static void rename_SAI_cb(AW_window *aww) {
23    AW_awar  *awar_sai = aww->get_root()->awar(AWAR_SAI_NAME);
24    char     *sai_name = awar_sai->read_string();
25    GB_ERROR  error    = NULp;
26
27    if (!sai_name || !sai_name[0]) error = "Select SAI to rename";
28    else {
29        char *new_name = aw_input("Rename SAI", "Enter new name of SAI", sai_name);
30        if (new_name && new_name[0]) {
31            error = GB_begin_transaction(GLOBAL.gb_main);
32            if (!error) {
33                GBDATA *gb_sai     = GBT_find_SAI(GLOBAL.gb_main, sai_name);
34                if (!gb_sai) error = GBS_global_string("can't find SAI '%s'", sai_name);
35                else {
36                    GBDATA *gb_dest_exists    = GBT_find_SAI(GLOBAL.gb_main, new_name);
37                    if (gb_dest_exists) error = GBS_global_string("There is already a SAI named '%s'", new_name);
38                    else {
39                        error = GBT_write_string(gb_sai, "name", new_name);
40                        if (!error) awar_sai->write_string(new_name);
41                    }
42                }
43            }
44            error = GB_end_transaction(GLOBAL.gb_main, error);
45        }
46        free(new_name);
47    }
48    free(sai_name);
49
50    if (error) aw_message(error);
51}
52
53static void copy_SAI_cb(AW_window *aww) {
54    AW_awar  *awar_sai    = aww->get_root()->awar(AWAR_SAI_NAME);
55    char     *source_name = awar_sai->read_string();
56    GB_ERROR  error       = NULp;
57
58    if (!source_name || !source_name[0]) error = "Select SAI to duplicate";
59    else {
60        char *dest_name = aw_input("Copy SAI", "Enter name of new SAI", source_name);
61        if (dest_name && dest_name[0]) {
62            error = GB_begin_transaction(GLOBAL.gb_main);
63            if (!error) {
64                GBDATA *gb_sai_data   = GBT_get_SAI_data(GLOBAL.gb_main);
65                GBDATA *gb_source     = GBT_find_SAI_rel_SAI_data(gb_sai_data, source_name);
66                if (!gb_source) error = GBS_global_string("can't find SAI '%s'", source_name);
67                else {
68                    GBDATA *gb_dest_exists    = GBT_find_SAI_rel_SAI_data(gb_sai_data, dest_name);
69                    if (gb_dest_exists) error = GBS_global_string("There is already a SAI named '%s'", dest_name);
70                    else {
71                        GBDATA *gb_dest     = GB_create_container(gb_sai_data, "extended");
72                        if (!gb_dest) error = GB_await_error();
73                        else {
74                            error             = GB_copy(gb_dest, gb_source);
75                            if (!error) {
76                                error = GBT_write_string(gb_dest, "name", dest_name);
77                                if (!error) awar_sai->write_string(dest_name);
78                            }
79                        }
80                    }
81                }
82            }
83            error = GB_end_transaction(GLOBAL.gb_main, error);
84        }
85        free(dest_name);
86    }
87    free(source_name);
88
89    if (error) aw_message(error);
90}
91
92static void copy_SAI_to_species_cb(AW_window *aww) {
93    AW_root  *aw_root  = aww->get_root();
94    char     *sai_name = aw_root->awar(AWAR_SAI_NAME)->read_string();
95    GB_ERROR  error    = NULp;
96
97    if (!sai_name || !sai_name[0]) error = "No SAI selected";
98    else {
99        char *species_name = aw_input("Copy SAI to species", "Enter target species name:", sai_name);
100
101        if (species_name && species_name[0]) {
102            error = GB_begin_transaction(GLOBAL.gb_main);
103
104            if (!error) {
105                GBDATA *gb_species_data = GBT_get_species_data(GLOBAL.gb_main);
106                GBDATA *gb_dest         = GBT_find_species_rel_species_data(gb_species_data, species_name);
107
108                if (gb_dest) error = GBS_global_string("Species '%s' already exists", species_name);
109                else {
110                    GBDATA *gb_sai = GBT_find_SAI(GLOBAL.gb_main, sai_name);
111
112                    if (!gb_sai) error = GBS_global_string("SAI '%s' not found", sai_name);
113                    else {
114                        gb_dest             = GB_create_container(gb_species_data, "species");
115                        if (!gb_dest) error = GB_await_error();
116                        else {
117                            error = GB_copy(gb_dest, gb_sai);
118                            if (!error) {
119                                error = GBT_write_string(gb_dest, "name", species_name);
120                                if (!error) aw_root->awar(AWAR_SPECIES_NAME)->write_string(species_name);
121                            }
122                        }
123                    }
124                }
125            }
126            error = GB_end_transaction(GLOBAL.gb_main, error);
127        }
128        free(species_name);
129    }
130    free(sai_name);
131    if (error) aw_message(error);
132}
133
134static void delete_SAI_cb(AW_window *aww) {
135    char     *sai_name      = aww->get_root()->awar(AWAR_SAI_NAME)->read_string();
136    GB_ERROR  error       = GB_begin_transaction(GLOBAL.gb_main);
137
138    if (!error) {
139        GBDATA *gb_sai = GBT_find_SAI(GLOBAL.gb_main, sai_name);
140        error          = gb_sai ? GB_delete(gb_sai) : "Please select a SAI";
141    }
142    GB_end_transaction_show_error(GLOBAL.gb_main, error, aw_message);
143    free(sai_name);
144}
145
146static void map_SAI_to_scanner(AW_root *aw_root, DbScanner *scanner) {
147    GB_transaction  ta(GLOBAL.gb_main);
148    char           *sai_name = aw_root->awar(AWAR_SAI_NAME)->read_string();
149    GBDATA         *gb_sai   = GBT_find_SAI(GLOBAL.gb_main, sai_name);
150
151    scanner->Map(gb_sai, CHANGE_KEY_PATH);
152    free(sai_name);
153}
154
155static void edit_SAI_description(AW_window *aww) {
156    AW_root  *awr      = aww->get_root();
157    char     *sai_name = awr->awar(AWAR_SAI_NAME)->read_string();
158    GB_ERROR  error    = NULp;
159
160    if (!sai_name || !sai_name[0]) error = "No SAI selected";
161    else {
162        GBDATA *gb_ali = NULp;
163        char   *type   = NULp;
164        {
165            GB_transaction  ta(GLOBAL.gb_main);
166            GBDATA         *gb_sai = GBT_find_SAI(GLOBAL.gb_main, sai_name);
167
168            if (!gb_sai) error = GBS_global_string("SAI '%s' not found", sai_name);
169            else {
170                char *ali_name = GBT_get_default_alignment(GLOBAL.gb_main);
171
172                gb_ali = GB_entry(gb_sai, ali_name);
173                if (!gb_ali) error = GBS_global_string("SAI '%s' has no data in alignment '%s'", sai_name, ali_name);
174                else {
175                    GB_clear_error();
176                    type = GBT_read_string(gb_ali, "_TYPE");
177                    if (!type) {
178                        if (GB_have_error()) {
179                            error = GB_await_error();
180                        }
181                        else {
182                            type = ARB_strdup("");
183                        }
184                    }
185                }
186            }
187            error = ta.close(error);
188        }
189
190        if (!error) {
191            nt_assert(gb_ali);
192            char *new_type = aw_input("Change SAI description", type);
193            if (new_type) {
194                GB_transaction t2(GLOBAL.gb_main);
195
196                if (new_type[0]) {
197                    error = GBT_write_string(gb_ali, "_TYPE", new_type);
198                }
199                else { // empty description -> delete
200                    GBDATA *gb_type = GB_entry(gb_ali, "_TYPE");
201                    if (gb_type) error = GB_delete(gb_type);
202                }
203                error = t2.close(error);
204                free(new_type);
205            }
206        }
207
208        free(type);
209    }
210
211    if (error) aw_message(error);
212}
213
214static GB_ERROR set_SAI_group(GBDATA *gb_main, const char *sai_name, const char *group_name) {
215    GB_transaction ta(gb_main);
216
217    GB_ERROR  error  = NULp;
218    GBDATA   *gb_sai = GBT_find_SAI(gb_main, sai_name);
219    if (!gb_sai) {
220        error = GBS_global_string("SAI '%s' not found", sai_name);
221    }
222    else {
223        const char *old_group_name = GBT_read_char_pntr(gb_sai, "sai_group");
224        nt_assert(group_name);
225        if (!old_group_name || strcmp(old_group_name, group_name) != 0) {
226            if (group_name[0]) { // assign group
227                error = GBT_write_string(gb_sai, "sai_group", group_name);
228            }
229            else { // remove group
230                GBDATA *gb_group    = GB_entry(gb_sai, "sai_group");
231                if (gb_group) error = GB_delete(gb_group);
232            }
233        }
234    }
235    return error;
236}
237
238static const char *get_SAI_group(GBDATA *gb_main, const char *sai_name) {
239    GB_transaction  ta(gb_main);
240    GBDATA         *gb_sai     = GBT_find_SAI(gb_main, sai_name);
241    const char     *group_name = "";
242    if (gb_sai) group_name     = GBT_read_char_pntr(gb_sai, "sai_group");
243    return group_name;
244}
245
246static void get_SAI_groups(GBDATA *gb_main, ConstStrArray& sai_groups) {
247    GB_transaction ta(gb_main);
248    for (GBDATA *gb_sai = GBT_first_SAI(gb_main); gb_sai; gb_sai = GBT_next_SAI(gb_sai)) {
249        const char *group = GBT_read_char_pntr(gb_sai, "sai_group");
250        if (group) sai_groups.put(group);
251    }
252    sai_groups.sort_and_uniq(GB_string_comparator, NULp);
253}
254
255static void fill_SAI_group_selection_list(AW_selection_list *sel, GBDATA *gb_main) {
256    ConstStrArray sai_groups;
257    get_SAI_groups(gb_main, sai_groups);
258    sel->init_from_array(sai_groups, "<nogroup>", "");
259}
260
261#define AWAR_SAI_GROUP          "tmp/extended/group"
262#define AWAR_SAI_REFRESH_GROUPS "tmp/extended/refresh"
263
264static void refresh_grouplist(AW_root *aw_root) {
265    aw_root->awar(AWAR_SAI_REFRESH_GROUPS)->touch(); // fill/refresh group selection list
266}
267
268static void set_SAI_group_cb(AW_root *aw_root, GBDATA *gb_main) {
269    const char *sai_name   = aw_root->awar(AWAR_SAI_NAME)->read_char_pntr();
270    const char *group_name = aw_root->awar(AWAR_SAI_GROUP)->read_char_pntr();
271    aw_message_if(set_SAI_group(gb_main, sai_name, group_name));
272    refresh_grouplist(aw_root);
273}
274
275static AW_selection_list *sai_group_sel = NULp;
276static void refresh_SAI_groups_cb(AW_root*, GBDATA *gb_main) {
277    if (sai_group_sel) fill_SAI_group_selection_list(sai_group_sel, gb_main);
278}
279
280static void refresh_group_cb(AW_root *aw_root, GBDATA *gb_main) {
281    const char *sai_name   = aw_root->awar(AWAR_SAI_NAME)->read_char_pntr();
282    const char *group_name = get_SAI_group(gb_main, sai_name);
283    aw_root->awar(AWAR_SAI_GROUP)->write_string(group_name);
284}
285
286void NT_create_extendeds_vars(AW_root *aw_root, AW_default aw_def, GBDATA *gb_main) {
287    const char *sai_name   = aw_root->awar(AWAR_SAI_NAME)->read_char_pntr();
288    const char *group_name = get_SAI_group(gb_main, sai_name);
289
290    aw_root->awar_string(AWAR_SAI_GROUP,          group_name, aw_def)->add_callback(makeRootCallback(set_SAI_group_cb,      gb_main));
291    aw_root->awar_int   (AWAR_SAI_REFRESH_GROUPS, 0,          aw_def)->add_callback(makeRootCallback(refresh_SAI_groups_cb, gb_main));
292    aw_root->awar       (AWAR_SAI_NAME)                              ->add_callback(makeRootCallback(refresh_group_cb,      gb_main));
293}
294
295static AW_window *create_SAI_group_window(AW_root *aw_root) {
296    AW_window_simple *aws = new AW_window_simple;
297    aws->init(aw_root, "SAI_GROUP", "Define SAI group");
298    aws->load_xfig("ad_ext_group.fig");
299
300    aws->at("close");
301    aws->callback(AW_POPDOWN);
302    aws->create_button("CLOSE", "CLOSE", "C");
303
304    aws->at("help");
305    aws->callback(makeHelpCallback("ad_extended.hlp"));
306    aws->create_button("HELP", "HELP", "H");
307
308    aws->at("sai");
309    aws->create_button(NULp, AWAR_SAI_NAME);
310
311    aws->at("group");
312    sai_group_sel = awt_create_selection_list_with_input_field(aws, AWAR_SAI_GROUP, "list", "group");
313    refresh_grouplist(aw_root);
314
315    return aws;
316}
317
318AW_window *NT_create_extendeds_window(AW_root *aw_root) {
319    static AW_window_simple *aws = NULp;
320
321    if (!aws) {
322        aws = new AW_window_simple;
323        aws->init(aw_root, "INFO_OF_SAI", "SAI INFORMATION");
324        aws->load_xfig("ad_ext.fig");
325
326        aws->at("close");
327        aws->callback(AW_POPDOWN);
328        aws->create_button("CLOSE", "CLOSE", "C");
329
330        aws->at("help");
331        aws->callback(makeHelpCallback("ad_extended.hlp"));
332        aws->create_button("HELP", "HELP", "H");
333
334        aws->button_length(13);
335
336        aws->at("delete");
337        aws->callback(delete_SAI_cb);
338        aws->create_button("DELETE", "DELETE", "D");
339
340        aws->at("rename");
341        aws->callback(rename_SAI_cb);
342        aws->create_button("RENAME", "RENAME", "R");
343
344        aws->at("copy");
345        aws->callback(copy_SAI_cb);
346        aws->create_button("COPY", "COPY", "C");
347
348        aws->at("remark");
349        aws->callback(edit_SAI_description);
350        aws->create_button("EDIT_COMMENT", "EDIT COMMENT", "R");
351
352        aws->at("group");
353        aws->callback(create_SAI_group_window);
354        aws->create_button("ASSIGN_GROUP", "ASSIGN GROUP", "R");
355
356        aws->at("makespec");
357        aws->callback(copy_SAI_to_species_cb);
358        aws->create_button("COPY_TO_SPECIES", "COPY TO\nSPECIES", "C");
359
360        aws->at("list");
361        awt_create_SAI_selection_list(GLOBAL.gb_main, aws, AWAR_SAI_NAME, true);
362
363        DbScanner *scanner = DbScanner::create(GLOBAL.gb_main, "sai", aws, "info", NULp, NULp, DB_SCANNER, NULp, SPECIES_get_selector());
364        aws->get_root()->awar(AWAR_SAI_NAME)->add_callback(makeRootCallback(map_SAI_to_scanner, scanner));
365    }
366    aws->show();
367    return aws;
368}
Note: See TracBrowser for help on using the repository browser.