source: tags/ms_r16q3/EDIT4/ED4_flags.cxx

Last change on this file was 15290, checked in by westram, 8 years ago
  • add some predefined settings for editor flags
File size: 9.8 KB
Line 
1// ============================================================== //
2//                                                                //
3//   File      : ED4_flags.cxx                                    //
4//   Purpose   : species flag implementation                      //
5//                                                                //
6//   Coded by Ralf Westram (coder@reallysoft.de) in August 2016   //
7//   http://www.arb-home.de/                                      //
8//                                                                //
9// ============================================================== //
10
11#include "ed4_flags.hxx"
12#include "ed4_class.hxx"
13
14#include <item_sel_list.h>
15#include <awt_config_manager.hxx>
16
17#include <aw_awar.hxx>
18#include <aw_root.hxx>
19
20#include <arbdbt.h>
21
22#include <arb_strbuf.h>
23
24using namespace std;
25
26#define MAX_SPECIES_FLAGS 5
27
28#define AWAR_FLAGS_PREFIX         "arb_edit/flags" // in main database
29#define AWAR_FLAGS_ENABLED        AWAR_FLAGS_PREFIX "/display"
30#define AWAR_FLAG_PREFIX_TEMPLATE AWAR_FLAGS_PREFIX "/flag%i"
31#define AWAR_FLAG_ENABLE_TEMPLATE AWAR_FLAG_PREFIX_TEMPLATE "/enable"
32#define AWAR_FLAG_HEADER_TEMPLATE AWAR_FLAG_PREFIX_TEMPLATE "/header"
33#define AWAR_FLAG_FIELD_TEMPLATE  AWAR_FLAG_PREFIX_TEMPLATE "/field"
34
35#define MAX_AWARNAME_LENGTH (8+1+5+1+5+1+6)
36
37inline const char *awarname(const char *awarname_template, int idx) {
38    e4_assert(idx>=0 && idx<MAX_SPECIES_FLAGS);
39    static char buffer[MAX_AWARNAME_LENGTH+1];
40
41#if defined(ASSERTION_USED)
42    int printed =
43#endif
44        sprintf(buffer, awarname_template, idx);
45    e4_assert(printed<=MAX_AWARNAME_LENGTH);
46
47    return buffer;
48}
49
50static void header_changed_cb(AW_root *) {
51    SpeciesFlags::forget();
52    ED4_request_relayout();
53}
54
55static void init_flag_awars() {
56    static bool initialized = false;
57
58    if (!initialized) {
59        AW_root *awr = AW_root::SINGLETON;
60        GBDATA  *db  = GLOBAL_gb_main;
61
62        awr->awar_int(AWAR_FLAGS_ENABLED, 0, db)->add_callback(header_changed_cb);
63
64        for (int i = 0; i<MAX_SPECIES_FLAGS; ++i) {
65            awr->awar_int   (awarname(AWAR_FLAG_ENABLE_TEMPLATE, i), 0, db)->add_callback(header_changed_cb);
66            awr->awar_string(awarname(AWAR_FLAG_HEADER_TEMPLATE, i), 0, db)->add_callback(header_changed_cb);
67            awr->awar_string(awarname(AWAR_FLAG_FIELD_TEMPLATE,  i), 0, db)->add_callback(header_changed_cb);
68        }
69    }
70}
71
72// --------------------------------------------------------------------------------
73
74const char *SpeciesFlag::prepare_itemfield() const {
75    /*! setup DB field for flag (create changekey)
76     * @return fieldname if changekey exists or has been created
77     * otherwise error is exported
78     */
79
80    const char *awar_name     = awarname(AWAR_FLAG_FIELD_TEMPLATE, awar_index);
81    const char *reg_awar_name = get_itemfield_type_awarname(awar_name);
82
83    const char *key   = NULL;
84    GB_ERROR    error = NULL;
85
86    AW_root       *awr      = AW_root::SINGLETON;
87    GBDATA        *gb_main  = GLOBAL_gb_main;
88    ItemSelector&  selector = SPECIES_get_selector();
89
90    if (reg_awar_name) { // field selection was used (normal case) -> create field as specified by user
91        key   = prepare_and_get_selected_itemfield(awr, awar_name, gb_main, selector, FIF_STANDARD);
92        error = GB_incur_error_if(!key);
93    }
94    else { // field was stored in properties -> check changekey
95        key           = awr->awar(awar_name)->read_char_pntr();
96        GB_TYPES type = GBT_get_type_of_changekey(gb_main, key, selector.change_key_path);
97
98        if (type == GB_NONE) { // changekey does not exist -> default to type GB_INT
99            error          = GBT_add_new_changekey_to_keypath(gb_main, key, GB_INT, selector.change_key_path);
100            if (error) key = NULL;
101        }
102    }
103
104    e4_assert(correlated(!key, error));
105    if (error) GB_export_errorf("Failed to prepare flag-field (Reason: %s)", error);
106
107    return key;
108}
109
110// --------------------------------------------------------------------------------
111
112SpeciesFlags *SpeciesFlags::SINGLETON = NULL;
113
114void SpeciesFlags::create_instance() {
115    e4_assert(!SINGLETON);
116    SINGLETON = new SpeciesFlags;
117
118    init_flag_awars();
119
120    {
121        // create shown flags from AWAR state:
122        AW_root *awr = AW_root::SINGLETON;
123
124        if (awr->awar(AWAR_FLAGS_ENABLED)->read_int()) {
125            for (int f = 0; f<MAX_SPECIES_FLAGS; ++f) {
126                if (awr->awar(awarname(AWAR_FLAG_ENABLE_TEMPLATE, f))->read_int()) {
127                    const char *abbr  = awr->awar(awarname(AWAR_FLAG_HEADER_TEMPLATE, f))->read_char_pntr();
128                    const char *field = awr->awar(awarname(AWAR_FLAG_FIELD_TEMPLATE,  f))->read_char_pntr();
129
130                    if (!abbr[0]) abbr = "?";
131
132                    SINGLETON->push_back(SpeciesFlag(abbr, field, f));
133                }
134            }
135        }
136    }
137}
138
139void SpeciesFlags::build_header_text() const {
140    GBS_strstruct buf(30);
141
142    bool first = true;
143    for (SpeciesFlagCiter i = begin(); i != end(); ++i) {
144        if (!first) buf.put(' ');
145        const SpeciesFlag& flag = *i;
146        buf.cat(flag.get_shortname().c_str());
147        first = false;
148    }
149
150    header = buf.release();
151}
152
153void SpeciesFlags::calculate_header_dimensions(AW_device *device, int gc) {
154    int space_width = device->get_string_size(gc, " ", 1);
155    int xpos        = CHARACTEROFFSET; // x-offset of first character of header-text
156
157    const SpeciesFlag *prev_flag = NULL;
158
159    min_flag_distance = INT_MAX;
160
161    for (SpeciesFlagIter i = begin(); i != end(); ++i) {
162        SpeciesFlag&  flag       = *i;
163        const string& shortname  = flag.get_shortname();
164        int           text_width = device->get_string_size(gc, shortname.c_str(), shortname.length());
165
166        flag.set_dimension(xpos, text_width);
167        xpos += text_width+space_width;
168
169        if (prev_flag) {
170            min_flag_distance = std::min(min_flag_distance, int(floor(flag.center_xpos()-prev_flag->center_xpos())));
171        }
172        else { // first
173            min_flag_distance = std::min(min_flag_distance, int(floor(2*flag.center_xpos())));
174        }
175        prev_flag = &flag;
176    }
177
178    pixel_width = xpos - space_width + 1 + 1;       // +1 (pos->width) +1 (avoid character clipping)
179
180    e4_assert(prev_flag);
181    min_flag_distance = std::min(min_flag_distance, int(floor(2*((pixel_width-1)-prev_flag->center_xpos()))));
182}
183
184inline const char *settingName(const char *name, int idx) {
185    e4_assert(idx>=0 && idx<MAX_SPECIES_FLAGS);
186    const int   BUFSIZE = 20;
187    static char buffer[BUFSIZE];
188#if defined(ASSERTION_USED)
189    int printed =
190#endif
191        sprintf(buffer, "%s%i", name, idx);
192    e4_assert(printed<BUFSIZE);
193    return buffer;
194}
195
196static void setup_species_flags_config(AWT_config_definition& cfg) {
197    cfg.add(AWAR_FLAGS_ENABLED, "display");
198    for (int i = 0; i<MAX_SPECIES_FLAGS; ++i) {
199        cfg.add(awarname(AWAR_FLAG_ENABLE_TEMPLATE, i), settingName("enable", i));
200        cfg.add(awarname(AWAR_FLAG_HEADER_TEMPLATE, i), settingName("header", i));
201        cfg.add(awarname(AWAR_FLAG_FIELD_TEMPLATE,  i), settingName("field",  i));
202    }
203}
204
205
206static AWT_predefined_config predefined_flag_setup[] = {
207    { "*curation", "Curation of newly inserted sequences:\n - mark sequence / alignment as bad\n - mark as done (curated)", "display='1';enable0='1';enable1='1';enable2='1';enable3='0';enable4='0';field0='bad_sequence';field1='bad_alignment';field2='curated';header0='bad';header1='align';header2='cur'" },
208    { "*example1", "Example from help (phase1)", "display='1';enable0='1';enable1='1';enable2='1';enable3='0';enable4='0';field0='tocheck';field1='bad_sequence';field2='bad_alignment';field3='fixed';header0='2chk';header1='bad';header2='align';header3='fixed'" },
209    { "*example2", "Example from help (phase2)", "display='1';enable0='0';enable1='0';enable2='1';enable3='1';enable4='0';field0='tocheck';field1='bad_sequence';field2='bad_alignment';field3='fixed';header0='2chk';header1='bad';header2='align';header3='fixed'" },
210    { 0, 0, 0 }
211};
212
213AW_window *ED4_configure_species_flags(AW_root *root, GBDATA *gb_main) {
214    AW_window_simple *aws = new AW_window_simple;
215    aws->init(root, "SPECIES_FLAGS", "Species flags");
216
217    aws->at(10, 10);
218    aws->auto_space(5, 5);
219
220    aws->callback(AW_POPDOWN);
221    aws->create_button("CLOSE", "CLOSE", "C");
222
223    aws->callback(makeHelpCallback("ed4_flags.hlp"));
224    aws->create_button("HELP", "HELP");
225
226    int cfg_x, cfg_y;
227    aws->get_at_position(&cfg_x, &cfg_y);
228
229    aws->at_newline();
230
231    aws->label("Display flags");
232    aws->create_toggle(AWAR_FLAGS_ENABLED);
233
234    aws->at_newline();
235
236    // header will be added at the current position (after looping over flags)
237    const int COLUMNS      = 3;
238    const int HEADERHEIGHT = 20;
239
240    int header_y = aws->get_at_yposition();
241    int header_x[COLUMNS];
242
243    const char *headertext[COLUMNS] = {
244        "on?",
245        "abbreviation",
246        "field to display",
247    };
248
249    aws->at_y(header_y+HEADERHEIGHT);
250
251    for (int i = 0; i<MAX_SPECIES_FLAGS; ++i) {
252        aws->at_newline();
253
254        if (!i) header_x[0] = aws->get_at_xposition();
255        aws->create_toggle(awarname(AWAR_FLAG_ENABLE_TEMPLATE, i));
256
257        if (!i) header_x[1] = aws->get_at_xposition();
258        aws->create_input_field(awarname(AWAR_FLAG_HEADER_TEMPLATE, i), 10);
259
260        if (!i) header_x[2] = aws->get_at_xposition();
261        FieldSelDef field_sel(awarname(AWAR_FLAG_FIELD_TEMPLATE, i), gb_main, SPECIES_get_selector(), FIELD_FILTER_BYTE_WRITEABLE, "flag field", SF_ALLOW_NEW);
262        create_itemfield_selection_button(aws, field_sel, NULL);
263    }
264
265    for (int h = 0; h<COLUMNS; ++h)  {
266        aws->at(header_x[h], header_y);
267        aws->create_autosize_button(0, headertext[h]);
268    }
269
270    aws->at(cfg_x, cfg_y);
271    AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "species_flags", makeConfigSetupCallback(setup_species_flags_config), NULL, predefined_flag_setup);
272
273    return aws;
274}
Note: See TracBrowser for help on using the repository browser.