52
54
GB_push_transaction(gb_main);
53
55
GB_push_my_security(gb_main);
55
aw_status("Checking alignments");
56
err = GBT_check_data(gb_main, 0);
58
AW_repeated_question question;
59
GBDATA *gb_presets = GB_entry(gb_main,"presets");
61
question.add_help("prompt/format_alignments.hlp");
63
for (GBDATA *gb_ali = GB_entry(gb_presets,"alignment"); gb_ali && !err; gb_ali = GB_nextEntry(gb_ali)) {
64
GBDATA *gb_aligned = GB_search(gb_ali, "aligned", GB_INT);
66
if (GB_read_int(gb_aligned) == 0) { // sequences in alignment are not formatted
68
FA_ASK_USER = 0, // ask user
69
FA_FORMAT_ALL = 1, // format automatically w/o asking
70
FA_SKIP_ALL = 2, // skip automatically w/o asking
72
FormatAction format_action = FA_ASK_USER;
73
GBDATA *gb_ali_name = GB_entry(gb_ali,"alignment_name");
74
const char *ali_name = GB_read_char_pntr(gb_ali_name);
77
bool is_ali_genom = strcmp(ali_name, GENOM_ALIGNMENT) == 0;
78
GBDATA *gb_auto_format = GB_entry(gb_ali, "auto_format");
81
format_action = FormatAction(GB_read_int(gb_auto_format));
83
if (format_action != FA_SKIP_ALL) {
84
format_action = FA_SKIP_ALL; // always skip ali_genom
85
err = GB_write_int(gb_auto_format, FA_SKIP_ALL);
89
else if (is_ali_genom) {
90
format_action = FA_SKIP_ALL;
91
err = GBT_write_int(gb_ali, "auto_format", FA_SKIP_ALL); // always skip
95
bool perform_format = false;
97
switch (format_action) {
98
case FA_FORMAT_ALL: perform_format = true; break;
99
case FA_SKIP_ALL: perform_format = false; break;
101
char *qtext = GBS_global_string_copy("Alignment '%s' is not formatted. Format?", ali_name);
102
int answer = question.get_answer(qtext, "Format,Skip,Always format,Always skip", "all", false);
106
err = GBT_write_int(gb_ali, "auto_format", FA_FORMAT_ALL);
109
perform_format = true;
113
err = GBT_write_int(gb_ali, "auto_format", FA_SKIP_ALL);
122
if (!err && perform_format) {
123
aw_status(GBS_global_string("Formatting '%s'", ali_name));
124
GB_push_my_security(gb_main);
125
err = GBT_format_alignment(gb_main, ali_name);
126
GB_pop_my_security(gb_main);
57
int ali_count = GBT_count_alignments(gb_main);
59
arb_progress progress("Formatting alignments", ali_count);
60
err = GBT_check_data(gb_main, 0);
62
AW_repeated_question question;
63
question.add_help("prompt/format_alignments.hlp");
65
GBDATA *gb_presets = GBT_get_presets(gb_main);
66
for (GBDATA *gb_ali = GB_entry(gb_presets, "alignment");
68
gb_ali = GB_nextEntry(gb_ali))
70
GBDATA *gb_aligned = GB_search(gb_ali, "aligned", GB_INT);
72
if (GB_read_int(gb_aligned) == 0) { // sequences in alignment are not formatted
74
FA_ASK_USER = 0, // ask user
75
FA_FORMAT_ALL = 1, // format automatically w/o asking
76
FA_SKIP_ALL = 2, // skip automatically w/o asking
78
FormatAction format_action = FA_ASK_USER;
79
GBDATA *gb_ali_name = GB_entry(gb_ali, "alignment_name");
80
const char *ali_name = GB_read_char_pntr(gb_ali_name);
83
bool is_ali_genom = strcmp(ali_name, GENOM_ALIGNMENT) == 0;
84
GBDATA *gb_auto_format = GB_entry(gb_ali, "auto_format");
87
format_action = FormatAction(GB_read_int(gb_auto_format));
89
if (format_action != FA_SKIP_ALL) {
90
format_action = FA_SKIP_ALL; // always skip ali_genom
91
err = GB_write_int(gb_auto_format, FA_SKIP_ALL);
95
else if (is_ali_genom) {
96
format_action = FA_SKIP_ALL;
97
err = GBT_write_int(gb_ali, "auto_format", FA_SKIP_ALL); // always skip
101
bool perform_format = false;
103
switch (format_action) {
104
case FA_FORMAT_ALL: perform_format = true; break;
105
case FA_SKIP_ALL: perform_format = false; break;
107
char *qtext = GBS_global_string_copy("Alignment '%s' is not formatted. Format?", ali_name);
108
int answer = question.get_answer("format_alignments", qtext, "Format,Skip,Always format,Always skip", "all", false);
112
err = GBT_write_int(gb_ali, "auto_format", FA_FORMAT_ALL);
115
perform_format = true;
119
err = GBT_write_int(gb_ali, "auto_format", FA_SKIP_ALL);
128
if (!err && perform_format) {
129
GB_push_my_security(gb_main);
130
err = ARB_format_alignment(gb_main, ali_name);
131
GB_pop_my_security(gb_main);
134
progress.inc_and_check_user_abort(err);
137
144
// --------------------------------------------------------------------------------
141
// called once on ARB_NTREE startup
143
147
static GB_ERROR nt_check_database_consistency() {
144
aw_openstatus("Checking database...");
146
GB_ERROR err = NT_format_all_alignments(GLOBAL_gb_main);
147
if (!err) err = NT_repair_DB(GLOBAL_gb_main);
148
// called once on ARB_NTREE startup
149
arb_progress cons_progress("Checking consistency");
151
GB_ERROR err = NT_format_all_alignments(GLOBAL.gb_main);
152
if (!err) err = NT_repair_DB(GLOBAL.gb_main);
154
void serve_db_interrupt(AW_root *awr){
155
GB_BOOL succes = GBCMS_accept_calls(GLOBAL_gb_main,GB_FALSE);
157
awr->check_for_remote_command((AW_default)GLOBAL_gb_main,AWAR_NT_REMOTE_BASE);
158
succes = GBCMS_accept_calls(GLOBAL_gb_main,GB_TRUE);
161
awr->add_timed_callback(NT_SERVE_DB_TIMER,(AW_RCB)serve_db_interrupt,0,0);
164
void check_db_interrupt(AW_root *awr){
165
awr->check_for_remote_command((AW_default)GLOBAL_gb_main,AWAR_NT_REMOTE_BASE);
166
awr->add_timed_callback(NT_CHECK_DB_TIMER,(AW_RCB)check_db_interrupt,0,0);
169
GB_ERROR create_nt_window(AW_root *aw_root){
171
GB_ERROR error = GB_request_undo_type(GLOBAL_gb_main, GB_UNDO_NONE);
172
if (error) aw_message(error);
173
nt_create_all_awars(aw_root,AW_ROOT_DEFAULT);
174
aww = create_nt_main_window(aw_root,0);
176
error = GB_request_undo_type(GLOBAL_gb_main, GB_UNDO_UNDO);
177
if (error) aw_message(error);
182
void nt_main_startup_main_window(AW_root *aw_root){
183
create_nt_window(aw_root);
185
if (GB_read_clients(GLOBAL_gb_main)==0) { // i am the server
186
GB_ERROR error = GBCMS_open(":",0,GLOBAL_gb_main);
189
"THIS PROGRAM HAS PROBLEMS TO OPEN INTERCLIENT COMMUNICATION !!!\n"
190
"(MAYBE THERE IS ALREADY ANOTHER SERVER RUNNING)\n\n"
191
"You cannot use any EDITOR or other external SOFTWARE with this dataset!\n\n"
192
"Advice: Close ARB again, open a console, type 'arb_clean' and restart arb.\n"
193
"Caution: Any unsaved data in an eventually running ARB will be lost!\n");
195
aw_root->add_timed_callback(NT_SERVE_DB_TIMER,(AW_RCB)serve_db_interrupt,0,0);
157
__ATTR__USERESULT static GB_ERROR startup_mainwindow_and_dbserver(AW_root *aw_root, const char *autorun_macro) {
158
AWT_initTreeAwarRegistry(GLOBAL.gb_main);
160
GB_ERROR error = configure_macro_recording(aw_root, "ARB_NT", GLOBAL.gb_main); // @@@ problematic if called from startup-importer
162
nt_create_main_window(aw_root);
163
if (GB_is_server(GLOBAL.gb_main)) {
196
164
error = nt_check_database_consistency();
197
if (error) aw_message(error);
165
if (!error) NT_repair_userland_problems();
200
aw_root->add_timed_callback(NT_CHECK_DB_TIMER,(AW_RCB)check_db_interrupt,0,0);
169
if (!error && autorun_macro) execute_macro(aw_root, autorun_macro); // @@@ triggering execution here is ok, but its a bad place to pass 'autorun_macro'. Should be handled more generally
204
int main_load_and_startup_main_window(AW_root *aw_root) // returns 0 when successfull
174
static ARB_ERROR load_and_startup_main_window(AW_root *aw_root, const char *autorun_macro) {
207
175
char *db_server = aw_root->awar(AWAR_DB_PATH)->read_string();
208
GLOBAL_gb_main = GBT_open(db_server,"rw","$(ARBHOME)/lib/pts/*");
176
GLOBAL.gb_main = GBT_open(db_server, "rw");
210
if (!GLOBAL_gb_main) {
211
aw_popup_ok(GB_await_error());
179
if (!GLOBAL.gb_main) {
180
error = GB_await_error();
215
aw_root->awar(AWAR_DB_PATH)->write_string(db_server);
217
#define MAXNAMELEN 35
218
int len = strlen(db_server);
219
if (len>MAXNAMELEN) {
220
char *nameOnly = strrchr(db_server, '/');
223
len -= (nameOnly-db_server);
224
memmove(db_server, nameOnly, len+1);
225
if (len>MAXNAMELEN) {
226
strcpy(db_server+MAXNAMELEN-3, "...");
183
aw_root->awar(AWAR_DB_PATH)->write_string(db_server);
185
#define MAXNAMELEN 35
186
int len = strlen(db_server);
187
if (len>MAXNAMELEN) {
188
char *nameOnly = strrchr(db_server, '/');
191
len -= (nameOnly-db_server);
192
memmove(db_server, nameOnly, len+1);
193
if (len>MAXNAMELEN) {
194
strcpy(db_server+MAXNAMELEN-3, "...");
230
198
#if defined(DEBUG)
231
AWT_announce_db_to_browser(GLOBAL_gb_main, GBS_global_string("ARB database (%s)", db_server));
199
AWT_announce_db_to_browser(GLOBAL.gb_main, GBS_global_string("ARB database (%s)", db_server));
202
GB_ERROR problem = startup_mainwindow_and_dbserver(aw_root, autorun_macro);
203
aw_message_if(problem); // no need to terminate ARB
235
nt_main_startup_main_window(aw_root);
240
void nt_delete_database(AW_window *aww){
241
char *db_server = aww->get_root()->awar(AWAR_DB_PATH)->read_string();
242
if (strlen(db_server)){
243
if (aw_ask_sure(GBS_global_string("Are you sure to delete database %s\nNote: there is no way to undelete it afterwards", db_server))) {
245
error = GB_delete_database(db_server);
210
static void nt_delete_database(AW_window *aww) {
211
AW_root *aw_root = aww->get_root();
212
char *db_server = aw_root->awar(AWAR_DB_PATH)->read_string();
214
if (strlen(db_server)) {
215
if (aw_ask_sure(NULL, GBS_global_string("Are you sure to delete database %s\nNote: there is no way to undelete it afterwards", db_server))) {
216
GB_ERROR error = GB_delete_database(db_server);
247
218
aw_message(error);
250
aww->get_root()->awar(AWAR_DB"filter")->touch();
221
aw_root->awar(AWAR_DB_FILTER)->touch();
260
// after import !!!!!
261
void main3(AW_root *aw_root)
264
GLOBAL_NT.awr = aw_root;
265
create_nt_window(aw_root);
267
if (GB_read_clients(GLOBAL_gb_main)==0) {
268
GB_ERROR error = GBCMS_open(":",0,GLOBAL_gb_main);
270
aw_message("THIS PROGRAM IS NOT THE ONLY DB SERVER !!!\nDON'T USE ANY ARB PROGRAM !!!!");
272
aw_root->add_timed_callback(NT_SERVE_DB_TIMER, (AW_RCB)serve_db_interrupt,0,0);
273
error = nt_check_database_consistency();
274
if (error) aw_message(error);
280
void nt_intro_start_old(AW_window *aws)
283
if (main_load_and_startup_main_window(aws->get_root())) {
288
void nt_intro_start_merge(AW_window *aws,AW_root *awr){
289
if (aws) awr = aws->get_root();
290
create_MG_main_window(awr);
291
if (aws) aws->hide();
294
void nt_intro_start_import(AW_window *aws)
297
aws->get_root()->awar_string( AWAR_DB_PATH )->write_string( "noname.arb");
298
aws->get_root()->awar_int(AWAR_READ_GENOM_DB, IMP_PLAIN_SEQUENCE); // Default toggle in window "Create&import" is Non-Genom
299
GLOBAL_gb_main = open_AWTC_import_window(aws->get_root(), "", true, 0, (AW_RCB)main3, 0, 0);
302
AW_window *nt_create_intro_window(AW_root *awr)
231
static void start_main_window_after_import(AW_root *aw_root) {
232
GLOBAL.aw_root = aw_root;
234
GBDATA *gb_imported = AWTI_take_imported_DB_and_cleanup_importer();
235
nt_assert(gb_imported == GLOBAL.gb_main); // import-DB should already be used as main-DB
236
GLOBAL.gb_main = gb_imported;
238
aw_message_if(startup_mainwindow_and_dbserver(aw_root, NULL));
241
static void nt_intro_start_existing(AW_window *aw_intro) {
243
ARB_ERROR error = load_and_startup_main_window(aw_intro->get_root(), NULL);
244
nt_assert(contradicted(error, got_macro_ability(aw_intro->get_root())));
247
aw_popup_ok(error.deliver());
250
error.expect_no_error();
254
static void nt_intro_start_merge(AW_window *aw_intro) {
255
AW_root *aw_root = aw_intro->get_root();
256
const char *dir = aw_root->awar("tmp/nt/arbdb/directory")->read_char_pntr();
257
char *merge_args = GBS_global_string_copy("'%s' '%s'", dir, dir);
259
nt_restart(aw_root, merge_args); // call arb_ntree as merge-tool on exit
262
static void nt_intro_start_import(AW_window *aw_intro) {
265
AW_root *aw_root = aw_intro->get_root();
266
aw_root->awar_string(AWAR_DB_PATH)->write_string("noname.arb");
267
aw_root->awar_int(AWAR_READ_GENOM_DB, IMP_PLAIN_SEQUENCE); // Default toggle in window "Create&import" is Non-Genom
269
nt_assert(!GLOBAL.gb_main);
270
AWTI_open_import_window(aw_root, "", true, 0, makeRootCallback(start_main_window_after_import));
271
GLOBAL.gb_main = AWTI_peek_imported_DB();
273
nt_assert(got_macro_ability(aw_root));
276
static AW_window *nt_create_intro_window(AW_root *awr) {
304
277
AW_window_simple *aws = new AW_window_simple;
305
aws->init( awr, "ARB_INTRO", "ARB INTRO");
278
aws->init(awr, "ARB_INTRO", "ARB INTRO");
306
279
aws->load_xfig("arb_intro.fig");
308
aws->callback( (AW_CB0)exit);
281
aws->callback(nt_exit, EXIT_SUCCESS);
309
282
aws->at("close");
310
aws->create_button("CANCEL","CANCEL","C");
283
aws->create_button("EXIT", "Exit", "x");
313
aws->callback(AW_POPUP_HELP,(AW_CL)"arb_intro.hlp");
314
aws->create_button("HELP","HELP","H");
286
aws->callback(makeHelpCallback("arb_intro.hlp"));
287
aws->create_button("HELP", "HELP", "H");
316
awt_create_selection_box(aws,"tmp/nt/arbdb");
289
AW_create_standard_fileselection(aws, "tmp/nt/arbdb");
318
291
aws->button_length(0);
321
aws->create_button(0,"#logo.xpm");
294
aws->create_button(0, "#logo.xpm");
323
296
aws->at("version");
324
297
aws->create_button(0, GBS_global_string("Version " ARB_VERSION), 0); // version
385
// ---------------------------------------
386
// int main(int argc, char **argv)
387
// ---------------------------------------
388
int main(int argc, char **argv)
391
AW_default aw_default;
393
const char *db_server =":";
395
unsigned long mtime = GB_time_of_file("$(ARBHOME)/lib/message");
396
unsigned long rtime = GB_time_of_file("$(HOME)/.arb_prop/msgtime");
398
AWT_edit("${ARBHOME}/lib/message");
399
system("touch ${HOME}/.arb_prop/msgtime");
404
aw_root = new AW_root;
405
GLOBAL_NT.awr = aw_root;
406
AD_set_default_root(aw_root); // set default for AD_map_viewer (as long as no info-box was opened)
408
aw_default = aw_root->open_default(".arb_prop/ntree.arb");
409
aw_root->init_variables(aw_default);
410
aw_root->init_root("ARB_NT", false);
349
class NtreeCommandLine : virtual Noncopyable {
351
char const*const* args;
356
const char *macro_name;
359
NtreeCommandLine(int argc_, char const*const* argv_)
360
: arg_count(argc_-1),
362
help_requested(false),
367
void shift() { ++args; --arg_count; }
369
int free_args() const { return arg_count; }
370
const char *get_arg(int num) const { return num<arg_count ? args[num] : NULL; }
372
bool wants_help() const { return help_requested; }
373
bool wants_import() const { return do_import; }
374
bool wants_merge() const { return arg_count == 2; }
376
const char *autorun_macro() const { return macro_name; }
378
void print_help(FILE *out) const {
381
"arb_ntree version " ARB_VERSION_DETAILED "\n"
382
"(C) 1993-" ARB_BUILD_YEAR " Lehrstuhl fuer Mikrobiologie - TU Muenchen\n"
383
"http://www.arb-home.de/\n"
384
"(version build by: " ARB_BUILD_USER "@" ARB_BUILD_HOST ")\n"
387
" arb_ntree => start ARB (intro)\n"
388
" arb_ntree DB => start ARB with DB\n"
389
" arb_ntree DB1 DB2 => merge from DB1 into DB2\n"
390
" arb_ntree --import FILE => import FILE into new database (FILE may be a filemask)\n"
392
"Additional arguments possible with command lines above:\n"
393
" --execute macroname => execute macro 'macroname' after startup\n"
395
"Each DB argument may be one of the following:\n"
396
" database.arb -> use existing or new database\n"
397
" \":\" -> connect to database of a running instance of ARB\n"
398
" directory -> prompt for databases inside directory\n"
399
" filemask -> also prompt for DB, but more specific (e.g. \"prot*.arb\")\n"
407
while (!error && arg_count>0 && args[0][0] == '-') {
408
const char *opt = args[0]+1;
409
if (opt[0] == '-') ++opt; // accept '-' or '--'
410
if (strcmp(opt, "help") == 0 || strcmp(opt, "h") == 0) { help_requested = true; }
411
else if (strcmp(opt, "execute") == 0) { shift(); macro_name = *args; }
412
else if (strcmp(opt, "import") == 0) { do_import = true; }
414
// bunch of test switches to provoke various ways to terminate (see also http://bugs.arb-home.de/ticket/538)
415
else if (strcmp(opt, "crash") == 0) { GBK_terminate("crash requested"); }
416
else if (strcmp(opt, "trap") == 0) { arb_assert(0); }
417
else if (strcmp(opt, "sighup") == 0) { raise(SIGHUP); }
418
else if (strcmp(opt, "sigsegv") == 0) { raise(SIGSEGV); }
419
else if (strcmp(opt, "sigterm") == 0) { raise(SIGTERM); }
420
else if (strcmp(opt, "fail") == 0) { exit(EXIT_FAILURE); }
421
else if (strcmp(opt, "exit") == 0) { exit(EXIT_SUCCESS); }
422
// end of test switches ----------------------------------------
424
else error = GBS_global_string("Unknown switch '%s'", args[0]);
427
// non-switch arguments remain in arg_count/args
429
if (do_import && arg_count != 1) error = "expected exactly one file-name or file-mask behind --import";
430
else if (arg_count>2) error = "too many stray arguments given (max. 2 accepted)";
436
enum ArgType { // args that might be specified on command line (for DB or FILE; see above)
446
inline bool has_arb_suffix(const char *arg) {
447
const char *suffix = strstr(arg, ".arb");
449
return strcmp(suffix, ".arb") == 0;
454
static ArgType detectArgType(const char *arg) {
455
if (strcmp(arg, ":") == 0) return RUNNING_DB;
456
if (GB_is_directory(arg)) return DIRECTORY;
457
if (strpbrk(arg, "*?") != 0) return FILEMASK;
458
if (has_arb_suffix(arg)) {
459
return GB_is_regularfile(arg) ? EXISTING_DB : NEW_DB;
462
GB_ERROR load_file_err = GBT_check_arb_file(arg);
463
if (!load_file_err) return EXISTING_DB;
465
return GB_is_regularfile(arg) ? EXISTING_FILE : UNKNOWN_ARG;
468
enum RunMode { NORMAL, IMPORT, MERGE, BROWSE };
470
#define ABORTED_BY_USER "aborted by user"
472
static ARB_ERROR check_argument_for_mode(const char *database, char *&browser_startdir, RunMode& mode) {
473
// Check whether 'database' is a
478
// Modify 'mode' occordingly.
479
// Set 'browser_startdir'
482
if (mode != IMPORT) {
483
if (!database) mode = BROWSE;
485
GB_ERROR load_file_err = GBT_check_arb_file(database);
487
char *full_path = AW_unfold_path("PWD", database);
489
enum Action { LOAD_DB, CONVERT_DB, BROWSE_DB, EXIT, NOIDEA };
490
Action action = NOIDEA;
491
if (GB_is_directory(full_path)) {
495
if (!GB_is_regularfile(full_path)) {
496
const char *msg = GBS_global_string("'%s' is neither a known option nor a legal file- or directory-name.\n(Error: %s)",
497
full_path, load_file_err);
499
int ans = aw_question(NULL, msg, "Browser,Exit");
500
action = ans ? EXIT : BROWSE_DB;
503
const char *msg = GBS_global_string("Your file is not an original arb file\n(%s)", load_file_err);
504
action = (Action)aw_question(NULL, msg, "Continue (dangerous),Start Converter,Browser,Exit");
509
case CONVERT_DB: mode = IMPORT; break;
511
case NOIDEA: nt_assert(0);
512
case EXIT: error = ABORTED_BY_USER; break;
514
char *dir = nulldup(full_path);
515
while (dir && !GB_is_directory(dir)) freeset(dir, AW_extract_directory(dir));
518
nt_assert(GB_is_directory(dir));
519
reassign(browser_startdir, dir);
535
class SelectedDatabase : virtual Noncopyable {
542
if (type != RUNNING_DB && name[0]) {
545
if (type == NEW_DB) {
546
changed = GB_unfold_in_directory(GB_getcwd(), name);
549
changed = GB_canonical_path(name);
552
if (strcmp(name, changed) != 0) {
553
reselect_file(changed);
559
SelectedDatabase(GBDATA*& gb_main_, const char *name_, const char *role_)
562
type(detectArgType(name)),
567
~SelectedDatabase() {
572
ArgType arg_type() const { return type; }
574
bool needs_to_prompt() const {
575
return type == DIRECTORY || type == FILEMASK || type == UNKNOWN_ARG;
578
const char *get_fullname() const { return name; }
579
const char *get_nameonly() const {
580
const char *slash = strrchr(name, '/');
581
return slash ? slash+1 : name;
583
const char *get_role() const { return role; }
584
const char *get_description() const { return GBS_global_string("%s (%s)", get_role(), get_nameonly()); }
586
ArgType get_type() const { return type; }
588
const char *get_dir() const {
589
const char *dir = NULL;
592
dir = get_fullname();
600
GB_split_full_path(name, &dir_copy, NULL, NULL, NULL);
602
static SmartCharPtr dir_store;
603
dir_store = dir_copy;
616
const char *get_mask() const {
621
GB_split_full_path(name, NULL, &mask_copy, NULL, NULL);
623
static SmartCharPtr mask_store;
624
mask_store = mask_copy;
636
void reselect_file(const char *file) {
638
type = detectArgType(name);
641
void reselect_from_awar(AW_root *aw_root, const char *awar_name) {
643
const char *file = aw_root->awar(awar_name)->read_char_pntr();
644
if (file) reselect_file(file);
648
GB_ERROR open_db_for_merge(bool is_source_db);
649
void close_db() { if (gb_main) GB_close(gb_main); }
652
GB_ERROR SelectedDatabase::open_db_for_merge(bool is_source_db) {
653
GB_ERROR error = NULL;
654
const char *openMode = "rw";
656
switch (get_type()) {
659
GBK_terminate("Program logic error (should have been prompted for explicit DB name)");
664
error = GBS_global_string("'%s' is no arb-database", get_fullname());
669
error = GBS_global_string("'%s' has to exist", get_fullname());
672
openMode = "crw"; // allow to create DB
681
gb_main = GBT_open(get_fullname(), openMode);
682
if (!gb_main) error = GB_await_error();
684
IF_DEBUG(AWT_announce_db_to_browser(gb_main, get_description()));
691
struct merge_scheme : virtual Noncopyable {
692
SelectedDatabase *src;
693
SelectedDatabase *dst;
700
merge_scheme(SelectedDatabase *src_, SelectedDatabase *dst_)
720
if (!error) error = src->open_db_for_merge(true);
721
if (!error) error = dst->open_db_for_merge(false);
724
void fix_dst(AW_root *aw_root) { dst->reselect_from_awar(aw_root, awar_dst); }
725
void fix_src(AW_root *aw_root) { src->reselect_from_awar(aw_root, awar_src); }
727
bool knows_dbs() const { return !src->needs_to_prompt() && !dst->needs_to_prompt(); }
730
static bool merge_tool_running_as_client = true; // default to safe state (true avoids call of 'arb_clean' at exit)
731
static void exit_from_merge(const char *restart_args) {
732
if (merge_tool_running_as_client) { // there is a main ARB running
733
if (restart_args) nt_start(restart_args, true);
734
exit(EXIT_SUCCESS); // exit w/o killing clients (as nt_exit() does)
737
nt_restart(AW_root::SINGLETON, restart_args ? restart_args : "");
742
static void merge_startup_abort_cb(AW_window*) {
743
fputs("Error: merge aborted by user\n", stderr);
744
exit_from_merge(NULL);
747
static AW_window *merge_startup_error_window(AW_root *aw_root, GB_ERROR error) {
748
AW_window_simple *aw_msg = new AW_window_simple;
750
aw_msg->init(aw_root, "arb_merge_error", "ARB merge error");
751
aw_msg->recalc_size_atShow(AW_RESIZE_DEFAULT); // force size recalc (ignores user size)
754
aw_msg->auto_space(10, 10);
756
aw_msg->create_autosize_button(NULL, error, "", 2);
757
aw_msg->at_newline();
759
aw_msg->callback(merge_startup_abort_cb);
760
aw_msg->create_autosize_button("OK", "Ok", "O", 2);
762
aw_msg->window_fit();
766
static AW_window *startup_merge_main_window(AW_root *aw_root, merge_scheme *ms) {
767
ms->fix_src(aw_root);
768
ms->fix_dst(aw_root);
770
if (ms->knows_dbs()) {
774
ms->error = "Need two database to merge";
777
AW_window *aw_result;
779
MERGE_create_db_file_awars(aw_root, AW_ROOT_DEFAULT, ms->src->get_fullname(), ms->dst->get_fullname());
780
bool dst_is_new = ms->dst->arg_type() == NEW_DB;
781
aw_result = MERGE_create_main_window(aw_root, dst_is_new, exit_from_merge);
783
nt_assert(got_macro_ability(aw_root));
786
aw_result = merge_startup_error_window(aw_root, ms->error);
788
delete ms; // was allocated in startup_gui()
792
static AW_window *startup_merge_prompting_for_nonexplicit_dst_db(AW_root *aw_root, merge_scheme *ms) {
793
AW_window *aw_result;
794
if (ms->dst->needs_to_prompt()) {
795
aw_result = awt_create_load_box(aw_root, "Select", ms->dst->get_role(),
796
ms->dst->get_dir(), ms->dst->get_mask(),
798
AW_window::makeWindowReplacer(makeCreateWindowCallback(startup_merge_main_window, ms)),
799
makeWindowCallback(merge_startup_abort_cb), "Cancel");
802
aw_result = startup_merge_main_window(aw_root, ms);
807
static AW_window *startup_merge_prompting_for_nonexplicit_dbs(AW_root *aw_root, merge_scheme *ms) {
808
// if src_spec or dst_spec needs to be prompted for -> startup prompters with callbacks bound to continue
809
// otherwise just startup merge
811
AW_window *aw_result;
812
if (ms->src->needs_to_prompt()) {
813
aw_result = awt_create_load_box(aw_root, "Select", ms->src->get_role(),
814
ms->src->get_dir(), ms->src->get_mask(),
816
AW_window::makeWindowReplacer(makeCreateWindowCallback(startup_merge_prompting_for_nonexplicit_dst_db, ms)),
817
makeWindowCallback(merge_startup_abort_cb), "Cancel");
820
aw_result = startup_merge_prompting_for_nonexplicit_dst_db(aw_root, ms);
825
static void startup_gui(NtreeCommandLine& cl, ARB_ERROR& error) {
827
char *message = strdup(GB_path_in_ARBLIB("message"));
828
char *stamp = strdup(GB_path_in_arbprop("msgtime"));
829
if (GB_time_of_file(message)>GB_time_of_file(stamp)) {
831
aw_message_if(GBK_system(GBS_global_string("touch %s", stamp)));
412
837
// create some early awars
413
838
// Note: normally you don't like to add your awar-init-function here, but into nt_create_all_awars()
415
aw_create_selection_box_awars(aw_root, AWAR_DB, "", ".arb", "noname.arb", aw_default);
416
aw_root->awar_string( AWAR_DB"type", "b", aw_default);
418
aw_root->awar_int(AWAR_EXPERT, 0, aw_default);
420
aw_root->awar_string(AWAR_DB_NAME, "noname.arb", aw_default);
840
AW_root* aw_root = GLOBAL.aw_root;
842
AW_create_fileselection_awars(aw_root, AWAR_DB, "", ".arb", "noname.arb");
843
aw_root->awar_string(AWAR_DB_TYPE, "b");
844
aw_root->awar_string(AWAR_DB_NAME, "noname.arb");
421
845
aw_root->awar(AWAR_DB_PATH)->add_callback(AWAR_DB_PATH_changed_cb);
423
init_Advisor(aw_root, aw_default);
425
if (argc==3) { // looks like merge
426
if (argv[1][0] != '-') { // not if first argument is a switch
427
MG_create_all_awars(aw_root,aw_default,argv[1],argv[2]);
428
nt_intro_start_merge(0,aw_root);
429
aw_root->main_loop();
434
bool start_db_browser = true;
435
char *browser_startdir = strdup(".");
438
start_db_browser = false;
440
if (strcmp(argv[1], "--help")==0 ||
441
strcmp(argv[1], "-help")==0 ||
442
strcmp(argv[1], "-h")==0)
446
"arb_ntree version " ARB_VERSION "\n"
447
"(C) 1993-" ARB_BUILD_YEAR " Lehrstuhl fuer Mikrobiologie - TU Muenchen\n"
448
"http://www.arb-home.de/\n"
449
#if defined(SHOW_WHERE_BUILD)
450
"(version build by: " ARB_BUILD_USER "@" ARB_BUILD_HOST ")\n"
451
#endif // SHOW_WHERE_BUILD
453
"Known command line arguments:\n"
455
"db.arb => start ARB_NTREE with database db.arb\n"
456
": => start ARB_NTREE and connect to existing db_server\n"
457
"db1.arb db2.arb => merge databases db1.arb and db2.arb\n"
458
"-export => connect to existing ARB server and export database to noname.arb\n"
459
"-import file => import 'file' into new database\n"
460
"w/o arguments => start database browser\n"
467
if ( strcmp(argv[1],"-export")==0) {
468
MG_create_all_awars(aw_root,aw_default,":","noname.arb");
469
GLOBAL_gb_merge = GBT_open(":","rw",0);
470
if (!GLOBAL_gb_merge) {
471
aw_popup_ok(GB_await_error());
475
AWT_announce_db_to_browser(GLOBAL_gb_merge, "Current database (:)");
478
GLOBAL_gb_dest = GBT_open("noname.arb","cw",0);
480
AWT_announce_db_to_browser(GLOBAL_gb_dest, "New database (noname.arb)");
483
MG_start_cb2(NULL, aw_root, true, true);
484
aw_root->main_loop();
487
bool run_importer = false;
488
if (strcmp(argv[1], "-import") == 0) {
494
GB_ERROR load_file_err = 0;
495
if (!run_importer) load_file_err = GBT_check_arb_file(db_server);
499
char *full_path = AWT_unfold_path(db_server);
501
printf("load_file_err='%s'\n", load_file_err);
503
if (AWT_is_dir(full_path)) answer = 2; // autoselect browser
506
if (!AWT_is_file(full_path)) {
507
const char *msg = GBS_global_string("'%s' is neither a known option nor a legal file- or directory-name.\n(Error: %s)",
508
full_path, load_file_err);
509
answer = aw_question(msg, "Browser,Exit");
511
switch (answer) { // map answer to codes used by aw_message below
512
case 0: answer = 2; break; // Browse
513
case 1: answer = 3; break; // Exit
514
default : nt_assert(0);
518
const char *msg = GBS_global_string("Your file is not an original arb file\n(%s)", load_file_err);
519
answer = aw_question(msg, "Continue (dangerous),Start Converter,Browser,Exit");
524
case 0: { // Continue
527
case 1: { // Start converter
532
char *dir = nulldup(full_path);
533
while (dir && !AWT_is_dir(dir)) freeset(dir, AWT_extract_directory(dir));
536
nt_assert(AWT_is_dir(dir));
537
reassign(browser_startdir, dir);
538
start_db_browser = true;
555
aw_root->awar_int(AWAR_READ_GENOM_DB, IMP_PLAIN_SEQUENCE);
556
GLOBAL_gb_main = open_AWTC_import_window(aw_root, db_server, true, 0, (AW_RCB)main3, 0, 0);
557
aw_root->main_loop();
562
if (start_db_browser) {
563
aw_root->awar(AWAR_DB"directory")->write_string(browser_startdir);
564
char *latest = GB_find_latest_file(browser_startdir, "/\\.(arb|a[0-9]{2})$/");
566
int l = strlen(latest);
570
aw_root->awar(AWAR_DB_PATH)->write_string(latest);
574
if (GLOBAL_NT.window_creator){
575
iws = GLOBAL_NT.window_creator(aw_root,0);
577
iws = nt_create_intro_window(aw_root);
580
aw_root->main_loop();
584
printf("Aborting.\n");
847
aw_root->awar_int(AWAR_EXPERT, 0);
849
AWT_install_cb_guards();
851
ARB_declare_global_awars(aw_root, AW_ROOT_DEFAULT);
853
aw_root->setUserActionTracker(new NullTracker); // no macro recording inside prompters that may popup
855
nt_assert(!cl.wants_help());
857
RunMode mode = NORMAL;
859
if (cl.wants_merge()) mode = MERGE;
860
else if (cl.wants_import()) mode = IMPORT;
863
MERGE_create_all_awars(aw_root, AW_ROOT_DEFAULT);
865
merge_scheme *ms = new merge_scheme( // freed in startup_merge_main_window()
866
new SelectedDatabase(GLOBAL_gb_src, cl.get_arg(0), "Source DB for merge"),
867
new SelectedDatabase(GLOBAL_gb_dst, cl.get_arg(1), "Destination DB for merge"));
869
merge_tool_running_as_client = ms->src->arg_type() == RUNNING_DB || ms->dst->arg_type() == RUNNING_DB;
871
if (ms->src->arg_type() == RUNNING_DB && ms->dst->arg_type() == RUNNING_DB) {
872
error = "You cannot merge from running to running DB";
875
aw_root->setUserActionTracker(new NullTracker); // no macro recording during startup of merge tool (file prompts)
876
AW_window *aww = startup_merge_prompting_for_nonexplicit_dbs(aw_root, ms);
878
nt_assert(contradicted(aww, error));
882
aw_root->main_loop();
888
const char *database = NULL;
889
char *browser_startdir = strdup(".");
891
if (cl.free_args() > 0) database = cl.get_arg(0);
893
error = check_argument_for_mode(database, browser_startdir, mode);
895
if (mode == IMPORT) {
896
aw_root->awar_int(AWAR_READ_GENOM_DB, IMP_PLAIN_SEQUENCE);
898
AWTI_open_import_window(aw_root, database, true, 0, makeRootCallback(start_main_window_after_import));
899
nt_assert(!GLOBAL.gb_main);
900
GLOBAL.gb_main = AWTI_peek_imported_DB();
902
nt_assert(got_macro_ability(aw_root));
903
aw_root->main_loop();
905
else if (mode == NORMAL) {
906
aw_root->awar(AWAR_DB_PATH)->write_string(database);
907
error = load_and_startup_main_window(aw_root, cl.autorun_macro());
909
nt_assert(got_macro_ability(aw_root));
910
aw_root->main_loop();
913
else if (mode == BROWSE) {
914
aw_root->awar(AWAR_DB"directory")->write_string(browser_startdir);
915
char *latest = GB_find_latest_file(browser_startdir, "/\\.(arb|a[0-9]{2})$/");
917
int l = strlen(latest);
918
strcpy(latest+l-3, "arb");
919
aw_root->awar(AWAR_DB_PATH)->write_string(latest);
922
nt_create_intro_window(aw_root)->show();
923
aw_root->setUserActionTracker(new NullTracker); // no macro recording inside intro window
924
aw_root->main_loop();
927
free(browser_startdir);
932
const char *msg = error.preserve();
933
if (strcmp(msg, ABORTED_BY_USER) != 0) aw_popup_ok(msg);
937
int ARB_main(int argc, char *argv[]) {
939
// i really dont want 'arb_ntree --help' to startup the GUI
940
// hack: parse CL twice
941
NtreeCommandLine cl(argc, argv);
942
bool cl_ok = !cl.parse().deliver();
944
if (cl.wants_help()) {
945
cl.print_help(stderr);
955
AW_root *aw_root = AWT_create_root("ntree.arb", "ARB_NT", need_macro_ability(), &argc, &argv);
957
GLOBAL.aw_root = aw_root;
959
NtreeCommandLine cl(argc, argv);
960
ARB_ERROR error = cl.parse();
963
if (cl.wants_help()) {
964
cl.print_help(stderr);
967
startup_gui(cl, error);
971
int exitcode = EXIT_SUCCESS;
973
exitcode = EXIT_FAILURE;
974
fprintf(stderr, "arb_ntree: Error: %s\n", error.deliver());
587
aw_root->awar(AWAR_DB_PATH)->write_string(db_server);
588
if (main_load_and_startup_main_window(aw_root)) return -1;
589
aw_root->main_loop();
977
error.expect_no_error();