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

Last change on this file was 8309, checked in by westram, 12 years ago
  • moved much code into static scope

(partly reverted by [8310])

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : NT_sort.cxx                                       //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "ntree.hxx"
12#include "nt_cb.hxx"
13
14#include <item_sel_list.h>
15#include <aw_awar.hxx>
16#include <arb_progress.h>
17#include <aw_msg.hxx>
18#include <aw_root.hxx>
19#include <arbdbt.h>
20#include <arb_sort.h>
21
22#define NT_RESORT_FILTER (1<<GB_STRING)|(1<<GB_INT)|(1<<GB_FLOAT)
23
24// test
25
26struct customsort_struct {
27    const char *key1;
28    const char *key2;
29    const char *key3;
30};
31
32static int cmpByKey(GBDATA *gbd1, GBDATA *gbd2, const char *field) {
33    GBDATA *gb_field1 = GB_entry(gbd1, field);
34    GBDATA *gb_field2 = GB_entry(gbd2, field);
35
36    int cmp;
37    if (gb_field1) {
38        if (gb_field2) {
39            switch (GB_read_type(gb_field1)) {
40                case GB_STRING: {
41                    const char *s1 = GB_read_char_pntr(gb_field1);
42                    const char *s2 = GB_read_char_pntr(gb_field2);
43
44                    cmp = strcmp(s1, s2);
45                    break;
46                }
47                case GB_FLOAT: {
48                    double d1 = GB_read_float(gb_field1);
49                    double d2 = GB_read_float(gb_field2);
50
51                    cmp = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
52                    break;
53                }
54                case GB_INT: {
55                    int i1 = GB_read_int(gb_field1);
56                    int i2 = GB_read_int(gb_field2);
57
58                    cmp = i1-i2;
59                    break;
60                }
61                default:
62                    cmp = 0; // other field type -> no idea how to compare
63                    break;
64            }
65        }
66        else cmp = -1;           // existing < missing!
67    }
68    else cmp = gb_field2 ? 1 : 0;
69
70    return cmp;
71}
72
73static int resort_data_by_customsub(const void *v1, const void *v2, void *cd_sortBy) {
74    GBDATA            *gbd1   = (GBDATA*)v1;
75    GBDATA            *gbd2   = (GBDATA*)v2;
76    customsort_struct *sortBy = (customsort_struct*)cd_sortBy;
77
78    int cmp = cmpByKey(gbd1, gbd2, sortBy->key1);
79    if (!cmp) {
80        cmp = cmpByKey(gbd1, gbd2, sortBy->key2);
81        if (!cmp) {
82            cmp = cmpByKey(gbd1, gbd2, sortBy->key3);
83        }
84    }
85    return cmp;
86}
87
88
89static GBDATA **gb_resort_data_list;
90static long    gb_resort_data_count;
91
92static void NT_resort_data_base_by_tree(GBT_TREE *tree, GBDATA *gb_species_data) {
93    if (tree) {
94        if (tree->is_leaf) {
95            if (tree->gb_node) {
96                gb_resort_data_list[gb_resort_data_count++] = tree->gb_node;
97            }
98        }
99        else {
100            NT_resort_data_base_by_tree(tree->leftson, gb_species_data);
101            NT_resort_data_base_by_tree(tree->rightson, gb_species_data);
102        }
103    }
104}
105
106
107static GB_ERROR NT_resort_data_base(GBT_TREE *tree, const char *key1, const char *key2, const char *key3) {
108    customsort_struct sortBy;
109
110    sortBy.key1 = key1;
111    sortBy.key2 = key2;
112    sortBy.key3 = key3;
113
114    GB_ERROR error = GB_begin_transaction(GLOBAL_gb_main);
115    if (!error) {
116        GBDATA *gb_sd     = GB_search(GLOBAL_gb_main, "species_data", GB_CREATE_CONTAINER);
117        if (!gb_sd) error = GB_await_error();
118        else {
119            if (tree) {
120                gb_resort_data_count = 0;
121                gb_resort_data_list = (GBDATA **)calloc(sizeof(GBDATA *), GB_nsons(gb_sd) + 256);
122                NT_resort_data_base_by_tree(tree, gb_sd);
123            }
124            else {
125                gb_resort_data_list = GBT_gen_species_array(GLOBAL_gb_main, &gb_resort_data_count);
126                GB_sort((void **)gb_resort_data_list, 0, gb_resort_data_count, resort_data_by_customsub, &sortBy);
127
128            }
129            error = GB_resort_data_base(GLOBAL_gb_main, gb_resort_data_list, gb_resort_data_count);
130            free(gb_resort_data_list);
131        }
132    }
133    return GB_end_transaction(GLOBAL_gb_main, error);
134}
135
136void NT_resort_data_by_phylogeny(AW_window *, AW_CL, AW_CL) {
137    arb_progress  progress("Sorting data");
138    GB_ERROR      error = 0;
139    GBT_TREE     *tree  = nt_get_current_tree_root();
140
141    if (!tree)  error = "Please select/build a tree first";
142    if (!error) error = NT_resort_data_base(tree, 0, 0, 0);
143    if (error) aw_message(error);
144}
145
146static void NT_resort_data_by_user_criteria(AW_window *aw) {
147    arb_progress progress("Sorting data");
148   
149    char *s1 = aw->get_root()->awar("ad_tree/sort_1")->read_string();
150    char *s2 = aw->get_root()->awar("ad_tree/sort_2")->read_string();
151    char *s3 = aw->get_root()->awar("ad_tree/sort_3")->read_string();
152
153    GB_ERROR error = NT_resort_data_base(0, s1, s2, s3);
154    if (error) aw_message(error);
155
156    free(s3);
157    free(s2);
158    free(s1);
159}
160
161void NT_build_resort_awars(AW_root *awr, AW_default aw_def) {
162    awr->awar_string("ad_tree/sort_1", "name",      aw_def);
163    awr->awar_string("ad_tree/sort_2", "name",      aw_def);
164    awr->awar_string("ad_tree/sort_3", "name",      aw_def);
165}
166
167AW_window *NT_build_resort_window(AW_root *awr) {
168    AW_window_simple *aws = new AW_window_simple;
169    aws->init(awr, "SORT_DATABASE", "SORT DATABASE");
170    aws->load_xfig("nt_sort.fig");
171
172    aws->callback((AW_CB0)AW_POPDOWN);
173    aws->at("close");
174    aws->create_button("CLOSE", "CLOSE", "C");
175
176    aws->callback(AW_POPUP_HELP, (AW_CL)"sp_sort_fld.hlp");
177    aws->at("help");
178    aws->create_button("HELP", "HELP", "H");
179
180    aws->at("go");
181    aws->callback((AW_CB0)NT_resort_data_by_user_criteria);
182    aws->create_button("GO", "GO", "G");
183
184    create_selection_list_on_itemfields(GLOBAL_gb_main,
185                                            aws, "ad_tree/sort_1",
186                                            NT_RESORT_FILTER,
187                                            "key1", 0, SPECIES_get_selector(), 20, 10);
188
189    create_selection_list_on_itemfields(GLOBAL_gb_main,
190                                            aws, "ad_tree/sort_2",
191                                            NT_RESORT_FILTER,
192                                            "key2", 0, SPECIES_get_selector(), 20, 10);
193
194    create_selection_list_on_itemfields(GLOBAL_gb_main,
195                                            aws, "ad_tree/sort_3",
196                                            NT_RESORT_FILTER,
197                                            "key3", 0, SPECIES_get_selector(), 20, 10);
198
199    return (AW_window *)aws;
200
201}
Note: See TracBrowser for help on using the repository browser.