63 void call(
void (*aPizza)(
TreeNode*))
const;
72 if (next) next->
call(aPizza);
90 *extra_marked_species = (
new Store_species(node))->
add(*extra_marked_species);
96 node = node->get_rightson();
115 father = node->get_father();
127 int use_species_aside,
130 int *marked_at_right)
167 *marked_at_right = marked_at_left;
177 *marked_at_right = 0;
182 if (marked_at_left<use_species_aside) {
188 int step_over = marked_at_left+1;
189 int then_mark = use_species_aside-marked_at_left;
191 while (step_over--) {
196 while (leaf_at_left && then_mark--) {
204 while (marked_back) {
205 memfile.
put(CFG_SEP);
215 marked_at_left = use_species_aside;
218 *auto_mark = use_species_aside;
221 memfile.
put(CFG_SEP);
226 *marked_at_right = marked_at_left+1;
233 memfile.
put(CFG_SEP);
244 int right_of_leftson;
245 long nspecies=
nt_build_conf_string_rek(used, tree->get_leftson(), memfile, extra_marked_species, use_species_aside, auto_mark, marked_at_left, &right_of_leftson);
246 nspecies +=
nt_build_conf_string_rek(used, tree->get_rightson(), memfile, extra_marked_species, use_species_aside, auto_mark, right_of_leftson, marked_at_right);
249 memfile.
put(CFG_SEP);
268 const char *sep = strchr(key, 1);
273 if (!last_group_name || strncmp(key, last_group_name, sep-key)) {
274 if (last_group_name) {
275 sai_middle.
put(CFG_SEP);
278 sai_middle.
put(CFG_SEP);
279 sai_middle.
cat(
"FSAI:");
280 sai_middle.
ncat(key, sep-key);
283 sai_middle.
put(CFG_SEP);
285 sai_middle.
cat(sep+1);
306 bool wantedInTop =
false;
307 for (
unsigned s = 0; !wantedInTop &&
s<topAreaSai.
size(); ++
s) {
308 wantedInTop = strcmp(name, topAreaSai[
s]) == 0;
318 char *cn =
new char[strlen(gn) + strlen(name) + 2];
319 sprintf(cn,
"%s%c%s", gn, 1, name);
329 for (
unsigned s = 0;
s<topAreaSai.
size(); ++
s) {
332 topfile.
put(CFG_SEP);
334 topfile.
cat(topAreaSai[s]);
339 middlefile.
put(CFG_SEP);
340 middlefile.
cat(
"GSAI-Maingroup");
345 middlefile.
put(CFG_SEP);
350 middlefile.
put(CFG_SEP);
359 file.
cat(
"FMore Sequences");
387 GBT_config cfg(gb_main, selectionName, error);
390 size_t unknown_species = 0;
391 bool refresh =
false;
411 for (
int area = 0; area<=1 && !
error; ++area) {
423 int newmark = oldmark;
436 if (newmark != oldmark) {
449 if (unknown_species>0 && !error) error =
GBS_global_string(
"configuration '%s' contains %zu unknown species", selectionName, unknown_species);
473 if (gb_configuration) {
477 error = ta.
close(error);
491 bool nonexisting_config =
false;
495 if (gb_configuration) {
496 gb_target_commment =
GB_entry(gb_configuration,
"comment");
499 nonexisting_config =
true;
504 if (gb_target_commment) {
506 awar_comment->
map(gb_target_commment);
511 awar_comment->
unmap();
533 awar_comment->
unmap();
540 if (gb_configuration) {
548 else if (!config[0]) {
551 error =
"Please select an existing species selection to edit its comment";
562 typedef map<AW_awar*, AW_awar*> CorrespondingAwarMap;
563 static CorrespondingAwarMap corresponding;
564 typedef CorrespondingAwarMap::iterator CorrespondingIter;
566 CorrespondingIter corr_selection = corresponding.find(awar_selection);
567 CorrespondingIter corr_comment = corresponding.find(awar_comment);
569 if (corr_selection == corr_comment) {
570 arb_assert(corr_selection == corresponding.end());
572 if (install_callbacks) {
578 corresponding[awar_comment] = awar_selection;
579 corresponding[awar_selection] = awar_comment;
582 #if defined(ASSERTION_USED)
585 arb_assert(corr_selection != corresponding.end() && corr_selection->second == awar_comment);
586 arb_assert(corr_comment != corresponding.end() && corr_comment->second == awar_selection);
594 if (!conf_name || !conf_name[0]) error =
"no config name given";
596 if (use_species_aside==-1) {
597 static int last_used_species_aside = 3;
600 char *use_species =
aw_input(
"How many extra species to view aside marked:", val);
601 if (use_species) use_species_aside = atoi(use_species);
605 if (use_species_aside<1) error =
"illegal number of 'species aside'";
606 else last_used_species_aside = use_species_aside;
627 if (use_species_aside) {
632 nt_build_conf_string_rek(used, tree, middlefile, &extra_marked_species, use_species_aside, &auto_mark, use_species_aside, &marked_at_right);
633 if (extra_marked_species) {
635 delete extra_marked_species;
639 int dummy_1=0, dummy_2;
652 GBT_config previous(gb_main, conf_name, error);
655 const char *prevComment =
NULp;
656 const char *comment =
NULp;
657 bool warnIfSavingDefault =
true;
660 prevComment =
"This configuration will be OVERWRITTEN each time\nARB_EDIT4 is started w/o specifying a config!\n---";
661 comment =
"created for ARB_EDIT4";
662 warnIfSavingDefault =
false;
668 comment =
"updated manually";
672 comment =
"created manually";
678 comment =
"created by importer";
683 if (prevComment && !prevComment[0]) prevComment =
NULp;
700 error = newcfg.
save(gb_main, conf_name, warnIfSavingDefault);
718 char *new_name =
aw_input(
"Rename selection",
"Enter the new name of the selection", old_name);
728 if (gb_existing_cfg) err =
GBS_global_string(
"There is already a selection named '%s'", new_name);
737 else err =
"Selection has no name";
739 else err =
"Can't find that selection";
756 #pragma GCC diagnostic push
757 #if (GCC_VERSION_CODE<700)
758 #pragma GCC diagnostic ignored "-Wstrict-overflow" // gcc 6.x produces a bogus overflow warning (gcc 7.x is smart enough)
764 if (i1>i2)
swap(i1, i2);
765 arb_assert(i1<i2 && i1>=0 && i2<
int(config.size()));
770 if (!error) error = c1.
saveAsOver(gb_main, config[i1], config[i2],
false);
771 if (!error) error = c2.
saveAsOver(gb_main, config[i2], config[i1],
false);
772 if (!error) config.swap(i1, i2);
777 #pragma GCC diagnostic pop
785 if (selected && selected[0]) {
789 case ARM_TOP: target_idx = 0;
break;
790 case ARM_UP: target_idx = source_idx-1;
break;
791 case ARM_DOWN: target_idx = source_idx+1;
break;
795 int entries = sellist->
size();
796 target_idx = (target_idx+entries)%entries;
806 if (source_idx<target_idx) {
807 for (
int i = source_idx+1; i<=target_idx; ++i) {
811 else if (source_idx>target_idx) {
812 for (
int i = source_idx-1; i>=target_idx; --i) {
817 error = ta.
close(error);
820 awar_config->
touch();
831 bool removedDatedLines =
false;
832 RegExpr datedLine(
"^([A-Z][a-z]{2}\\s){2}[0-9]+\\s([0-9]{2}:){2}[0-9]{2}\\s[0-9]{4}:\\s",
false);
833 for (
int i = line.
size()-1; i >= 0; --i) {
838 removedDatedLines =
true;
842 if (!removedDatedLines) line.
clear();
869 AW_awar *awar_counter_label = awr->
awar_string(awarname_buttontext,
"unknown", gb_main);
886 AW_window_simple *aws =
new AW_window_simple;
889 aws->load_xfig(
"nt_selection.fig");
893 aws->create_button(
"CLOSE",
"CLOSE",
"C");
897 aws->create_button(
"HELP",
"HELP",
"H");
907 aws->create_autosize_button(
"CLEAR",
"Clear",
"l");
912 aws->button_length(8);
917 const char *new_id =
"STORE";
918 aws->create_button(new_id,
"STORE",
"S");
922 aws->alias_remote_command(old_id, new_id);
927 aws->create_button(
"EXTRACT",
"EXTRACT",
"E");
931 aws->create_button(
"MARK",
"MARK",
"M");
935 aws->create_button(
"UNMARK",
"UNMARK",
"U");
939 aws->create_button(
"INVERT",
"INVERT",
"I");
943 aws->create_button(
"COMBINE",
"COMBINE",
"C");
947 aws->create_button(
"DELETE",
"DELETE",
"D");
951 aws->create_button(
"RENAME",
"RENAME",
"R");
953 aws->button_length(0);
967 static bool fold_group(
TreeNode *
tree,
const char *groupName) {
971 fprintf(stderr,
"group='%s' groupName='%s'\n", tree->
name, groupName);
972 if (strcmp(tree->
name, groupName) == 0) {
986 fold_group(tree->get_leftson(), groupName) ||
987 fold_group(tree->get_rightson(), groupName);
992 void TEST_build_conf_string() {
1037 TEST_EXPECT_EQUAL(memfile.get_data(),
"\1Gupper\1LCloButy2\1E\1Glower\1Glow1\1LCurCitre\1LCorAquat\1LCloPaste\1E\1Glow2\1LCloTyro4\1E\1E");
1053 TEST_EXPECT_EQUAL(memfile.get_data(),
"\1Gupper\1LCloButy2\1E\1Glower\1Flow1\1LCurCitre\1LCorAquat\1LCloPaste\1E\1Glow2\1LCloTyro4\1E\1E");
1067 TEST_EXPECT_EQUAL(memfile.get_data(),
"\1Gupper\1LCloTyro3\1LCloButyr\1LCloButy2\1LCloBifer\1LCloInnoc\1E\1Glower\1Flow1\1LCytAquat\1LCurCitre\1LCorAquat\1LCelBiazo\1LCorGluta\1LCloCarni\1LCloPaste\1E\1Glow2\1Gtwoleafs\1LCloTyrob\1LCloTyro2\1E\1LCloTyro4\1E\1E");
1072 delete extra_marked_species;
1085 TEST_EXPECT_EQUAL(memfile.get_data(),
"\1FMore Sequences\1LCorAquat\1LCurCitre\1LCloButy2\1LCloPaste\1LCloTyro4\1E");
1092 TEST_EXPECT_EQUAL(memfile.get_data(),
"\1FMore Sequences\1LCorAquat\1LCloButy2\1LCloTyro4\1E");
1105 TEST_EXPECT_EQUAL(memfile.get_data(),
"\1GSAI-Maingroup\1FSAI:SAI's\1SPOS_VAR_BY_PARSIMONY\1E\1FSAI:special\1SECOLI\1E\1E");
1114 #endif // UNIT_TESTS
GB_HASH * GBT_create_marked_species_hash(GBDATA *gb_main)
void GBS_hash_do_const_sorted_loop(const GB_HASH *hs, gb_hash_const_loop_type func, gbs_hash_compare_function sorter, void *client_data)
GBDATA * GB_open(const char *path, const char *opent)
static void init_awars_and_callbacks(AW_root *awr, const SelectionAdmin *selection, bool install_callbacks)
void cut_tail(size_t byte_count)
virtual const char * get_selection_awarname() const =0
void button_length(int length)
GBDATA * GBT_first_marked_species(GBDATA *gb_main)
Store_species(TreeNode *aNode)
#define implicated(hypothesis, conclusion)
long GBS_write_hash(GB_HASH *hs, const char *key, long val)
GB_ERROR GBT_restore_marked_species(GBDATA *gb_main, const char *stored_marked)
GB_ERROR GB_write_string(GBDATA *gbd, const char *s)
long GBT_mark_all(GBDATA *gb_main, int flag)
static const int MIDDLE_AREA
Store_species * add(Store_species *list)
virtual const char * get_name_of_tree() const =0
char * ARB_strdup(const char *str)
TreeNode * GBT_read_tree(GBDATA *gb_main, const char *tree_name, TreeRoot *troot)
virtual void speciesSelection_deleted_cb(const char *name) const =0
static const int TOP_AREA
const char * GBS_global_string(const char *templat,...)
static void nt_delete_configuration(AW_window *aww, AW_DB_selection *dbsel, const SelectionAdmin *selection)
void AW_POPDOWN(AW_window *window)
void GBS_free_hash(GB_HASH *hs)
TreeNode * getNode() const
void cat(const char *from)
static void unmark_species(TreeNode *node)
GB_ERROR GBT_link_tree(TreeNode *tree, GBDATA *gb_main, bool show_status, int *zombies, int *duplicates)
char buffer[MESSAGE_BUFFERSIZE]
static void update_marked_counter_label(GBDATA *gb_species_data, AW_awar *awar_counter_label)
static void nt_build_sai_string(GBDATA *gb_main, const char *topAreaSaiList, GBS_strstruct &topfile, GBS_strstruct &middlefile)
#define DEFAULT_CONFIGURATION
AW_awar * add_callback(const RootCallback &cb)
GB_ERROR GB_delete(GBDATA *&source)
struct Unfixed_cb_parameter * UNFIXED
const char * read_char_pntr() const
static void nt_build_conf_marked(GBDATA *gb_main, GB_HASH *used, GBS_strstruct &file)
void to_array(StrArray &array, bool values)
static AW_root * SINGLETON
WindowCallback makeHelpCallback(const char *helpfile)
#define TEST_EXPECT(cond)
char * GBT_read_string(GBDATA *gb_container, const char *fieldpath)
virtual const char * get_selectionComment_awarname() const =0
GBDATA * GB_create(GBDATA *father, const char *key, GB_TYPES type)
long GB_number_of_subentries(GBDATA *gbd)
static void nt_rename_configuration(AW_window *aww, const SelectionAdmin *selection)
GBT_CONFIG_ITEM_TYPE type
static void clear_comment_cb(AW_window *aww, const SelectionAdmin *selection)
void help_text(const char *id)
#define TEST_REJECT_NULL(n)
int get_index_of(const AW_scalar &searched_value)
const char * get_comment() const
static void error(const char *msg)
GBDATA * GB_get_root(GBDATA *gbd)
#define AWAR_TREE_REFRESH
#define NO_CONFIG_SELECTED
const RegMatch * match(const std::string &versus, size_t offset=0) const
void set_comment(const char *newComment)
GBDATA * GBT_next_marked_species(GBDATA *gb_species)
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
GB_ERROR save(GBDATA *gb_main, const char *name, bool warnIfSavingDefault) const
size_t GBS_hash_elements(const GB_HASH *hs)
virtual void speciesSelection_renamed_cb(const char *old_name, const char *new_name) const =0
AW_DB_selection * awt_create_CONFIG_selection_list(GBDATA *gb_main, AW_window *aws, const char *varname)
GBDATA * GBT_first_SAI_rel_SAI_data(GBDATA *gb_sai_data)
static int nt_build_conf_string_rek(GB_HASH *used, TreeNode *tree, GBS_strstruct &memfile, Store_species **extra_marked_species, int use_species_aside, int *auto_mark, int marked_at_left, int *marked_at_right)
static SearchTree * tree[SEARCH_PATTERNS]
int GB_read_flag(GBDATA *gbd)
char * read_string() const
AW_window * create_species_selection_window(AW_root *root, const SelectionAdmin *selection)
GB_ERROR saveAsOver(GBDATA *gb_main, const char *name, const char *oldName, bool warnIfSavingDefault) const
AW_awar * awar(const char *awar)
void awt_create_order_buttons(AW_window *aws, awt_orderfun reorder_cb, AW_CL cl_user)
char * GBS_log_action_to(const char *comment, const char *action, bool stamp)
GBDATA * GBT_find_configuration(GBDATA *gb_main, const char *name)
void call(void(*aPizza)(TreeNode *)) const
static AW_window_menu_modes_opengl * awm
long GBT_count_marked_species(GBDATA *gb_main)
static void reorder_configs_cb(AW_window *aww, awt_reorder_mode mode, AW_DB_selection *sel)
#define TEST_EXPECT_ZERO(cond)
void extract_species_selection(GBDATA *gb_main, const char *selectionName, SelectionExtractType ext_type)
const std::string * has_failed() const
char * GBT_join_strings(const CharPtrArray &strings, char separator)
GBDATA * GBT_next_SAI(GBDATA *gb_sai)
void ncat(const char *from, size_t count)
#define TEST_EXPECT_NULL(n)
GB_ERROR close(GB_ERROR error)
void GB_write_flag(GBDATA *gbd, long flag)
GB_ERROR GBT_write_string(GBDATA *gb_container, const char *fieldpath, const char *content)
const GBT_config_item & nextItem(GB_ERROR &error)
virtual const char * get_toparea_SAIs() const =0
void move_selection(int offset)
static TreeNode * left_neighbour_leaf(TreeNode *node)
const char * get_awar_name() const
int GB_read_byte(GBDATA *gbd)
AW_awar * map(const char *awarn)
char * GB_read_string(GBDATA *gbd)
GB_ERROR GB_write_byte(GBDATA *gbd, int i)
static void nt_store_configuration(AW_window *, const SelectionAdmin *selection)
#define TEST_EXPECT_NO_ERROR(call)
void aw_message(const char *msg)
int GBS_HCF_sortedByKey(const char *k0, long dummy_1x, const char *k1, long dummy_2x)
static TreeNode * rightmost_leaf(TreeNode *node)
GBDATA * GBT_find_species(GBDATA *gb_main, const char *name)
void create_species_selection_button(AW_window *awm, WindowCallback wcb, const char *macro_id, const char *awarname_buttontext, GBDATA *gb_main)
GB_ERROR write_string(const char *aw_string)
void GBT_split_string(ConstStrArray &dest, const char *namelist, const char *separator, SplitMode mode)
GB_ERROR GB_ensure_callback(GBDATA *gbd, GB_CB_TYPE type, const DatabaseCallback &dbcb)
const char * get_data() const
GBDATA * GBT_find_SAI_rel_SAI_data(GBDATA *gb_sai_data, const char *name)
int GB_get_transaction_level(GBDATA *gbd)
static void nt_extract_configuration(UNFIXED, const SelectionAdmin *selection, SelectionExtractType ext_type)
virtual const char * get_macro_suffix() const =0
long GBT_get_species_count(GBDATA *gb_main)
GB_ERROR create_species_selection(const SelectionAdmin &selection, const char *conf_name, int use_species_aside, SelectionCreation creation)
static void mark_species(TreeNode *node, Store_species **extra_marked_species)
GB_transaction ta(gb_var)
void callback(const WindowCallback &cb)
static void config_comment_changed_cb(AW_root *root, const SelectionAdmin *selection)
void destroy(TreeNode *that)
virtual const char * get_window_title() const =0
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
GBDATA * GBT_get_SAI_data(GBDATA *gb_main)
GBDATA * GB_search(GBDATA *gbd, const char *fieldpath, GB_TYPES create)
static void selected_config_changed_cb(AW_root *root, const SelectionAdmin *selection)
char * aw_input(const char *title, const char *prompt, const char *default_input)
void GBT_splitNdestroy_string(ConstStrArray &names, char *&namelist, const char *separator, SplitMode mode)
virtual GBDATA * get_gb_main() const =0
#define TEST_EXPECT_EQUAL(expr, want)
static GB_ERROR swap_configs(GBDATA *gb_main, StrArray &config, int i1, int i2)
static void nt_build_sai_string_by_hash(const char *key, long, void *cd_sai_builder)
bool is_normal_group() const
long GBS_read_hash(const GB_HASH *hs, const char *key)
GBDATA * GB_entry(GBDATA *father, const char *key)
size_t get_position() const
AW_selection_list * get_sellist()
void aw_message_if(GB_ERROR error)
void GB_close(GBDATA *gbd)
void set_definition(int area, char *new_def)
const char * last_group_name
GBS_strstruct & sai_middle
GB_HASH * GBS_create_hash(long estimated_elements, GB_CASE case_sens)
virtual class TreeNode * get_tree_root() const =0
void create_button(const char *macro_name, AW_label label, const char *mnemonic=NULp, const char *color=NULp)
GBDATA * GBT_get_species_data(GBDATA *gb_main)
GB_write_int const char s