ARB
MG_trees.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : MG_trees.cxx //
4 // Purpose : Merge trees between databases //
5 // //
6 // Institute of Microbiology (Technical University Munich) //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #include "merge.hxx"
12 #include <TreeAdmin.h>
13 #include <awt_sel_boxes.hxx>
14 #include <aw_root.hxx>
15 #include <aw_awar.hxx>
16 #include <aw_msg.hxx>
17 #include <arbdbt.h>
18 #include <arb_global_defs.h>
19 
20 #define AWAR_TREE_NAME_SRC AWAR_MERGE_TMP_SRC "tree_name"
21 #define AWAR_TREE_NAME_DST AWAR_MERGE_TMP_DST "tree_name"
22 
23 #define AWAR_TREE_XFER_WHAT AWAR_MERGE_TMP "xfer_what"
24 #define AWAR_TREE_OVERWRITE AWAR_MERGE_TMP "overwrite"
25 
31 };
32 
33 void MG_create_trees_awar(AW_root *aw_root, AW_default aw_def) {
36 
37  aw_root->awar_int(AWAR_TREE_XFER_WHAT, XFER_SELECTED, aw_def);
38  aw_root->awar_int(AWAR_TREE_OVERWRITE, 0, aw_def);
39 
40  TreeAdmin::create_awars(aw_root, aw_def, false);
41 }
42 
43 static GB_ERROR transfer_tree(const char *tree_name, bool overwrite, const char *behind_name) {
44  // transfer tree 'tree_name' from DB1->DB2.
45  //
46  // if 'overwrite' is true and tree already exists, overwrite tree w/o changing its position.
47  //
48  // if tree does not exist, insert it behind tree 'behind_name'.
49  // if tree 'behind_name' does not exist or if 'behind_name' is NULp, insert at end.
50 
51 
53  GBDATA *gb_tree = GBT_find_tree(GLOBAL_gb_src, tree_name);
54  if (!gb_tree) {
55  if (strcmp(tree_name, NO_TREE_SELECTED) == 0) {
56  error = "No tree selected in source DB";
57  }
58  else {
59  error = GBS_global_string("No tree '%s' in source DB", tree_name);
60  }
61  }
62  else {
63  GBDATA *gb_at_tree = NULp;
64  GBT_ORDER_MODE next_to = GBT_BEHIND;
65 
66  if (behind_name && strcmp(behind_name, NO_TREE_SELECTED) != 0) {
67  gb_at_tree = GBT_find_tree(GLOBAL_gb_dst, behind_name);
68  if (!gb_at_tree) {
69  error = GBS_global_string("Can't position tree behind '%s' (no such tree)", behind_name);
70  }
71  }
72 
73  if (!error) {
74  GBDATA *gb_dest_tree = GBT_find_tree(GLOBAL_gb_dst, tree_name);
75  if (gb_dest_tree) {
76  if (!overwrite) {
77  error = GBS_global_string("Tree '%s' already exists in destination DB", tree_name);
78  }
79  else {
80  // keep position of existing tree
81  GBDATA *gb_tree_infrontof = GBT_tree_infrontof(gb_dest_tree);
82  if (gb_tree_infrontof) {
83  next_to = GBT_BEHIND;
84  gb_at_tree = gb_tree_infrontof;
85  }
86  else {
87  GBDATA *gb_tree_behind = GBT_tree_behind(gb_dest_tree);
88  next_to = GBT_INFRONTOF;
89  gb_at_tree = gb_tree_behind;
90  }
91 
92  error = GB_delete(gb_dest_tree);
93  }
94  }
95  }
96 
97  if (!error) {
98  GBDATA *gb_dest_tree_data = GBT_get_tree_data(GLOBAL_gb_dst);
99  if (!gb_dest_tree_data) error = GB_await_error();
100  else {
101  GBDATA *gb_dest_tree = GB_create_container(gb_dest_tree_data, tree_name);
102  if (!gb_dest_tree) error = GB_await_error();
103  else {
104  error = GB_copy_dropProtectMarksAndTempstate(gb_dest_tree, gb_tree);
105  if (!error) {
106  if (!gb_at_tree) {
107  gb_at_tree = GBT_find_bottom_tree(GLOBAL_gb_dst);
108  next_to = GBT_BEHIND;
109  }
110  if (gb_at_tree) {
111  error = GBT_move_tree(gb_dest_tree, next_to, gb_at_tree);
112  }
113  }
114  }
115  }
116  }
117  }
118  return error;
119 }
120 
121 static void MG_transfer_tree(AW_window *aww) {
122  AW_root *awr = aww->get_root();
123 
125 
126  AW_awar *awar_tree_source = awr->awar(AWAR_TREE_NAME_SRC);
127  AW_awar *awar_tree_dest = awr->awar(AWAR_TREE_NAME_DST);
128 
129  bool overwrite = awr->awar(AWAR_TREE_OVERWRITE)->read_int();
130 
131  char *source_name = awar_tree_source->read_string();
132  char *behind_name = awar_tree_dest->read_string();
133 
134  char *select_dst = NULp;
135 
137  if (!error) error = GB_begin_transaction(GLOBAL_gb_src);
138 
139  int xferd_missing = 0;
140  int xferd_existing = 0;
141 
142  if (!error) {
143  switch (what) {
144  case XFER_SELECTED:
145  error = transfer_tree(source_name, overwrite, behind_name);
146  if (!error) select_dst = ARB_strdup(source_name);
147  break;
148 
149  case XFER_ALL:
150  case XFER_EXISTING:
151  for (GBDATA *gb_tree = GBT_find_top_tree(GLOBAL_gb_src); gb_tree && !error; gb_tree = GBT_tree_behind(gb_tree)) {
152  const char *tree_name = GBT_get_tree_name(gb_tree);
153  GBDATA *gb_exists = GBT_find_tree(GLOBAL_gb_dst, tree_name);
154 
155  if (gb_exists) {
156  xferd_existing++;
157  error = transfer_tree(tree_name, overwrite, NULp);
158  }
159  }
160  if (what == XFER_EXISTING) break;
161  FALLTHROUGH; // for XFER_ALL
162  case XFER_MISSING:
163  for (GBDATA *gb_tree = GBT_find_top_tree(GLOBAL_gb_src); gb_tree && !error; gb_tree = GBT_tree_behind(gb_tree)) {
164  const char *tree_name = GBT_get_tree_name(gb_tree);
165  GBDATA *gb_exists = GBT_find_tree(GLOBAL_gb_dst, tree_name);
166 
167  if (!gb_exists) {
168  error = transfer_tree(tree_name, false, behind_name);
169  xferd_missing++;
170  if (!select_dst) select_dst = ARB_strdup(tree_name); // select first missing in dest box
171  freedup(behind_name, tree_name);
172  }
173  }
174  break;
175  }
176  }
177 
178  error = GB_end_transaction(GLOBAL_gb_dst, error);
180 
181  if (!error) {
182  if (select_dst) awar_tree_dest->write_string(select_dst);
183 
184  if (what == XFER_SELECTED) {
186  GBDATA *gb_next = GBT_find_next_tree(GBT_find_tree(GLOBAL_gb_src, source_name));
187  awar_tree_source->write_string(gb_next ? GBT_get_tree_name(gb_next) : NO_TREE_SELECTED);
188  }
189 
190  if (xferd_existing) {
191  if (xferd_missing) aw_message(GBS_global_string("Transferred %i existing and %i missing trees", xferd_existing, xferd_missing));
192  else aw_message(GBS_global_string("Transferred %i existing trees", xferd_existing));
193  }
194  else {
195  if (xferd_missing) aw_message(GBS_global_string("Transferred %i missing trees", xferd_missing));
196  else {
197  if (what != XFER_SELECTED) aw_message("No trees have been transferred");
198  }
199  }
200  }
201 
202  free(select_dst);
203  free(behind_name);
204  free(source_name);
205 }
206 
209  if (error) {
210  aw_message(error);
211  return NULp; // deny to open window before user has renamed species
212  }
213 
214  AW_window_simple *aws = new AW_window_simple;
215 
216  aws->init(awr, "MERGE_TREES", "MERGE TREES");
217  aws->load_xfig("merge/trees.fig");
218 
219  aws->button_length(7);
220 
221  aws->at("close");
222  aws->callback(AW_POPDOWN);
223  aws->create_button("CLOSE", "CLOSE", "C");
224 
225  aws->at("help");
226  aws->callback(makeHelpCallback("mg_trees.hlp"));
227  aws->create_button("HELP", "HELP", "H");
228 
229  aws->at("trees1");
231 
232  aws->at("trees2");
234 
237 
238  aws->button_length(15);
239 
240  aws->at("delete1");
241  aws->callback(makeWindowCallback(TreeAdmin::delete_tree_cb, &src_spec));
242  aws->create_button("DELETE TREE_DB1", "Delete Tree");
243 
244  aws->at("delete2");
245  aws->callback(makeWindowCallback(TreeAdmin::delete_tree_cb, &dst_spec));
246  aws->create_button("DELETE_TREE_DB2", "Delete Tree");
247 
248  aws->at("rename1");
249  aws->callback(makeCreateWindowCallback(TreeAdmin::create_rename_window, &src_spec));
250  aws->create_button("RENAME_TREE_DB1", "Rename Tree");
251 
252  aws->at("rename2");
253  aws->callback(makeCreateWindowCallback(TreeAdmin::create_rename_window, &dst_spec));
254  aws->create_button("RENAME_TREE_DB2", "Rename Tree");
255 
256  aws->at("transfer");
257  aws->callback(MG_transfer_tree);
258  aws->create_autosize_button("TRANSFER_TREE", "Transfer");
259 
260  aws->at("xfer_what");
261  aws->create_option_menu(AWAR_TREE_XFER_WHAT, true);
262  aws->insert_default_option("selected tree", "s", XFER_SELECTED);
263  aws->insert_option ("all trees", "a", XFER_ALL);
264  aws->insert_option ("missing trees", "m", XFER_MISSING);
265  aws->insert_option ("existing trees", "e", XFER_EXISTING);
266  aws->update_option_menu();
267 
268  aws->at("overwrite");
269  aws->label("Overwrite trees?");
270  aws->create_toggle(AWAR_TREE_OVERWRITE);
271 
272  aws->button_length(0);
273  aws->shadow_width(1);
274  aws->at("icon");
275  aws->callback(makeHelpCallback("mg_trees.hlp"));
276  aws->create_button("HELP_MERGE", "#merge/icon.xpm");
277 
278  return aws;
279 }
280 
GB_ERROR GB_begin_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2516
GBDATA * GBT_find_bottom_tree(GBDATA *gb_main)
Definition: adtree.cxx:1004
void MG_create_trees_awar(AW_root *aw_root, AW_default aw_def)
Definition: MG_trees.cxx:33
GB_ERROR GB_copy_dropProtectMarksAndTempstate(GBDATA *dest, GBDATA *source)
Definition: arbdb.cxx:2144
static GB_ERROR transfer_tree(const char *tree_name, bool overwrite, const char *behind_name)
Definition: MG_trees.cxx:43
const char * GB_ERROR
Definition: arb_core.h:25
NOT4PERL GB_ERROR GBT_move_tree(GBDATA *gb_moved_tree, GBT_ORDER_MODE mode, GBDATA *gb_target_tree)
Definition: adtree.cxx:1194
AW_window * create_rename_window(AW_root *root, const Spec *spec)
Definition: TreeAdmin.cxx:218
GBDATA * GBT_tree_behind(GBDATA *gb_tree)
Definition: adtree.cxx:990
GB_ERROR GB_end_transaction(GBDATA *gbd, GB_ERROR error)
Definition: arbdb.cxx:2549
#define NO_TREE_SELECTED
char * ARB_strdup(const char *str)
Definition: arb_string.h:27
void GB_end_transaction_show_error(GBDATA *gbd, GB_ERROR error, void(*error_handler)(GB_ERROR))
Definition: arbdb.cxx:2572
long read_int() const
Definition: AW_awar.cxx:187
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:204
GB_ERROR MG_expect_renamed()
Definition: MG_names.cxx:119
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
GBDATA * GBT_get_tree_data(GBDATA *gb_main)
Definition: adtree.cxx:26
GBDATA * GLOBAL_gb_dst
Definition: MG_main.cxx:32
GB_ERROR GB_delete(GBDATA *&source)
Definition: arbdb.cxx:1904
const char * GBT_get_tree_name(GBDATA *gb_tree)
Definition: adtree.cxx:1033
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:353
GBDATA * GB_create_container(GBDATA *father, const char *key)
Definition: arbdb.cxx:1827
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
GBT_ORDER_MODE
Definition: arbdbt.h:43
#define AWAR_TREE_NAME_SRC
Definition: MG_trees.cxx:20
GBDATA * GBT_find_next_tree(GBDATA *gb_tree)
Definition: adtree.cxx:1017
TREE_XFER_MODE
Definition: MG_trees.cxx:26
void create_awars(AW_root *root, AW_default aw_def, bool registerTreeAwar)
Definition: TreeAdmin.cxx:30
GBDATA * GBT_find_top_tree(GBDATA *gb_main)
Definition: adtree.cxx:996
void delete_tree_cb(AW_window *aww, const Spec *spec)
Definition: TreeAdmin.cxx:46
#define AWAR_TREE_OVERWRITE
Definition: MG_trees.cxx:24
#define AWAR_TREE_NAME_DST
Definition: MG_trees.cxx:21
static void error(const char *msg)
Definition: mkptypes.cxx:96
char * read_string() const
Definition: AW_awar.cxx:201
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
#define AWAR_TREE_XFER_WHAT
Definition: MG_trees.cxx:23
GBDATA * GLOBAL_gb_src
Definition: MG_main.cxx:31
AW_DB_selection * awt_create_TREE_selection_list(GBDATA *gb_main, AW_window *aws, const char *varname, bool fallback2default)
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:580
static void MG_transfer_tree(AW_window *aww)
Definition: MG_trees.cxx:121
void aw_message(const char *msg)
Definition: AW_status.cxx:932
AW_root * get_root()
Definition: aw_window.hxx:348
#define NULp
Definition: cxxforward.h:97
GB_ERROR write_string(const char *aw_string)
AW_window * MG_create_merge_trees_window(AW_root *awr)
Definition: MG_trees.cxx:207
#define FALLTHROUGH
Definition: cxxforward.h:110
GBDATA * GBT_find_tree(GBDATA *gb_main, const char *tree_name)
Definition: adtree.cxx:947
GB_transaction ta(gb_var)
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:570
GBDATA * GBT_tree_infrontof(GBDATA *gb_tree)
Definition: adtree.cxx:985