source: tags/arb-6.0/MERGE/MG_main.cxx

Last change on this file was 12267, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : MG_main.cxx                                       //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "merge.hxx"
12
13#include <AW_rename.hxx>
14
15#include <awt.hxx>
16
17#include <aw_preset.hxx>
18#include <aw_awars.hxx>
19#include <aw_file.hxx>
20#include <aw_msg.hxx>
21#include <aw_root.hxx>
22#include <aw_question.hxx>
23
24#include <arb_progress.h>
25#include <arb_file.h>
26#include <macros.hxx>
27
28// AISC_MKPT_PROMOTE:// source and destination DBs for merge:
29// AISC_MKPT_PROMOTE:extern GBDATA *GLOBAL_gb_src;
30// AISC_MKPT_PROMOTE:extern GBDATA *GLOBAL_gb_dst;
31
32GBDATA *GLOBAL_gb_src = NULL;
33GBDATA *GLOBAL_gb_dst = NULL;
34
35static void (*MG_exit_cb)(const char *) = NULL;
36
37static void MG_exit(AW_window *aww, bool start_dst_db) {
38    char *arb_ntree_restart_args = NULL;
39
40    if (start_dst_db) {
41        // restart with destination DB
42        const char *dst_db_name = aww->get_root()->awar(AWAR_DB_DST"/file_name")->read_char_pntr();
43        arb_ntree_restart_args  = GBS_global_string_copy("'%s'", dst_db_name);
44    }
45    else {
46        // restart in directory of destination- or source-DB
47        const char *dst_db_dir = aww->get_root()->awar(AWAR_DB_DST"/directory")->read_char_pntr();
48        if (GB_is_directory(dst_db_dir)) {
49            arb_ntree_restart_args = GBS_global_string_copy("'%s'", dst_db_dir);
50        }
51        else {
52            const char *src_db_dir = aww->get_root()->awar(AWAR_DB_SRC"/directory")->read_char_pntr();
53            if (GB_is_directory(src_db_dir)) {
54                arb_ntree_restart_args = GBS_global_string_copy("'%s'", src_db_dir);
55            }
56        }
57    }
58
59    shutdown_macro_recording(AW_root::SINGLETON);
60
61    // @@@ code below duplicates code from nt_disconnect_from_db()
62    aww->get_root()->unlink_awars_from_DB(GLOBAL_gb_src);
63    aww->get_root()->unlink_awars_from_DB(GLOBAL_gb_dst);
64
65    GB_close(GLOBAL_gb_src);
66    GB_close(GLOBAL_gb_dst);
67
68    mg_assert(MG_exit_cb);
69
70    MG_exit_cb(arb_ntree_restart_args);
71}
72
73static void MG_save_merge_cb(AW_window *aww) {
74    AW_root *awr  = aww->get_root();
75    char    *name = awr->awar(AWAR_DB_SRC"/file_name")->read_string();
76
77    awr->dont_save_awars_with_default_value(GLOBAL_gb_src);
78    GB_begin_transaction(GLOBAL_gb_src);
79    GBT_check_data(GLOBAL_gb_src, 0);
80    GB_commit_transaction(GLOBAL_gb_src);
81
82    GB_ERROR error = GB_save(GLOBAL_gb_src, name, "b");
83    if (error) aw_message(error);
84    else AW_refresh_fileselection(awr, AWAR_DB_SRC);
85
86    free(name);
87}
88
89static AW_window *MG_save_source_cb(AW_root *aw_root, const char *base_name) {
90    static AW_window_simple *aws = 0;
91    if (aws) return (AW_window *)aws;
92
93    aws = new AW_window_simple;
94    aws->init(aw_root, "MERGE_SAVE_DB_I", "Save source DB");
95    aws->load_xfig("sel_box.fig");
96
97    aws->at("close"); aws->callback((AW_CB0)AW_POPDOWN);
98    aws->create_button("CLOSE", "CLOSE", "C");
99
100    aws->at("save"); aws->callback(MG_save_merge_cb);
101    aws->create_button("SAVE", "SAVE", "S");
102
103    aws->callback((AW_CB0)AW_POPDOWN);
104    aws->at("cancel");
105    aws->create_button("CLOSE", "CANCEL", "C");
106
107    AW_create_standard_fileselection(aws, base_name);
108
109    return (AW_window *)aws;
110}
111
112static void MG_save_cb(AW_window *aww) {
113    AW_root *awr  = aww->get_root();
114    char    *name = awr->awar(AWAR_DB_DST"/file_name")->read_string();
115    char    *type = awr->awar(AWAR_DB_DST"/type")->read_string();
116
117    arb_progress progress("Saving database");
118
119    awr->dont_save_awars_with_default_value(GLOBAL_gb_dst); // has to be done outside transaction!
120    GB_begin_transaction(GLOBAL_gb_dst);
121    GBT_check_data(GLOBAL_gb_dst, 0);
122    GB_commit_transaction(GLOBAL_gb_dst);
123
124    GB_ERROR error = GB_save(GLOBAL_gb_dst, name, type);
125    if (error) aw_message(error);
126    else AW_refresh_fileselection(awr, AWAR_DB_DST);
127
128    free(type);
129    free(name);
130}
131
132static AW_window *MG_create_save_result_window(AW_root *aw_root, const char *base_name) {
133    static AW_window_simple *aws = 0;
134    if (aws) return (AW_window *)aws;
135    aw_root->awar_string(AWAR_DB_COMMENT, "<no description>", GLOBAL_gb_dst);
136
137    aws = new AW_window_simple;
138    aws->init(aw_root, "MERGE_SAVE_WHOLE_DB", "SAVE WHOLE DATABASE");
139    aws->load_xfig("sel_box_user3.fig");
140
141    aws->at("close"); aws->callback((AW_CB0)AW_POPDOWN);
142    aws->create_button("CLOSE", "CLOSE", "C");
143
144    AW_create_standard_fileselection(aws, base_name);
145
146    aws->at("user");
147    aws->label("Type");
148    aws->create_option_menu(AWAR_DB_DST"/type", true);
149    aws->insert_option("Binary", "B", "b");
150    aws->insert_option("Bin (with FastLoad File)", "f", "bm");
151    aws->update_option_menu();
152
153    aws->at("user2");
154    aws->create_button(0, "Database Description");
155
156    aws->at("user3");
157    aws->create_text_field(AWAR_DB_COMMENT);
158
159    aws->callback((AW_CB0)AW_POPDOWN);
160    aws->at("cancel4");
161    aws->create_button("CLOSE", "CANCEL", "C");
162
163    aws->at("save4"); aws->callback(MG_save_cb);
164    aws->create_button("SAVE", "SAVE", "S");
165
166    return (AW_window *)aws;
167}
168
169static void MG_save_quick_result_cb(AW_window *aww) {
170    char *name = aww->get_root()->awar(AWAR_DB_DST"/file_name")->read_string();
171
172    arb_progress progress("Saving database");
173    GB_begin_transaction(GLOBAL_gb_dst);
174    GBT_check_data(GLOBAL_gb_dst, 0);
175    GB_commit_transaction(GLOBAL_gb_dst);
176   
177    GB_ERROR error = GB_save_quick_as(GLOBAL_gb_dst, name);
178    if (error) aw_message(error);
179    else AW_refresh_fileselection(aww->get_root(), AWAR_DB_DST);
180
181    free(name);
182}
183
184static void MG_create_db_dependent_awars(AW_root *aw_root, GBDATA *gb_src, GBDATA *gb_dst) {
185    MG_create_db_dependent_rename_awars(aw_root, gb_src, gb_dst);
186}
187
188AW_window *MERGE_create_main_window(AW_root *aw_root, bool dst_is_new, void (*exit_cb)(const char *)) {
189    // 'dst_is_new' == true -> setup dest DB according to source-DB
190    //
191    // GLOBAL_gb_src and GLOBAL_gb_dst have to be opened before
192
193    // @@@ add GB_is_client and use that here
194    bool src_is_client = GB_read_clients(GLOBAL_gb_src)<0;
195    bool dst_is_client = GB_read_clients(GLOBAL_gb_dst)<0;
196
197    MG_exit_cb = exit_cb;
198
199    mg_assert(contradicted(src_is_client, GB_is_server(GLOBAL_gb_src)));
200    mg_assert(contradicted(dst_is_client, GB_is_server(GLOBAL_gb_dst)));
201
202    mg_assert(!(src_is_client && dst_is_client));
203
204    bool save_src_enabled = !src_is_client;
205    bool save_dst_enabled = !dst_is_client;
206
207    {
208        GBDATA     *gb_main_4_macros = NULL;
209        const char *app_id           = NULL;
210
211        if (src_is_client) {
212            gb_main_4_macros = GLOBAL_gb_src;
213            app_id           = "ARB_MERGE_OUTOF";
214        }
215        else if (dst_is_client) {
216            gb_main_4_macros = GLOBAL_gb_dst;
217            app_id           = "ARB_MERGE_INTO";
218        }
219        else {
220            gb_main_4_macros = GLOBAL_gb_dst; // does not matter
221            app_id           = "ARB_MERGE";
222        }
223
224        configure_macro_recording(aw_root, app_id, gb_main_4_macros); // @@@ use result
225    }
226
227    mg_assert(aw_root);
228
229    {
230        GB_transaction ta_merge(GLOBAL_gb_src);
231        GB_transaction ta_dest(GLOBAL_gb_dst);
232
233        GBT_mark_all(GLOBAL_gb_dst, 0); // unmark everything in dest DB
234
235        // set DB-type to non-genome (compatibility to old DBs)
236        // when exporting to new DB (dest_is_new == true) -> use DB-type of merge-DB
237        bool merge_is_genome = GEN_is_genome_db(GLOBAL_gb_src, 0);
238
239        int dest_genome = 0;
240        if (dst_is_new) {
241            if (merge_is_genome) {
242                dest_genome = aw_question("select_dest_dbtype", "Enter destination DB-type", "Normal,Genome");
243            }
244            else {
245                dest_genome = 0; // from non-genome -> to non-genome
246            }
247        }
248
249        GEN_is_genome_db(GLOBAL_gb_dst, dest_genome); // does not change anything if type is already defined
250    }
251
252    {
253        GB_transaction ta_merge(GLOBAL_gb_src);
254        GB_transaction ta_dest(GLOBAL_gb_dst);
255
256        GB_change_my_security(GLOBAL_gb_dst, 6);
257        GB_change_my_security(GLOBAL_gb_src, 6);
258
259        MG_create_db_dependent_awars(aw_root, GLOBAL_gb_src, GLOBAL_gb_dst);
260    }
261
262    {
263        GB_transaction ta_merge(GLOBAL_gb_src);
264        GB_transaction ta_dest(GLOBAL_gb_dst);
265
266        MG_set_renamed(false, aw_root, "Not renamed yet.");
267
268        AW_window_simple_menu *awm = new AW_window_simple_menu;
269        awm->init(aw_root, "ARB_MERGE", "ARB_MERGE");
270        awm->load_xfig("merge/main.fig");
271
272        // create menus
273#if defined(DEBUG)
274        AWT_create_debug_menu(awm);
275#endif // DEBUG
276
277        awm->create_menu("File", "F", AWM_ALL);
278        if (save_src_enabled) {
279            awm->insert_menu_topic("save_DB1", "Save source DB ...", "S", "save_as.hlp", AWM_ALL, makeCreateWindowCallback(MG_save_source_cb, AWAR_DB_SRC));
280        }
281
282        awm->insert_menu_topic("quit", "Quit", "Q", "quit.hlp", AWM_ALL, makeWindowCallback(MG_exit, false));
283        if (save_dst_enabled) {
284            awm->insert_menu_topic("quitnstart", "Quit & start target DB", "D", "quit.hlp", AWM_ALL, makeWindowCallback(MG_exit, true));
285        }
286
287        insert_macro_menu_entry(awm, true);
288
289        awm->create_menu("Properties", "P", AWM_ALL);
290        AW_insert_common_property_menu_entries(awm);
291        awm->sep______________();
292        awm->insert_menu_topic("save_props", "Save properties (ntree.arb)", "p", "savedef.hlp", AWM_ALL, AW_save_properties);
293
294        awm->insert_help_topic("ARB_MERGE help", "M", "arb_merge.hlp", AWM_ALL, makeHelpCallback("arb_merge.hlp"));
295
296
297        // display involved databases
298        awm->button_length(28);
299
300        awm->at("db1"); awm->create_button(0, AWAR_DB_SRC"/name", 0, "+");
301        awm->at("db2"); awm->create_button(0, AWAR_DB_DST"/name", 0, "+");
302
303
304        // add main controls
305        awm->button_length(32);
306
307        {
308            // conditional section:
309            // when exporting into a new database there is no need to adapt alignments or names
310
311            if (dst_is_new) awm->sens_mask(AWM_DISABLED);
312
313            awm->at("alignment");
314            awm->callback(MG_create_merge_alignment_window);
315            awm->help_text("mg_alignment.hlp");
316            awm->create_button("CHECK_ALIGNMENTS", "Check alignments ...");
317
318            awm->at("names");
319            awm->callback(MG_create_merge_names_window);
320            awm->help_text("mg_names.hlp");
321            awm->create_button("CHECK_NAMES", "Check IDs ...");
322
323            if (dst_is_new) {
324                awm->sens_mask(AWM_ALL);
325                MG_set_renamed(true, aw_root, "Not necessary");
326            }
327        }
328
329        awm->at("species");
330        awm->callback(makeCreateWindowCallback(MG_create_merge_species_window, dst_is_new));
331        awm->help_text("mg_species.hlp");
332        awm->create_button("TRANSFER_SPECIES", "Transfer species ... ");
333
334        awm->at("extendeds");
335        awm->callback(MG_create_merge_SAIs_window);
336        awm->help_text("mg_extendeds.hlp");
337        awm->create_button("TRANSFER_SAIS", "Transfer SAIs ...");
338
339        awm->at("trees");
340        awm->callback(MG_create_merge_trees_window);
341        awm->help_text("mg_trees.hlp");
342        awm->create_button("TRANSFER_TREES", "Transfer trees ...");
343
344        awm->at("configs");
345        awm->callback(MG_create_merge_configs_window);
346        awm->help_text("mg_configs.hlp");
347        awm->create_button("TRANSFER_CONFIGS", "Transfer configurations ...");
348
349        {
350            // conditional section:
351            // allow save only when not merging into DB running inside ARB_NT
352
353            if (!save_dst_enabled) awm->sens_mask(AWM_DISABLED);
354
355            awm->at("save");
356            awm->callback(makeCreateWindowCallback(MG_create_save_result_window, AWAR_DB_DST));
357            awm->create_button("SAVE_WHOLE_DB2", "Save whole target DB as ...");
358
359            awm->at("save_quick");
360            awm->callback(MG_save_quick_result_cb);
361            awm->create_button("SAVE_CHANGES_OF_DB2", "Quick-save changes of target DB");
362
363            awm->sens_mask(AWM_ALL);
364        }
365
366        awm->at("quit");
367        awm->callback(makeWindowCallback(MG_exit, false));
368        awm->create_button("QUIT", save_dst_enabled ? "Quit" : "Close");
369
370        awm->activate();
371
372        return awm;
373    }
374}
375
376void MERGE_create_all_awars(AW_root *awr, AW_default aw_def) {
377    MG_create_trees_awar(awr, aw_def);
378    MG_create_config_awar(awr, aw_def);
379    MG_create_extendeds_awars(awr, aw_def);
380    MG_create_alignment_awars(awr, aw_def);
381    MG_create_species_awars(awr, aw_def);
382    MG_create_gene_species_awars(awr, aw_def);
383
384    MG_create_rename_awars(awr, aw_def);
385
386#if defined(DEBUG)
387    AWT_create_db_browser_awars(awr, aw_def);
388#endif // DEBUG
389}
390
391inline const char *get_awar_name(const char *awar_base_name, const char *entry) {
392    return GBS_global_string("%s/%s", awar_base_name, entry);
393}
394
395static void filename_changed_cb(AW_root *awr, const char *awar_base_name) {
396    AW_awar *filename_awar = awr->awar(get_awar_name(awar_base_name, "file_name"));
397
398    char *name;
399    char *suffix;
400    GB_split_full_path(filename_awar->read_char_pntr(), NULL, NULL, &name, &suffix);
401
402    if (name) {
403        AW_awar    *name_awar = awr->awar(get_awar_name(awar_base_name, "name"));
404        const char *shown_name;
405        if (strcmp(name, ":") == 0 && !suffix) {
406            shown_name = ": (DB loaded in ARB_NT)";
407        }
408        else {
409            shown_name = GB_append_suffix(name, suffix);
410        }
411        name_awar->write_string(shown_name);
412    }
413
414    free(name);
415    free(suffix);
416}
417
418static void create_fileselection_and_name_awars(AW_root *awr, AW_default aw_def, const char *awar_base_name, const char *filename) {
419    AW_create_fileselection_awars(awr, awar_base_name, "", ".arb", filename);
420
421    awr->awar_string(get_awar_name(awar_base_name, "name"), "", aw_def); // create awar to display DB-names w/o path
422    AW_awar *filename_awar = awr->awar(get_awar_name(awar_base_name, "file_name")); // defined by AW_create_fileselection_awars above
423
424    filename_awar->add_callback(makeRootCallback(filename_changed_cb, awar_base_name));
425    filename_awar->touch(); // trigger callback once
426}
427
428void MERGE_create_db_file_awars(AW_root *awr, AW_default aw_def, const char *src_name, const char *dst_name) {
429    create_fileselection_and_name_awars(awr, aw_def, AWAR_DB_DST, dst_name);
430    awr->awar_string(AWAR_DB_DST"/type", "b", aw_def);
431
432    create_fileselection_and_name_awars(awr, aw_def, AWAR_DB_SRC, src_name);
433}
434
Note: See TracBrowser for help on using the repository browser.