source: tags/ms_r16q3/NTREE/NT_join.cxx

Last change on this file was 14786, checked in by westram, 8 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : NT_join.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 <item_sel_list.h>
13#include <awt_sel_boxes.hxx>
14#include <aw_awar.hxx>
15#include <aw_root.hxx>
16#include <aw_msg.hxx>
17#include <arb_progress.h>
18#include <arbdbt.h>
19
20#define AWAR_SPECIES_JOIN_FIELD "/tmp/NT/species_join/field"
21#define AWAR_SPECIES_JOIN_SEP   "/tmp/NT/species_join/separator"
22#define AWAR_SPECIES_JOIN_SEP2  "/tmp/NT/species_join/separator_sequences"
23
24static GB_ERROR nt_species_join(GBDATA *dest, GBDATA *source, int deep, char *sep, char *sep2) {
25    GB_TYPES dtype = GB_read_type(dest);
26    GB_TYPES stype = GB_read_type(source);
27    if (dtype != stype) return 0;
28
29    GB_ERROR error = 0;
30
31    switch (dtype) {
32        case GB_DB:
33            for (GBDATA *gb_source_field = GB_child(source);
34                 !error && gb_source_field;
35                 gb_source_field = GB_nextChild(gb_source_field))
36            {
37                const char *source_field = GB_read_key_pntr(gb_source_field);
38                if (!strcmp(source_field, "name")) continue;
39
40                GBDATA *gb_dest_field = GB_entry(dest, source_field);
41                if (gb_dest_field) { // if destination exists -> recurse
42                    error = nt_species_join(gb_dest_field, gb_source_field, 0, sep, sep2);
43                }
44                else {
45                    GB_TYPES type = GB_read_type(gb_source_field);
46
47                    if (type == GB_DB) {
48                        GBDATA *gb_dest_container     = GB_create_container(dest, source_field);
49                        if (!gb_dest_container) error = GB_await_error();
50                        else    error                 = nt_species_join(gb_dest_container, gb_source_field, 0, sep, sep2);
51                    }
52                    else {
53                        gb_dest_field             = GB_create(dest, source_field, GB_read_type(gb_source_field));
54                        if (!gb_dest_field) error = GB_await_error();
55                        else error                = GB_copy(gb_dest_field, gb_source_field);
56                    }
57                }
58            }
59            break;
60
61        case GB_STRING: {
62            char *sf = GB_read_string(source);
63            char *df = GB_read_string(dest);
64            if (strcmp(sf, df) != 0) {
65                char *s = sep;
66                const char *spacers = " ";
67                if (deep) {
68                    s = sep2;
69                    spacers = ".- ";
70                }
71                int i;
72                // remove trailing spacers;
73                for (i = strlen(df)-1; i>=0; i--) {
74                    if (strchr(spacers, df[i])) df[i] = 0;
75                }
76                // remove leading spacers
77                int end = strlen(sf);
78                for (i=0; i<end; i++) {
79                    if (!strchr(spacers, sf[i])) break;
80                }
81                char *str = new char [strlen(sf) + strlen(df) + strlen(s) + 1];
82                sprintf(str, "%s%s%s", df, s, sf+i);
83                error = GB_write_string(dest, str);
84                delete [] str;
85            }
86            free(sf);
87            free(df);
88            break;
89        }
90        default: {
91            break;
92        }
93    }
94    return error;
95}
96
97static void species_rename_join(AW_window *aww) {
98    char     *field = aww->get_root()->awar(AWAR_SPECIES_JOIN_FIELD)->read_string();
99    char     *sep   = aww->get_root()->awar(AWAR_SPECIES_JOIN_SEP)->read_string();
100    char     *sep2  = aww->get_root()->awar(AWAR_SPECIES_JOIN_SEP2)->read_string();
101    GB_ERROR  error = GB_begin_transaction(GLOBAL.gb_main);
102
103    if (!error) {
104        GB_HASH *hash = GBS_create_hash(1000, GB_MIND_CASE);
105        long     maxs = GBT_count_marked_species(GLOBAL.gb_main);
106
107        arb_progress progress("Joining species", maxs);
108
109        GBDATA *gb_next = 0;
110        for (GBDATA *gb_species = GBT_first_marked_species(GLOBAL.gb_main);
111             gb_species && !error;
112             gb_species = gb_next)
113        {
114            gb_next = GBT_next_marked_species(gb_species);
115
116            GBDATA *gb_field = GB_entry(gb_species, field);
117            if (gb_field) {
118                char   *field_value = GB_read_as_string(gb_field);
119                GBDATA *gb_old      = (GBDATA *)GBS_read_hash(hash, field_value);
120
121                if (!gb_old) {
122                    GBS_write_hash(hash, field_value, (long)gb_species);
123                }
124                else {
125                    error = nt_species_join(gb_old, gb_species, 0, sep, sep2);
126                    if (!error) error = GB_delete(gb_species);
127                }
128                free(field_value);
129            }
130            progress.inc_and_check_user_abort(error);
131        }
132
133        GBS_free_hash(hash);
134    }
135    GB_end_transaction_show_error(GLOBAL.gb_main, error, aw_message);
136
137    free(sep2);
138    free(sep);
139    free(field);
140}
141
142
143AW_window *NT_create_species_join_window(AW_root *root) {
144    static AW_window_simple *aws = 0;
145    if (!aws) {
146        root->awar_string(AWAR_SPECIES_JOIN_FIELD, "name", AW_ROOT_DEFAULT);
147        root->awar_string(AWAR_SPECIES_JOIN_SEP, "#", AW_ROOT_DEFAULT);
148        root->awar_string(AWAR_SPECIES_JOIN_SEP2, "#", AW_ROOT_DEFAULT);
149
150        aws = new AW_window_simple;
151        aws->init(root, "SPECIES_JOIN", "JOIN SPECIES");
152        aws->load_xfig("join_species.fig");
153
154        aws->at("close");
155        aws->callback(AW_POPDOWN);
156        aws->create_button("CLOSE", "CLOSE", "C");
157
158        aws->at("help"); aws->callback(makeHelpCallback("species_join.hlp"));
159        aws->create_button("HELP", "HELP", "H");
160
161        aws->at("sym");
162        aws->create_input_field(AWAR_SPECIES_JOIN_SEP);
163
164        aws->at("symseq");
165        aws->create_input_field(AWAR_SPECIES_JOIN_SEP2);
166
167        aws->at("go");
168        aws->callback(species_rename_join);
169        aws->help_text("species_join.hlp");
170        aws->create_button("GO", "GO", "G");
171
172        create_itemfield_selection_button(aws, FieldSelDef(AWAR_SPECIES_JOIN_FIELD, GLOBAL.gb_main, SPECIES_get_selector(), FIELD_FILTER_STRING_READABLE, "field to compare"), "field");
173    }
174    return aws;
175}
Note: See TracBrowser for help on using the repository browser.