ARB
ED4_flags.cxx
Go to the documentation of this file.
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 
24 using 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 40
36 
37 inline 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);
46 
47  return buffer;
48 }
49 
50 static void header_changed_cb(AW_root *) {
53 }
54 
55 static void init_flag_awars() {
56  static bool initialized = false;
57 
58  if (!initialized) {
60  GBDATA *db = ED4_ROOT->get_gb_main();
61 
63 
64  for (int i = 0; i<MAX_SPECIES_FLAGS; ++i) {
68  }
69  }
70 }
71 
72 // --------------------------------------------------------------------------------
73 
74 const char *SpeciesFlag::prepare_itemfield() const {
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 = NULp;
85 
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 = NULp;
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 
112 SpeciesFlags *SpeciesFlags::SINGLETON = NULp;
113 
114 void 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:
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 
139 void 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 
154  int space_width = device->get_string_size(gc, SizedCstr(" ", 1));
155  int xpos = CHARACTEROFFSET; // x-offset of first character of header-text
156 
157  const SpeciesFlag *prev_flag = NULp;
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, SizedCstr(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 
184 inline 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 
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 
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  { NULp, NULp, NULp }
211 };
212 
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();
262  create_itemfield_selection_button(aws, field_sel, NULp);
263  }
264 
265  for (int h = 0; h<COLUMNS; ++h) {
266  aws->at(header_x[h], header_y);
267  aws->create_autosize_button(NULp, 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), NULp, predefined_flag_setup);
272 
273  return aws;
274 }
GB_TYPES type
void add(const char *awar_name, const char *config_name)
static void forget()
Definition: ed4_flags.hxx:98
void at(int x, int y)
Definition: AW_at.cxx:93
void ED4_request_relayout()
void AWT_insert_config_manager(AW_window *aww, AW_default default_file_, const char *id, const StoreConfigCallback &store_cb, const RestoreConfigCallback &load_or_reset_cb, const char *macro_id, const AWT_predefined_config *predef)
long read_int() const
Definition: AW_awar.cxx:187
void set_dimension(int xpos_, int width_)
Definition: ed4_flags.hxx:47
ED4_root * ED4_ROOT
Definition: ED4_main.cxx:48
STL namespace.
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
AW_window * ED4_configure_species_flags(AW_root *root, GBDATA *gb_main)
Definition: ED4_flags.cxx:213
#define MAX_AWARNAME_LENGTH
Definition: ED4_flags.cxx:35
#define MAX_SPECIES_FLAGS
Definition: ED4_flags.cxx:26
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
#define e4_assert(bed)
Definition: ed4_class.hxx:11
GB_ERROR GB_incur_error_if(bool error_may_occur)
Definition: arb_msg.h:56
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:234
static AWT_predefined_config predefined_flag_setup[]
Definition: ED4_flags.cxx:206
void create_itemfield_selection_button(AW_window *aws, const FieldSelDef &selDef, const char *at)
static bool initialized
Definition: AW_advice.cxx:36
const char * read_char_pntr() const
Definition: AW_awar.cxx:171
static AW_root * SINGLETON
Definition: aw_root.hxx:102
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
SpeciesFlagList::iterator SpeciesFlagIter
Definition: ed4_flags.hxx:68
#define AWAR_FLAG_HEADER_TEMPLATE
Definition: ED4_flags.cxx:32
int get_string_size(int gc, long textlen) const
Definition: AW_device.cxx:443
const char * awarname(const char *awarname_template, int idx)
Definition: ED4_flags.cxx:37
#define AWAR_FLAG_ENABLE_TEMPLATE
Definition: ED4_flags.cxx:31
SpeciesFlagList::const_iterator SpeciesFlagCiter
Definition: ed4_flags.hxx:69
GBDATA * get_gb_main() const
Definition: ed4_class.hxx:1420
#define AWAR_FLAG_FIELD_TEMPLATE
Definition: ED4_flags.cxx:33
const char * change_key_path
Definition: items.h:64
static void error(const char *msg)
Definition: mkptypes.cxx:96
const char * prepare_itemfield() const
Definition: ED4_flags.cxx:74
static void header_changed_cb(AW_root *)
Definition: ED4_flags.cxx:50
#define CHARACTEROFFSET
Definition: ed4_defs.hxx:110
const char * prepare_and_get_selected_itemfield(AW_root *awr, const char *awar_name, GBDATA *gb_main, const ItemSelector &itemtype, FailIfField failIf)
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
GB_TYPES GBT_get_type_of_changekey(GBDATA *gb_main, const char *field_name, const char *change_key_path)
Definition: adChangeKey.cxx:34
const std::string & get_shortname() const
Definition: ed4_flags.hxx:44
const char * settingName(const char *name, int idx)
Definition: ED4_flags.cxx:184
long int flag
Definition: f2c.h:39
Definition: arbdb.h:63
GB_ERROR GB_export_errorf(const char *templat,...)
Definition: arb_msg.cxx:264
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:580
void calculate_header_dimensions(AW_device *device, int gc)
Definition: ED4_flags.cxx:153
ItemSelector & SPECIES_get_selector()
Definition: species.cxx:139
GB_ERROR GBT_add_new_changekey_to_keypath(GBDATA *gb_main, const char *name, int type, const char *keypath)
Definition: adChangeKey.cxx:87
double center_xpos() const
Definition: ed4_flags.hxx:60
#define NULp
Definition: cxxforward.h:97
#define AWAR_FLAGS_ENABLED
Definition: ED4_flags.cxx:29
static void setup_species_flags_config(AWT_config_definition &cfg)
Definition: ED4_flags.cxx:196
GB_TYPES
Definition: arbdb.h:62
#define BUFSIZE
GBDATA * gb_main
Definition: adname.cxx:33
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:570
#define min(a, b)
Definition: f2c.h:153
static void init_flag_awars()
Definition: ED4_flags.cxx:55
#define AW_ROOT_DEFAULT
Definition: aw_base.hxx:106
CONSTEXPR long FIELD_FILTER_BYTE_WRITEABLE
Definition: item_sel_list.h:44
Definition: arbdb.h:66
const char * get_itemfield_type_awarname(const char *itemfield_awarname)