31 #if defined(DEVEL_RALF) && 0
32 #define TRACE(msg) fprintf(stderr, "TRACE: %s\n", (msg))
40 #define GS_AWARS "group_search/"
41 #define GS_AWARS_DUPS GS_AWARS "dup/"
42 #define GS_AWARS_TMP "tmp/" GS_AWARS
44 #define AWAR_MAYBE_INVALID_GROUP GS_AWARS_TMP "sellist" // may point to deleted or unlisted group
45 #define AWAR_SELECTED_RESULT_GROUP GS_AWARS_TMP "selected" // bound to AWAR_MAYBE_INVALID_GROUP, but never points to deleted or unlisted group
46 #define AWAR_GROUP_HIT_COUNT GS_AWARS_TMP "hits"
47 #define AWAR_SELECTED_GROUP_NAME GS_AWARS_TMP "selname"
48 #define AWAR_RESULTING_GROUP_NAME GS_AWARS_TMP "resname"
49 #define AWAR_TREE_SELECTED GS_AWARS_TMP "treesel"
50 #define AWAR_RESULT_ORDER GS_AWARS_TMP "order"
52 #define AWAR_SEARCH_WHICH_TREES GS_AWARS "trees"
53 #define AWAR_SEARCH_MODE GS_AWARS "mode"
54 #define AWAR_MATCH_MODE GS_AWARS "match"
55 #define AWAR_MARK_TARGET GS_AWARS "markwhat"
56 #define AWAR_RENAME_EXPRESSION GS_AWARS "aci"
58 #define AWAR_DUPLICATE_MODE GS_AWARS_DUPS "mode"
59 #define AWAR_DUP_TREE_MODE GS_AWARS_DUPS "locmode"
60 #define AWAR_DUP_NAME_MATCH GS_AWARS_DUPS "namematch"
61 #define AWAR_DUP_MIN_CLUSTER_SIZE GS_AWARS_DUPS "clustsize"
62 #define AWAR_DUP_MIN_WORDS GS_AWARS_DUPS "minwords"
63 #define AWAR_DUP_IGNORE_CASE GS_AWARS_DUPS "ignore_case"
64 #define AWAR_DUP_EXCLUDED_WORDS GS_AWARS_DUPS "excluded"
65 #define AWAR_DUP_WORD_SEPARATORS GS_AWARS_DUPS "separators"
67 #define AWARFORMAT_CRIT_OPERATOR GS_AWARS "op%i"
68 #define AWARFORMAT_CRIT_KEY GS_AWARS "key%i"
69 #define AWARFORMAT_CRIT_EQUALS GS_AWARS "equals%i"
70 #define AWARFORMAT_CRIT_MATCHES GS_AWARS "match%i"
72 #define MAX_CRITERIA 3
101 void update_search_filters();
102 void update_search_range();
103 void update_duplicate_settings();
105 void refresh_hit_count(
size_t count) {
108 void result_order_changed_cb(
AW_root *awr) {
109 if (group_search.
isSet()) {
112 refill_result_list();
115 void result_list_awar_changed_cb(
AW_root *awr);
116 void selected_group_name_changed_cb(
AW_root *awr);
117 void selected_group_changed_cb(
AW_root *awr);
118 void update_resulting_groupname_cb(
AW_root *awr);
123 static void result_order_changed_cb(
AW_root *awr,
GroupUIdata *data) { data->result_order_changed_cb(awr); }
124 static void result_list_awar_changed_cb(
AW_root *awr,
GroupUIdata *data) { data->result_list_awar_changed_cb(awr); }
125 static void selected_group_name_changed_cb(
AW_root *awr,
GroupUIdata *data) { data->selected_group_name_changed_cb(awr); }
126 static void selected_group_changed_cb(
AW_root *awr,
GroupUIdata *data) { data->selected_group_changed_cb(awr); }
127 static void update_resulting_groupname_cb(
AW_root *awr,
GroupUIdata *data) { data->update_resulting_groupname_cb(awr); }
129 void install_callbacks(
AW_root *awr) {
136 void remove_callbacks(
AW_root *awr) {
147 show_tree_name(
false),
154 if (group_search.
isNull()) {
155 TRACE(
"initialize GroupUIdata");
156 group_search =
new GroupSearch(gb_main, makeGroupSearchCallback(GroupUIdata::refresh_result_list_cb,
this));
167 TRACE(
"cleanup GroupUIdata");
174 update_search_filters();
175 update_search_range();
176 update_duplicate_settings();
183 refill_result_list();
186 void refill_result_list();
187 void remove_selected_result();
188 void remove_all_results();
189 void clear_result_list();
199 void delete_selected_group();
200 void delete_listed_groups();
202 void rename_selected_group();
203 void rename_listed_groups();
205 void toggle_selected_group_folding();
212 refresh_hit_count(0);
214 result_list->clear();
215 result_list->insert_default(
"<none>", (
GBDATA*)
NULp);
216 result_list->update();
219 const QueriedGroups& foundGroups = group_search->get_results();
224 if (foundGroups.
empty()) {
232 bool seen_selected =
false;
234 refresh_hit_count(foundGroups.
size());
236 result_list->clear();
239 GBDATA *gb_group = g->get_pointer();
241 result_list->insert(display, gb_group);
243 if (gb_group == gb_sellist_group) seen_selected =
true;
245 result_list->insert_default(
"<none>", (
GBDATA*)
NULp);
246 result_list->update();
252 void GroupUIdata::update_search_filters() {
255 group_search->forgetQExpressions();
262 group_search->addQueryExpression(op, type, mtype, expression);
266 void GroupUIdata::update_search_range() {
275 if (currentTree[0]) trees.insert(currentTree);
281 tree_list->get_values(tree_names);
282 for (
int t = 0; tree_names[t]; ++t) {
283 trees.insert(tree_names[t]);
289 aw_message(
"No tree selected -> searching all trees instead");
291 group_search->setSearchRange(trees);
292 show_tree_name = trees.size() != 1;
295 void GroupUIdata::update_duplicate_settings() {
300 group_search->forgetDupCriteria();
313 group_search->setDupCriteria(listDups, nametype, sens, treetype, minClusterSize);
320 group_search->setDupCriteria(listDups, nametype, sens, minWords, excludedWords, wordSeparators, treetype, minClusterSize);
327 int selidx = result_list->get_index_of_selected();
329 result_list->move_selection(1);
330 result_list->delete_element_at(selidx);
331 result_list->update();
332 group_search->remove_hit(selidx);
336 group_search->forget_results();
337 refill_result_list();
341 int sel = result_list->get_index_of_selected();
343 result_list->select_default();
349 if (group_search->has_results()) {
350 result_list->select_default();
382 if (!first_vis) first_vis = tc;
387 if (!ntw && forceDisplay) {
422 void GroupUIdata::result_list_awar_changed_cb(
AW_root *awr) {
450 if (!inside_group_selection) {
463 void GroupUIdata::selected_group_changed_cb(
AW_root *awr) {
469 const char *name =
"";
476 update_resulting_groupname_cb(awr);
479 void GroupUIdata::update_resulting_groupname_cb(
AW_root *awr) {
480 TRACE(
"update_resulting_groupname_cb");
486 int idx = result_list->get_index_of_selected();
492 result = strdup(
"<empty result> => group would be skipped in batch-rename");
496 result = strdup(error.
deliver());
505 void GroupUIdata::selected_group_name_changed_cb(
AW_root *awr) {
506 if (!nameChangedByGroupChange) {
511 if (!gb_group) error =
"select a group to rename it";
514 if (!new_name[0]) error =
"empty group name not allowed";
523 awar_selected_result->
touch();
529 int sel = result_list->get_index_of_selected();
532 aw_message_if(group_search->rename_group(sel, acisrt).deliver());
538 if (group_search.isNull()) {
542 if (group_search->has_results()) {
544 aw_message_if(group_search->rename_found_groups(acisrt).deliver());
550 int sel = result_list->get_index_of_selected();
560 ARB_ERROR error = group_search->fold_found_groups(foldmode);
578 bool anyGroup =
false;
588 int sel = result_list->get_index_of_selected();
590 error = group_search->set_marks_in_group(sel, mode);
593 error =
"Please select a group";
602 if (group_search->has_results()) {
603 error = group_search->set_marks_in_found_groups(mode, anyGroup ?
UNITE :
INTERSECT);
606 error =
"No results listed";
611 error = ta.
close(error);
641 " branch group clade subsection"
642 " order family genus"
644 " other unknown unclassified miscellaneous"
667 AW_window_simple *aws =
new AW_window_simple;
671 aws->init(aw_root,
"GROUP_TREES",
"Select trees to search");
672 aws->load_xfig(
"group_trees.fig");
676 aws->create_button(
"CLOSE",
"CLOSE",
"C");
680 aws->create_button(
"HELP",
"HELP",
"H");
692 AW_window_simple *aws =
new AW_window_simple;
693 aws->init(awr,
"RENAME_GROUPS",
"Rename taxonomic groups");
698 aws->auto_space(PAD/2, PAD/2);
700 aws->button_length(7);
703 aws->create_button(
"CLOSE",
"Close",
"C");
705 aws->at_shift(450, 0);
707 aws->at_attach(-PAD, 0);
709 aws->create_button(
"HELP",
"Help",
"H");
712 const int IF_YSIZE = 32;
714 const int LABEL_LENGTH = 27;
715 const int FIELD_LENGTH = 40;
717 aws->label_length(LABEL_LENGTH);
720 int sy = aws->get_at_yposition();
722 aws->at_attach_to(
true,
false, -PAD, IF_YSIZE);
723 aws->label(
"Selected group name:");
727 int inputlineHeight = aws->get_at_yposition()-sy;
729 aws->at_attach_to(
true,
false, -PAD, IF_YSIZE);
730 aws->label(
"Modify using ACI/SRT:");
736 aws->get_at_position(&rx, &ry);
737 aws->at_shift(0, inputlineHeight);
739 int by = aws->get_at_yposition();
740 aws->at_attach(0, -PAD);
742 aws->create_autosize_button(
"SELECTED",
"Apply to\nselected group");
743 aws->at_attach(0, -PAD);
745 aws->create_autosize_button(
"LISTED",
"Apply to all\nlisted groups");
749 int bheight = aws->get_at_yposition()-by;
752 aws->at_attach_to(
true,
true, -PAD, -(PAD+bheight));
753 aws->label(
"Resulting group name:");
763 AW_window_simple *aws =
new AW_window_simple;
764 aws->init(awr,
"DUP_CONFIG",
"Configure group duplicate search");
767 const int IF_YSIZE = 32;
770 aws->auto_space(PAD/2, PAD/2);
772 aws->button_length(7);
775 aws->create_button(
"CLOSE",
"Close",
"C");
777 const int LONG_LABEL_LENGTH = 30;
778 const int SHORT_LABEL_LENGTH = 15;
779 const int LONG_FIELD_LENGTH = 40;
780 const int SHORT_FIELD_LENGTH = 7;
782 aws->label_length(LONG_LABEL_LENGTH);
785 aws->label(
"Min. size of duplicate cluster:");
789 aws->label(
"Search duplicates");
791 aws->insert_default_option(
"inside same tree",
"s",
DLC_SAME_TREE);
792 aws->insert_option (
"in different trees",
"d",
DLC_DIFF_TREE);
794 aws->update_option_menu();
797 aws->label(
"Ignore case?");
802 aws->insert_default_toggle(
"match whole name",
"n",
DNC_WHOLENAME);
803 aws->insert_toggle (
"match wordwise",
"w",
DNC_WORDWISE);
804 aws->update_toggle_field();
807 aws->label(
"Min. number of matching words");
811 aws->label(
"Word separators");
815 aws->label_length(SHORT_LABEL_LENGTH);
816 aws->at_attach_to(
true,
false, -PAD, IF_YSIZE);
817 aws->label(
"Ignored words");
845 def.
add(group_search_config_mapping);
858 {
"*tagged_find",
"Search expression for \"tagged\" groupnames",
"dup_mode='0';eq1='0';expr1='*[*]*';match_mode='0';op2='2';op3='2';sel1='0'" },
859 {
"*tags_remove_all",
"Expression for batch-rename:\n- removes any prefix(es) in \"[..]\" from groupnames",
"rename_script='/\\\\[.*\\\\]//'" },
860 {
"*tag_prefix",
"Expression for batch-rename:\n- adds prefix \"[TAG] \" to groupnames",
"rename_script='\"[TAG] \";dd'" },
861 {
"*swap_AND_names",
"Batch-rename:\n \"X and Y\" -> \"Y and X\"\n \"X, Y and Z\" -> \"Z, X and Y\" ...",
"rename_script=':* and *=*2 and *1:* and *, *=*1, *2 and *3:*, * and *, *=*1, *2, *3 and *4'" },
862 {
"*rename_enumerated",
"Batch-rename:\n- appends running number to group-name\n (using duplicate search + hitlist order)",
"dup_mode='1';rename_script='dd;\"~\";dupidx|merge|srt(~~=~)'" },
863 {
"*remove_numeric_suffix",
"Batch-rename:\n- removes numeric suffixes \n like \"~1\", \"~003\"",
"rename_script='/~[0-9]+$//'" },
865 {
"*undo_groupXfer_report",
"undo group rename applied by \"Move groups\":\n * remove prefix \"XFRD_\"\n * remove penalty suffix",
"rename_script='command(\"/^XFRD_//\")|command(\"/\\\\\\\\{penalty.*\\\\\\\\}$//\")'" },
877 AW_window_simple *aws =
new AW_window_simple;
880 aws->init(aw_root,
"GROUP_SEARCH",
"Search taxonomic groups");
881 aws->load_xfig(
"group_search.fig");
883 aws->button_length(7);
887 aws->create_button(
"CLOSE",
"Close",
"C");
891 aws->create_button(
"HELP",
"Help",
"H");
901 aws->update_option_menu();
905 aws->create_autosize_button(
"select_trees",
"(select)");
909 aws->insert_default_option(
"list",
"l",
GSM_FIND);
910 aws->insert_option (
"add",
"a",
GSM_ADD);
911 aws->insert_option (
"keep",
"k",
GSM_KEEP);
912 aws->insert_option (
"remove",
"r",
GSM_REMOVE);
913 aws->update_option_menu();
917 aws->insert_default_option(
"match",
"m",
GSM_MATCH);
919 aws->update_option_menu();
925 aws->insert_option (
"unique groups only",
"u",
ONLY_UNIQUE);
926 aws->update_option_menu();
930 aws->create_autosize_button(
"config_dup",
"Configure");
938 aws->insert_option (
"and",
"a",
CO_AND);
939 aws->insert_option (
"or",
"o",
CO_OR);
940 aws->insert_default_option(
"ign",
"i",
CO_IGNORE);
941 aws->update_option_menu();
946 aws->insert_default_option(
"groupname",
"g",
CT_NAME);
951 aws->insert_option (
"folded",
"f",
CT_FOLDED);
952 aws->insert_option (
"size",
"s",
CT_SIZE);
953 aws->insert_option (
"marked",
"m",
CT_MARKED);
955 aws->insert_option (
"zombies",
"z",
CT_ZOMBIES);
956 aws->insert_option (
"AID",
"A",
CT_AID);
957 aws->insert_option (
"keeled",
"k",
CT_KEELED);
958 aws->update_option_menu();
964 aws->d_callback(search_wcb);
968 aws->button_length(18);
971 aws->callback(search_wcb);
972 aws->create_button(
"SEARCH",
"Search",
"S",
"+");
974 aws->button_length(13);
988 aws->insert_default_option(
"unsorted",
"u",
GSC_NONE);
989 aws->insert_option (
"by name",
"n",
GSC_NAME);
990 aws->insert_option (
"by nesting",
"g",
GSC_NESTING);
991 aws->insert_option (
"by size",
"s",
GSC_SIZE);
992 aws->insert_option (
"by marked",
"m",
GSC_MARKED);
997 aws->insert_option (
"by cluster",
"c",
GSC_CLUSTER);
998 aws->insert_option (
"by AID",
"A",
GSC_AID);
999 aws->insert_option (
"by keeled",
"k",
GSC_KEELED);
1001 aws->update_option_menu();
1004 aws->button_length(6);
1008 aws->create_button(
"rm_sel",
"Remove");
1012 aws->create_button(
"clear",
"Clear");
1018 aws->create_button(
"rename",
"Rename ...");
1023 aws->create_button(
"expand_listed",
"Expand listed");
1027 aws->create_button(
"explst_collrest",
"Expand listed\ncollapse rest");
1029 aws->at(
"expparent");
1031 aws->create_button(
"expand_parents",
"Expand parents");
1033 aws->at(
"collapse");
1035 aws->create_button(
"collapse_listed",
"Collapse listed");
1040 aws->create_button(
"del_sel",
"Destroy\nselected group");
1042 aws->at(
"dellisted");
1044 aws->create_button(
"del_listed",
"Destroy all\nlisted groups");
1049 aws->create_button(
"mark",
"Mark");
1052 aws->create_button(
"unmark",
"Unmark");
1055 aws->create_button(
"invert",
"Inv");
1063 aws->update_option_menu();
GB_ERROR rewrite_pointer(GBDATA *aw_pointer)
static void rename_listed_groups_cb(AW_window *, GroupUIdata *data)
AWT_graphic_tree * get_graphic_tree() const
#define AWAR_DUP_MIN_WORDS
static AW_window * create_group_rename_window_cb(AW_root *awr, GroupUIdata *data)
static AWT_config_mapping_def group_search_config_mapping[]
GBDATA * get_pointer() const
const char * get_group_display(const FoundGroup &g, bool show_tree_name) const
void change_listed_groups_folding(GroupFoldingMode mode)
void add(const char *awar_name, const char *config_name)
AliDataPtr format(AliDataPtr data, const size_t wanted_len, GB_ERROR &error)
static void double_click_group_cb(AW_window *, GroupUIdata *data)
GBDATA * read_pointer() const
char * GB_read_key(GBDATA *gbd)
static void group_mark_cb(AW_window *, GroupUIdata *data, GroupMarkMode mode)
#define AWAR_SELECTED_GROUP_NAME
static AW_window * create_tree_select_window_cb(AW_root *aw_root, GroupUIdata *data)
void GB_atclose_callback(GBDATA *gbd, const DatabaseCallback &atClose)
void announce_tree_select_list(AW_selection *tree_list_)
void addSortCriterion(GroupSortCriterion gsc)
long GBT_mark_all(GBDATA *gb_main, int flag)
#define AWAR_DUP_EXCLUDED_WORDS
GB_ERROR write_pointer(GBDATA *aw_pointer)
void delete_listed_groups()
void remove_selected_result()
AW_selection * awt_create_subset_selection_list(AW_window *aww, AW_selection_list *parent_selection, const char *at_box, const char *at_add, const char *at_sort, bool autocorrect_subselection, SubsetChangedCb subChanged_cb, AW_CL cl_user)
const char * criterion_awar_name(const char *format, int crit)
static bool inside_group_selection
#define AWAR_DUP_NAME_MATCH
void rename_listed_groups()
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)
static void popdown_search_window_cb(AW_window *, GroupUIdata *data)
#define AWAR_SELECTED_RESULT_GROUP
const char * GBS_global_string(const char *templat,...)
#define AWAR_TREE_SELECTED
#define AWAR_DUPLICATE_MODE
AW_DB_selection * awt_create_TREE_selection_list(GBDATA *gb_main, AW_window *aws, const char *varname)
void AW_POPDOWN(AW_window *window)
#define AWARFORMAT_CRIT_EQUALS
bool isNull() const
test if SmartPtr is NULp
TREE_canvas * NT_get_canvas_by_index(int idx)
static void listed_groups_folding_cb(AW_window *, GroupUIdata *data, GroupFoldingMode mode)
void announce_result_list(AW_selection_list *result_list_)
void setNull()
set SmartPtr to NULp
GBDATA * GB_get_father(GBDATA *gbd)
static AW_window * create_dup_config_window_cb(AW_root *awr)
static void remove_hit_cb(AW_window *, GroupUIdata *data)
AW_awar * add_callback(const RootCallback &cb)
const char * read_char_pntr() const
static void selected_group_changed_by_canvas_cb(AW_root *awr)
void mark_species(GroupMarkMode mode)
static AW_root * SINGLETON
WindowCallback makeHelpCallback(const char *helpfile)
void popup_group_search_window(AW_window *aw_parent, GBDATA *gb_main)
#define AWAR_DUP_MIN_CLUSTER_SIZE
static TREE_canvas * get_canvas_able_to_show(GBDATA *gb_group)
#define AWAR_DUP_IGNORE_CASE
bool isSet() const
test if SmartPtr is not NULp
static void delete_listed_groups_cb(AW_window *, GroupUIdata *data)
char * GBS_trim(const char *str)
int get_index_of(const AW_scalar &searched_value)
static void error(const char *msg)
std::set< std::string > TreeNameSet
#define AWAR_TREE_REFRESH
void expect_no_error() const
TREE_canvas * NT_get_canvas_showing_tree(const char *tree_name, bool forceDisplay)
FoundGroupCIter end() const
static void mark_species(TreeNode *node, Store_species **extra_marked_species)
char * read_string() const
AW_awar * awar(const char *awar)
static void delete_selected_group_cb(AW_window *, GroupUIdata *data)
char * GS_calc_resulting_groupname(GBDATA *gb_main, const QueriedGroups &queried, int hit_idx, const char *input_name, const char *acisrt, ARB_ERROR &error)
AW_awar * remove_callback(const RootCallback &cb)
FoundGroupContainer::const_iterator FoundGroupCIter
static void clear_results_cb(AW_window *, GroupUIdata *data)
#define AWARFORMAT_CRIT_KEY
#define AWAR_RESULTING_GROUP_NAME
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
GB_ERROR close(GB_ERROR error)
#define AWAR_DUP_WORD_SEPARATORS
#define AWARFORMAT_CRIT_MATCHES
#define AWAR_DUP_TREE_MODE
static void rename_selected_group_cb(AW_window *, GroupUIdata *data)
static void create_search_config_setup_cb(AWT_config_definition &def)
void delete_selected_group()
FoundGroupCIter begin() const
const char * get_name() const
void toggle_selected_group_folding()
void aw_message(const char *msg)
#define AWARFORMAT_CRIT_OPERATOR
#define AWAR_RESULT_ORDER
GB_ERROR GBT_write_name_to_groupData(GBDATA *gb_group, bool createNameEntry, const char *new_group_name, bool pedantic)
GB_ERROR write_string(const char *aw_string)
static void runGroupSearch_cb(AW_window *, GroupUIdata *data)
GroupUIdata(GBDATA *gb_main_)
GB_transaction ta(gb_var)
GBDATA * get_selected_group() const
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
#define AWAR_MAYBE_INVALID_GROUP
#define AWAR_RENAME_EXPRESSION
void rename_selected_group()
void perform_search(GroupSearchMode mode)
AW_awar * awar_pointer(const char *var_name, GBDATA *default_value=NULp, AW_default default_file=AW_ROOT_DEFAULT)
void remove_all_results()
GBDATA * get_gb_main() const
AW_awar * get_awar_tree() const
#define AWAR_GROUP_HIT_COUNT
GB_ERROR write_int(long aw_int)
#define AWAR_SEARCH_WHICH_TREES
void create_group_search_awars(AW_root *aw_root, AW_default props)
AW_scalar get_awar_value() const
AW_selection_list * get_sellist()
void aw_message_if(GB_ERROR error)
static AWT_predefined_config predefined_group_search[]
void refill_result_list()
static bool nameChangedByGroupChange
AW_awar * set_min(float min)