source: branches/stable/MERGE/MG_main.cxx

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