source: tags/svn.1.5.4/NTREE/ad_ext.cxx

Last change on this file was 8031, checked in by westram, 14 years ago
  • editing SAI comments was broken by [5851]
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 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 <db_scanner.hxx>
12#include <aw_window.hxx>
13#include <awt_sel_boxes.hxx>
14#include <aw_awars.hxx>
15#include <aw_msg.hxx>
16#include <aw_root.hxx>
17#include <arbdbt.h>
18#include <arb_strbuf.h>
19
20#define nt_assert(bed) arb_assert(bed)
21
22extern GBDATA *GLOBAL_gb_main;
23
24static void rename_SAI_cb(AW_window *aww) {
25    AW_awar  *awar_sai = aww->get_root()->awar(AWAR_SAI_NAME);
26    char     *sai_name = awar_sai->read_string();
27    GB_ERROR  error    = 0;
28
29    if (!sai_name || !sai_name[0]) error = "Select SAI to rename";
30    else {
31        char *new_name = aw_input("Rename SAI", "Enter new name of SAI", sai_name);
32        if (new_name && new_name[0]) {
33            error = GB_begin_transaction(GLOBAL_gb_main);
34            if (!error) {
35                GBDATA *gb_sai     = GBT_find_SAI(GLOBAL_gb_main, sai_name);
36                if (!gb_sai) error = GBS_global_string("can't find SAI '%s'", sai_name);
37                else {
38                    GBDATA *gb_dest_exists    = GBT_find_SAI(GLOBAL_gb_main, new_name);
39                    if (gb_dest_exists) error = GBS_global_string("There is already a SAI named '%s'", new_name);
40                    else {
41                        error = GBT_write_string(gb_sai, "name", new_name);
42                        if (!error) awar_sai->write_string(new_name);
43                    }
44                }
45            }
46            error = GB_end_transaction(GLOBAL_gb_main, error);
47        }
48        free(new_name);
49    }
50    free(sai_name);
51
52    if (error) aw_message(error);
53}
54
55static void copy_SAI_cb(AW_window *aww) {
56    AW_awar  *awar_sai    = aww->get_root()->awar(AWAR_SAI_NAME);
57    char     *source_name = awar_sai->read_string();
58    GB_ERROR  error       = 0;
59
60    if (!source_name || !source_name[0]) error = "Select SAI to duplicate";
61    else {
62        char *dest_name = aw_input("Copy SAI", "Enter name of new SAI", source_name);
63        if (dest_name && dest_name[0]) {
64            error = GB_begin_transaction(GLOBAL_gb_main);
65            if (!error) {
66                GBDATA *gb_sai_data   = GBT_get_SAI_data(GLOBAL_gb_main);
67                GBDATA *gb_source     = GBT_find_SAI_rel_SAI_data(gb_sai_data, source_name);
68                if (!gb_source) error = GBS_global_string("can't find SAI '%s'", source_name);
69                else {
70                    GBDATA *gb_dest_exists    = GBT_find_SAI_rel_SAI_data(gb_sai_data, dest_name);
71                    if (gb_dest_exists) error = GBS_global_string("There is already a SAI named '%s'", dest_name);
72                    else {
73                        GBDATA *gb_dest     = GB_create_container(gb_sai_data, "extended");
74                        if (!gb_dest) error = GB_await_error();
75                        else {
76                            error             = GB_copy(gb_dest, gb_source);
77                            if (!error) {
78                                error = GBT_write_string(gb_dest, "name", dest_name);
79                                if (!error) awar_sai->write_string(dest_name);
80                            }
81                        }
82                    }
83                }
84            }
85            error = GB_end_transaction(GLOBAL_gb_main, error);
86        }
87        free(dest_name);
88    }
89    free(source_name);
90
91    if (error) aw_message(error);
92}
93
94static void copy_SAI_to_species_cb(AW_window *aww) {
95    AW_root  *aw_root  = aww->get_root();
96    char     *sai_name = aw_root->awar(AWAR_SAI_NAME)->read_string();
97    GB_ERROR  error    = 0;
98
99    if (!sai_name || !sai_name[0]) error = "No SAI selected";
100    else {
101        char *species_name = aw_input("Copy SAI to species", "Enter target species name:", sai_name);
102
103        if (species_name && species_name[0]) {
104            error = GB_begin_transaction(GLOBAL_gb_main);
105
106            if (!error) {
107                GBDATA *gb_species_data = GBT_get_species_data(GLOBAL_gb_main);
108                GBDATA *gb_dest         = GBT_find_species_rel_species_data(gb_species_data, species_name);
109
110                if (gb_dest) error = GBS_global_string("Species '%s' already exists", species_name);
111                else {
112                    GBDATA *gb_sai = GBT_find_SAI(GLOBAL_gb_main, sai_name);
113
114                    if (!gb_sai) error = GBS_global_string("SAI '%s' not found", sai_name);
115                    else {
116                        gb_dest             = GB_create_container(gb_species_data, "species");
117                        if (!gb_dest) error = GB_await_error();
118                        else {
119                            error = GB_copy(gb_dest, gb_sai);
120                            if (!error) {
121                                error = GBT_write_string(gb_dest, "name", species_name);
122                                if (!error) aw_root->awar(AWAR_SPECIES_NAME)->write_string(species_name);
123                            }
124                        }
125                    }
126                }
127            }
128            error = GB_end_transaction(GLOBAL_gb_main, error);
129        }
130        free(species_name);
131    }
132    free(sai_name);
133    if (error) aw_message(error);
134}
135
136static void delete_SAI_cb(AW_window *aww) {
137    char     *sai_name      = aww->get_root()->awar(AWAR_SAI_NAME)->read_string();
138    GB_ERROR  error       = GB_begin_transaction(GLOBAL_gb_main);
139
140    if (!error) {
141        GBDATA *gb_sai = GBT_find_SAI(GLOBAL_gb_main, sai_name);
142        error          = gb_sai ? GB_delete(gb_sai) : "Please select a SAI";
143    }
144    GB_end_transaction_show_error(GLOBAL_gb_main, error, aw_message);
145    free(sai_name);
146}
147
148static void map_SAI_to_scanner(AW_root *aw_root, AW_CL cl_scanner) {
149    GB_transaction  ta(GLOBAL_gb_main);
150    char           *sai_name = aw_root->awar(AWAR_SAI_NAME)->read_string();
151    GBDATA         *gb_sai   = GBT_find_SAI(GLOBAL_gb_main, sai_name);
152
153    map_db_scanner((DbScanner*)cl_scanner, gb_sai, CHANGE_KEY_PATH);
154    free(sai_name);
155}
156
157static void edit_SAI_description(AW_window *aww) {
158    AW_root  *awr      = aww->get_root();
159    char     *sai_name = awr->awar(AWAR_SAI_NAME)->read_string();
160    GB_ERROR  error    = 0;
161
162    if (!sai_name || !sai_name[0]) error = "No SAI selected";
163    else {
164        GBDATA *gb_ali = 0;
165        char   *type    = 0;
166        {
167            GB_transaction  ta(GLOBAL_gb_main);
168            GBDATA         *gb_sai = GBT_find_SAI(GLOBAL_gb_main, sai_name);
169
170            if (!gb_sai) error = GBS_global_string("SAI '%s' not found", sai_name);
171            else {
172                char *ali_name = GBT_get_default_alignment(GLOBAL_gb_main);
173
174                gb_ali = GB_entry(gb_sai, ali_name);
175                if (!gb_ali) error = GBS_global_string("SAI '%s' has no data in alignment '%s'", sai_name, ali_name);
176                else {
177                    GB_clear_error();
178                    type = GBT_read_string(gb_ali, "_TYPE");
179                    if (!type) {
180                        if (GB_have_error()) {
181                            error = GB_await_error();
182                        }
183                        else {
184                            type = strdup("");
185                        }
186                    }
187                }
188            }
189            error = ta.close(error);
190        }
191
192        if (!error) {
193            nt_assert(gb_ali);
194            char *new_type = aw_input("Change SAI description", type);
195            if (new_type) {
196                GB_transaction t2(GLOBAL_gb_main);
197
198                if (new_type[0]) {
199                    error = GBT_write_string(gb_ali, "_TYPE", new_type);
200                }
201                else { // empty description -> delete
202                    GBDATA *gb_type = GB_entry(gb_ali, "_TYPE");
203                    if (gb_type) error = GB_delete(gb_type);
204                }
205                error = t2.close(error);
206                free(new_type);
207            }
208        }
209
210        free(type);
211    }
212
213    if (error) aw_message(error);
214}
215
216static char *getExistingSAIgroups() {
217    // scan SAIs for existing groups.
218    // return a string of ';'-separated group names (or NULL)
219
220    GB_HASH       *groups = GBS_create_hash(GBT_get_SAI_count(GLOBAL_gb_main), GB_MIND_CASE);
221    GBS_strstruct *out    = GBS_stropen(1000);
222    int            count  = 0;
223    GB_transaction ta(GLOBAL_gb_main);
224
225    for (GBDATA *gb_sai = GBT_first_SAI(GLOBAL_gb_main); gb_sai; gb_sai = GBT_next_SAI(gb_sai)) {
226        const char *group = GBT_read_char_pntr(gb_sai, "sai_group");
227        if (group && !GBS_read_hash(groups, group)) {
228            GBS_strcat(out, group);
229            GBS_chrcat(out, ';');
230            GBS_write_hash(groups, group, 1);
231            count++;
232        }
233    }
234
235    char *result = 0;
236    if (count>0) {
237        GBS_str_cut_tail(out, 1); // truncate final ';'
238        result = GBS_strclose(out);
239    }
240    else {
241        GBS_strforget(out);
242    }
243    GBS_free_hash(groups);
244
245    return result;
246}
247
248static void assign_SAI_to_group(AW_window *aww) {
249    AW_root  *awr      = aww->get_root();
250    char     *sai_name = awr->awar(AWAR_SAI_NAME)->read_string();
251    GB_ERROR  error    = 0;
252
253    if (!sai_name || !sai_name[0]) error = "No SAI selected";
254    else {
255        GBDATA *gb_sai;
256        {
257            GB_transaction ta(GLOBAL_gb_main);
258            gb_sai = GBT_find_SAI(GLOBAL_gb_main, sai_name);
259        }
260
261        if (!gb_sai) error = GBS_global_string("SAI '%s' not found", sai_name);
262        else {
263            bool        has_group = true;
264            const char *group     = GBT_read_char_pntr(gb_sai, "sai_group");
265            if (!group) {
266                group     = "default_group";
267                has_group = false;
268            }
269
270            char *new_group;
271            {
272                char *existingGroups = getExistingSAIgroups();
273                if (existingGroups) {
274                    new_group = aw_string_selection("Assign SAI to group", "Enter group name:", group, existingGroups, NULL, NULL);
275                    free(existingGroups);
276                }
277                else {
278                    new_group = aw_input("Assign SAI to group", "Enter group name:", group);
279                }
280            }
281
282            if (new_group) {
283                GB_transaction t2(GLOBAL_gb_main);
284                if (new_group[0]) error = GBT_write_string(gb_sai, "sai_group", new_group);
285                else if (has_group) {
286                    GBDATA *gb_group = GB_entry(gb_sai, "sai_group");
287                    if (gb_group) error = GB_delete(gb_group);
288                }
289            }
290        }
291    }
292
293    if (error) aw_message(error);
294    free(sai_name);
295}
296
297AW_window *NT_create_extendeds_window(AW_root *aw_root)
298{
299    static AW_window_simple *aws = 0;
300
301    if (!aws) {
302        aws = new AW_window_simple;
303        aws->init(aw_root, "INFO_OF_SAI", "SAI INFORMATION");
304        aws->load_xfig("ad_ext.fig");
305
306        aws->callback((AW_CB0)AW_POPDOWN);
307        aws->at("close");
308        aws->create_button("CLOSE", "CLOSE", "C");
309
310        aws->callback(AW_POPUP_HELP, (AW_CL)"ad_extended.hlp");
311        aws->at("help");
312        aws->create_button("HELP", "HELP", "H");
313
314        aws->button_length(13);
315
316        aws->at("delete");
317        aws->callback(delete_SAI_cb);
318        aws->create_button("DELETE", "DELETE", "D");
319
320        aws->at("rename");
321        aws->callback(rename_SAI_cb);
322        aws->create_button("RENAME", "RENAME", "R");
323
324        aws->at("copy");
325        aws->callback(copy_SAI_cb);
326        aws->create_button("COPY", "COPY", "C");
327
328        aws->at("remark");
329        aws->callback(edit_SAI_description);
330        aws->create_button("EDIT_COMMENT", "EDIT COMMENT", "R");
331
332        aws->at("group");
333        aws->callback(assign_SAI_to_group);
334        aws->create_button("ASSIGN_GROUP", "ASSIGN GROUP", "R");
335
336        aws->at("makespec");
337        aws->callback(copy_SAI_to_species_cb);
338        aws->create_button("COPY_TO_SPECIES", "COPY TO\nSPECIES", "C");
339
340        aws->at("list");
341        awt_create_selection_list_on_extendeds(GLOBAL_gb_main, (AW_window *)aws, AWAR_SAI_NAME);
342
343        DbScanner *scanner = create_db_scanner(GLOBAL_gb_main, aws, "info", 0, 0, 0, DB_SCANNER, 0, 0, 0, SPECIES_get_selector());
344        aws->get_root()->awar(AWAR_SAI_NAME)->add_callback(map_SAI_to_scanner, (AW_CL)scanner);
345    }
346    aws->show();
347    return aws;
348}
Note: See TracBrowser for help on using the repository browser.