source: branches/profile/NTREE/NT_ins_col.cxx

Last change on this file was 12803, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : NT_ins_col.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
13#include <RangeList.h>
14#include <arbdbt.h>
15#include <insdel.h>
16#include <aw_window.hxx>
17#include <aw_root.hxx>
18#include <aw_awars.hxx>
19#include <aw_msg.hxx>
20#include <awt_sel_boxes.hxx>
21#include <arb_defs.h>
22
23#define AWAR_INSDEL     "insdel/"
24#define TMP_AWAR_INSDEL "tmp/" AWAR_INSDEL
25
26#define AWAR_INSDEL_AMOUNT    AWAR_INSDEL "nchar"
27#define AWAR_INSDEL_DELETABLE AWAR_INSDEL "characters"
28#define AWAR_INSDEL_RANGE     AWAR_INSDEL "range"
29#define AWAR_INSDEL_SAI       AWAR_INSDEL "sainame"
30#define AWAR_INSDEL_CONTAINS  AWAR_INSDEL "contains"
31#define AWAR_INSDEL_SAI_CHARS AWAR_INSDEL "saichars"
32#define AWAR_INSDEL_AFFECTED  AWAR_INSDEL "affected"
33#define AWAR_INSDEL_WHAT      TMP_AWAR_INSDEL "what"
34#define AWAR_INSDEL_DIRECTION AWAR_INSDEL "direction"
35
36enum SaiContains { CONTAINS, DOESNT_CONTAIN };
37enum InsdelMode { INSERT, DELETE };
38
39class StaticData {
40    char      *ali;
41    RangeList  ranges;
42
43public:
44    StaticData() : ali(NULL) {}
45    StaticData(const StaticData& other) : ali(nulldup(other.ali)), ranges(other.ranges) {}
46    DECLARE_ASSIGNMENT_OPERATOR(StaticData);
47    ~StaticData() { free(ali); }
48
49    GB_ERROR track_ali(GBDATA *gb_main) {
50        freeset(ali, GBT_get_default_alignment(gb_main));
51        return ali ? NULL : "no alignment found";
52    }
53
54    const char *get_ali() const { return ali; }
55
56    const RangeList& get_ranges() const { return ranges; }
57    void set_ranges(const RangeList& new_ranges) { ranges = new_ranges; }
58};
59
60static StaticData SELECTED;
61
62static void cleanup_when_closing(AW_window*) {
63    SELECTED = StaticData();
64}
65
66static int columns_of(const RangeList& ranges) {
67    int count = 0;
68    for (RangeList::iterator r = ranges.begin(); r != ranges.end(); ++r) {
69        count += r->size();
70    }
71    return count;
72}
73
74static void range_count_update_cb(AW_root *root) {
75    UseRange use   = UseRange(root->awar(AWAR_INSDEL_RANGE)->read_int());
76    int      count = 0;
77    switch (use) {
78        case RANGES:         count = SELECTED.get_ranges().size(); break;
79        case SINGLE_COLUMNS: count = columns_of(SELECTED.get_ranges()); break;
80    }
81    root->awar(AWAR_INSDEL_AFFECTED)->write_int(count);
82}
83
84static void range_changed_cb(AW_root *root) {
85    UseRange    use  = UseRange(root->awar(AWAR_INSDEL_RANGE)->read_int());
86    const char *what = NULL;
87    switch (use) {
88        case RANGES:         what = "selected ranges";  break;
89        case SINGLE_COLUMNS: what = "selected columns"; break;
90    }
91    root->awar(AWAR_INSDEL_WHAT)->write_string(what);
92    range_count_update_cb(root);
93}
94
95static GB_ERROR update_RangeList(AW_root *root, GBDATA *gb_main) {
96    const char     *saiName = root->awar(AWAR_INSDEL_SAI)->read_char_pntr();
97    GB_transaction  ta(gb_main);
98    GBDATA         *gb_sai  = GBT_expect_SAI(gb_main, saiName);
99    GB_ERROR        error   = NULL;
100
101    if (!gb_sai) error = GB_await_error();
102    if (!error) error  = SELECTED.track_ali(gb_main);
103
104    if (!error) {
105        GBDATA *gb_data = GBT_find_sequence(gb_sai, SELECTED.get_ali());
106        if (!gb_data) {
107            if (GB_have_error()) error = GB_await_error();
108            else error                 = GBS_global_string("SAI '%s' has no data in alignment '%s'", saiName, SELECTED.get_ali());
109        }
110        else {
111            const char *data = GB_read_char_pntr(gb_data);
112            if (!data) error = GB_await_error();
113            else {
114                const char  *chars    = root->awar(AWAR_INSDEL_SAI_CHARS)->read_char_pntr();
115                SaiContains  contains = SaiContains(root->awar(AWAR_INSDEL_CONTAINS)->read_int());
116
117                SELECTED.set_ranges(build_RangeList_from_string(data, chars, contains == DOESNT_CONTAIN));
118                range_count_update_cb(root);
119            }
120        }
121    }
122    return error;
123}
124
125static void update_RangeList_cb(AW_root *root) {
126    aw_message_if(update_RangeList(root, GLOBAL.gb_main));
127}
128
129void create_insertDeleteColumn_variables(AW_root *root, AW_default props) {
130    root->awar_int   (AWAR_CURSOR_POSITION,  info2bio(0), GLOBAL.gb_main);
131    root->awar_int   (AWAR_INSDEL_AMOUNT,    0,           props)->set_minmax(0, 9999999);
132    root->awar_string(AWAR_INSDEL_DELETABLE, "-.",        props);
133    root->awar_int   (AWAR_INSDEL_RANGE,     RANGES,      props)->add_callback(range_changed_cb);
134
135    root->awar_string(AWAR_INSDEL_SAI,       "",             props)->add_callback(update_RangeList_cb);
136    root->awar_int   (AWAR_INSDEL_CONTAINS,  DOESNT_CONTAIN, props)->add_callback(update_RangeList_cb);
137    root->awar_string(AWAR_INSDEL_SAI_CHARS, "-.",           props)->add_callback(update_RangeList_cb);
138
139    root->awar_int   (AWAR_INSDEL_AFFECTED,  0,      props);
140    root->awar_string(AWAR_INSDEL_WHAT,      "???",  props);
141    root->awar_int   (AWAR_INSDEL_DIRECTION, BEHIND, props);
142
143    range_changed_cb(root);
144    update_RangeList(root, GLOBAL.gb_main);
145}
146
147static void insdel_event(AW_window *aws, AW_CL cl_insdelmode) {
148    GBDATA     *gb_main = GLOBAL.gb_main;
149    InsdelMode  mode    = InsdelMode(cl_insdelmode);
150    AW_root    *root    = aws->get_root();
151
152    long  pos       = bio2info(root->awar(AWAR_CURSOR_POSITION)->read_int());
153    long  nchar     = root->awar(AWAR_INSDEL_AMOUNT)->read_int();
154    const char *deletable = root->awar(AWAR_INSDEL_DELETABLE)->read_char_pntr();
155
156    if (mode == DELETE) nchar = -nchar;
157
158    GB_ERROR error    = GB_begin_transaction(gb_main);
159    if (!error) error = SELECTED.track_ali(gb_main);
160    if (!error) error = ARB_insdel_columns(gb_main, SELECTED.get_ali(), pos, nchar, deletable);
161    if (!error) error = GBT_check_data(gb_main, 0);
162
163    GB_end_transaction_show_error(gb_main, error, aw_message);
164}
165
166static void insdel_sai_event(AW_window *aws, AW_CL cl_insdelmode) {
167    GBDATA   *gb_main = GLOBAL.gb_main;
168    GB_ERROR  error   = GB_begin_transaction(GLOBAL.gb_main);
169    if (!error) error = SELECTED.track_ali(gb_main);
170
171    if (!error) {
172        InsdelMode  mode = InsdelMode(cl_insdelmode);
173        AW_root    *root = aws->get_root();
174
175        switch (mode) {
176            case INSERT: {
177                UseRange    units  = UseRange(root->awar(AWAR_INSDEL_RANGE)->read_int());
178                InsertWhere where  = InsertWhere(root->awar(AWAR_INSDEL_DIRECTION)->read_int());
179                size_t      amount = root->awar(AWAR_INSDEL_AMOUNT)->read_int();
180
181                error = ARB_insert_columns_using_SAI(gb_main, SELECTED.get_ali(), SELECTED.get_ranges(), units, where, amount);
182                break;
183            }
184            case DELETE: {
185                const char *deletable = root->awar(AWAR_INSDEL_DELETABLE)->read_char_pntr();
186
187                error = ARB_delete_columns_using_SAI(gb_main, SELECTED.get_ali(), SELECTED.get_ranges(), deletable);
188                break;
189            }
190        }
191    }
192    if (!error) error = GBT_check_data(gb_main, 0);
193
194    GB_end_transaction_show_error(gb_main, error, aw_message);
195}
196
197AW_window *create_insertDeleteColumn_window(AW_root *root) {
198    static AW_window_simple *aws = 0;
199    if (!aws) {
200        aws = new AW_window_simple;
201
202        aws->init(root, "INSDEL_COLUMNS", "Insert/delete columns");
203
204        aws->load_xfig("insdel.fig");
205        aws->button_length(8);
206
207        aws->callback((AW_CB0)AW_POPDOWN);
208        aws->at("close");
209        aws->create_button("CLOSE", "CLOSE", "C");
210
211        aws->callback(makeHelpCallback("insdel.hlp"));
212        aws->at("help");
213        aws->create_button("HELP", "HELP", "H");
214
215        aws->label_length(27);
216
217        aws->at("pos");
218        aws->label("Sequence Position");
219        aws->create_input_field(AWAR_CURSOR_POSITION, 7);
220
221        aws->at("len");
222        aws->label("How many Characters");
223        aws->create_input_field(AWAR_INSDEL_AMOUNT, 7);
224
225        aws->at("characters");
226        aws->label("Delete Only (% = all)");
227        aws->create_input_field(AWAR_INSDEL_DELETABLE, 7);
228
229        aws->auto_space(10, 0);
230
231        aws->at("actions");
232        aws->callback(insdel_event, (AW_CL)INSERT); aws->create_button("INSERT", "INSERT", "I");
233        aws->callback(insdel_event, (AW_CL)DELETE); aws->create_button("DELETE", "DELETE", "D");
234    }
235    return aws;
236}
237
238AW_window *create_insertDeleteBySAI_window(AW_root *root, GBDATA *gb_main) {
239    static AW_window_simple *aws = 0;
240    if (!aws) {
241        aws = new AW_window_simple;
242
243        aws->init(root, "INSDEL_BY_SAI", "Insert/delete using SAI");
244
245        aws->load_xfig("insdel_sai.fig");
246        aws->button_length(8);
247
248        aws->callback((AW_CB0)AW_POPDOWN);
249        aws->at("close");
250        aws->create_button("CLOSE", "CLOSE", "C");
251
252        aws->callback(makeHelpCallback("insdel_sai.hlp"));
253        aws->at("help");
254        aws->create_button("HELP", "HELP", "H");
255
256        aws->at("select");
257        aws->create_option_menu(AWAR_INSDEL_RANGE, true);
258        aws->insert_option("ranges",  "r", RANGES);
259        aws->insert_option("columns", "c", SINGLE_COLUMNS);
260        aws->update_option_menu();
261
262        aws->button_length(25);
263
264        aws->at("sai");
265        awt_create_SAI_selection_button(gb_main, aws, AWAR_INSDEL_SAI);
266
267        aws->at("contains");
268        aws->create_option_menu(AWAR_INSDEL_CONTAINS, true);
269        aws->insert_option("contains",        "c", CONTAINS);
270        aws->insert_option("doesn't contain", "d", DOESNT_CONTAIN);
271        aws->update_option_menu();
272
273        aws->at("characters");
274        aws->create_input_field(AWAR_INSDEL_SAI_CHARS, 18);
275
276        aws->button_length(18);
277
278        aws->at("affected");
279        aws->create_button(0, AWAR_INSDEL_AFFECTED, 0, "+");
280
281        aws->button_length(7);
282
283        aws->at("delete");
284        aws->callback(insdel_sai_event, (AW_CL)DELETE);
285        aws->create_button("DELETE", "DELETE", "D");
286
287        aws->at("deletable");
288        aws->create_input_field(AWAR_INSDEL_DELETABLE, 7);
289
290        aws->at("insert");
291        aws->callback(insdel_sai_event, (AW_CL)INSERT);
292        aws->create_button("INSERT", "INSERT", "I");
293
294        aws->at("amount");
295        aws->create_input_field(AWAR_INSDEL_AMOUNT, 7);
296
297        aws->at("direction");
298        aws->create_option_menu(AWAR_INSDEL_DIRECTION, true);
299        aws->insert_option("in front of", "f", INFRONTOF);
300        aws->insert_option("behind",      "b", BEHIND);
301        aws->update_option_menu();
302
303        aws->button_length(15);
304        aws->at("what0"); aws->create_button(0, AWAR_INSDEL_WHAT);
305        aws->at("what1"); aws->create_button(0, AWAR_INSDEL_WHAT);
306        aws->at("what2"); aws->create_button(0, AWAR_INSDEL_WHAT);
307
308        aws->on_hide(cleanup_when_closing);
309    }
310    return aws;
311}
Note: See TracBrowser for help on using the repository browser.