source: branches/species/NTREE/NT_edconf.cxx

Last change on this file was 19702, checked in by westram, 2 days ago
  • rename enum types + values.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : NT_edconf.cxx                                     //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "NT_local.h"
12
13#include <TreeDisplay.hxx>
14
15#include <sel_boxes.hxx>
16#include <selection_admin.h>
17#include <config_manager.hxx>
18
19#include <aw_awars.hxx>
20#include <aw_root.hxx>
21#include <aw_msg.hxx>
22#include <aw_select.hxx>
23#include <aw_system.hxx>
24
25#include <ad_config.h>
26#include <ad_cb_prot.h>
27
28#include <map>
29
30using namespace std;
31
32// AWT_canvas-local (%i=canvas-id):
33#define AWAR_CL_SELECTED_CONFIGS       "configuration_data/win%i/selected"
34#define AWAR_CL_DISPLAY_CONFIG_MARKERS "configuration_data/win%i/display"
35
36#define AWAR_CONFIG_COMMENT "tmp/configuration/comment"
37#define AWAR_CONFIGURATION  "focus/configuration"
38
39typedef map<string, string> ConfigHits; // key=speciesname; value[markerIdx]==1 -> highlighted
40
41class ConfigMarkerDisplay FINAL_TYPE : public MarkerDisplay, virtual Noncopyable {
42    GBDATA                  *gb_main;
43    SmartPtr<ConstStrArray>  config; // configuration names
44    StrArray                 errors; // config load-errors
45    ConfigHits               hits;
46
47    void updateHits() {
48        flush_cache();
49        hits.clear();
50        errors.erase();
51        for (int c = 0; c<size(); ++c) {
52            GB_ERROR   error;
53            GBT_config cfg(gb_main, (*config)[c], error);
54
55            for (int area = 0; area<=1 && !error; ++area) {
56                GBT_config_parser cparser(cfg, area);
57
58                while (1) {
59                    const GBT_config_item& item = cparser.nextItem(error);
60                    if (error || item.type == CI_END_OF_CONFIG) break;
61                    if (item.type == CI_SPECIES) {
62                        ConfigHits::iterator found = hits.find(item.name);
63                        if (found == hits.end()) {
64                            string h(size(), '0');
65                            h[c]            = '1';
66                            hits[item.name] = h;
67                        }
68                        else {
69                            (found->second)[c] = '1';
70                        }
71                    }
72                }
73            }
74
75            errors.put(ARB_strdup(null2empty(error)));
76        }
77    }
78
79public:
80    ConfigMarkerDisplay(SmartPtr<ConstStrArray> config_, GBDATA *gb_main_)
81        : MarkerDisplay(config_->size()),
82          gb_main(gb_main_),
83          config(config_)
84    {
85        updateHits();
86    }
87    const char *get_marker_name(int markerIdx) const OVERRIDE {
88        const char *error = errors[markerIdx];
89        const char *name  = (*config)[markerIdx];
90        if (error && error[0]) return GBS_global_string("%s (Error: %s)", name, error);
91        return name;
92    }
93    void retrieve_marker_state(const char *speciesName, NodeMarkers& node) OVERRIDE {
94        ConfigHits::const_iterator found = hits.find(speciesName);
95        if (found != hits.end()) {
96            const string& hit = found->second;
97
98            for (int c = 0; c<size(); ++c) {
99                if (hit[c] == '1') node.incMarker(c);
100            }
101        }
102        node.incNodeSize();
103    }
104
105    void handle_click(int markerIdx, AW_MouseButton button, AWT_graphic_exports& exports) OVERRIDE {
106        if (button == AW_BUTTON_LEFT || button == AW_BUTTON_RIGHT) {
107            const char *markerName = get_marker_name(markerIdx);
108            AW_root::SINGLETON->awar(AWAR_CONFIGURATION)->write_string(markerName); // select config of clicked marker
109            if (button == AW_BUTTON_RIGHT) { // extract configuration
110                extract_species_selection(GLOBAL.gb_main, markerName, SELECTION_EXTRACT);
111                exports.request_structure_update(); // request to recalculate branch colors
112            }
113        }
114    }
115};
116
117inline bool displays_config_markers(MarkerDisplay *md) { return dynamic_cast<ConfigMarkerDisplay*>(md); }
118
119#define CONFIG_SEPARATOR "\1"
120
121inline AW_awar *get_canvas_awar(const char *awar_name_format, int canvas_id) {
122    return AW_root::SINGLETON->awar_no_error(GBS_global_string(awar_name_format, canvas_id));
123}
124inline AW_awar *get_config_awar        (int canvas_id) { return get_canvas_awar(AWAR_CL_SELECTED_CONFIGS,       canvas_id); }
125inline AW_awar *get_display_toggle_awar(int canvas_id) { return get_canvas_awar(AWAR_CL_DISPLAY_CONFIG_MARKERS, canvas_id); }
126
127static SmartPtr<ConstStrArray> get_selected_configs_from_awar(int canvas_id) {
128    // returns configs stored in awar as array (empty array if awar undefined!)
129    SmartPtr<ConstStrArray> config(new ConstStrArray);
130
131    AW_awar *awar = get_config_awar(canvas_id);
132    if (awar) {
133        char *config_str = awar->read_string();
134        GBT_splitNdestroy_string(*config, config_str, CONFIG_SEPARATOR, SPLIT_DROPEMPTY);
135    }
136
137    return config;
138}
139static void write_configs_to_awar(int canvas_id, const CharPtrArray& configs) {
140    char *config_str = GBT_join_strings(configs, CONFIG_SEPARATOR[0]);
141    AW_root::SINGLETON->awar(GBS_global_string(AWAR_CL_SELECTED_CONFIGS, canvas_id))->write_string(config_str);
142    free(config_str);
143}
144
145// --------------------------------------------------------------------------------
146
147static AW_selection *selected_configs_list[MAX_NT_WINDOWS] = { MAX_NT_WINDOWS_NULLINIT };
148static bool allow_selection2awar_update = true;
149static bool allow_to_activate_display   = false;
150
151static void init_config_awars(AW_root *root) {
152    root->awar_string(AWAR_CONFIGURATION, DEFAULT_CONFIGURATION, GLOBAL.gb_main);
153}
154static void selected_configs_awar_changed_cb(AW_root *aw_root, TREE_canvas *ntw) {
155    AWT_graphic_tree        *agt    = DOWNCAST(AWT_graphic_tree*, ntw->gfx);
156    int                      ntw_id = ntw->get_index();
157    SmartPtr<ConstStrArray>  config = get_selected_configs_from_awar(ntw_id);
158    bool                     redraw = false;
159
160    if (config->empty() || get_display_toggle_awar(ntw_id)->read_int() == 0) {
161        if (displays_config_markers(agt->get_marker_display())) { // only hide config markers
162            agt->hide_marker_display();
163            redraw = true;
164        }
165    }
166    else {
167        bool activate = allow_to_activate_display || displays_config_markers(agt->get_marker_display());
168
169        if (activate) {
170            init_config_awars(aw_root);
171            ConfigMarkerDisplay *disp = new ConfigMarkerDisplay(config, ntw->gb_main);
172            agt->set_marker_display(disp);
173            redraw = true;
174        }
175    }
176
177    if (selected_configs_list[ntw_id]) { // if configuration_marker_window has been opened
178        // update content of subset-selection (needed when reloading a config-set (not implemented yet) or after renaming a config)
179        LocallyModify<bool> avoid(allow_selection2awar_update, false);
180        awt_set_subset_selection_content(selected_configs_list[ntw_id], *config);
181    }
182
183    if (redraw) AW_root::SINGLETON->awar(AWAR_TREE_REFRESH)->touch();
184}
185
186static void selected_configs_display_awar_changed_cb(AW_root *root, TREE_canvas *ntw) {
187    LocallyModify<bool> allowInteractiveActivation(allow_to_activate_display, true);
188    selected_configs_awar_changed_cb(root, ntw);
189}
190
191static void configs_selectionlist_changed_cb(AW_selection *selected_configs, bool interactive_change, AW_CL ntw_id) {
192    if (allow_selection2awar_update) {
193        LocallyModify<bool> allowInteractiveActivation(allow_to_activate_display, interactive_change);
194
195        StrArray config;
196        selected_configs->get_values(config);
197        write_configs_to_awar(ntw_id, config);
198    }
199}
200
201static void config_modified_cb(GBDATA *gb_cfg_area) { // called with "top_area" AND "middle_area" entry!
202    static GBDATA   *gb_lastname = NULp;
203    static GB_ULONG  lastcall     = 0;
204
205    GBDATA   *gb_name  = GB_entry(GB_get_father(gb_cfg_area), "name");
206    GB_ULONG  thiscall = GB_time_of_day();
207
208    bool is_same_modification = gb_name == gb_lastname && (thiscall == lastcall || thiscall == (lastcall+1));
209    if (!is_same_modification) { // avoid duplicate check if "top_area" and "middle_area" changed (=standard case)
210        // touch all canvas-specific awars that contain 'name'
211        const char *name = GB_read_char_pntr(gb_name);
212
213        for (int canvas_id = 0; canvas_id<MAX_NT_WINDOWS; ++canvas_id) {
214            SmartPtr<ConstStrArray> config = get_selected_configs_from_awar(canvas_id);
215            for (size_t c = 0; c<config->size(); ++c) {
216                if (strcmp((*config)[c], name) == 0) {
217                    get_config_awar(canvas_id)->touch();
218                    break;
219                }
220            }
221        }
222    }
223    gb_lastname = gb_name;
224    lastcall    = thiscall;
225}
226
227#define CONFIG_BASE_PATH "/configuration_data/configuration"
228
229static void install_config_change_callbacks(GBDATA *gb_main) {
230    static bool installed = false;
231    if (!installed) {
232        DatabaseCallback dbcb = makeDatabaseCallback(config_modified_cb);
233        ASSERT_NO_ERROR(GB_add_hierarchy_callback(gb_main, CONFIG_BASE_PATH "/middle_area", GB_CB_CHANGED, dbcb));
234        ASSERT_NO_ERROR(GB_add_hierarchy_callback(gb_main, CONFIG_BASE_PATH "/top_area",    GB_CB_CHANGED, dbcb));
235
236        installed = true;
237    }
238}
239
240void NT_activate_configMarkers_display(TREE_canvas *ntw) {
241    GBDATA *gb_main = ntw->gb_main;
242
243    int      ntw_idx      = ntw->get_index();
244    AW_awar *awar_selCfgs = ntw->awr->awar_string(GBS_global_string(AWAR_CL_SELECTED_CONFIGS, ntw_idx), "", gb_main);
245    awar_selCfgs->add_callback(makeRootCallback(selected_configs_awar_changed_cb, ntw));
246
247    AW_awar *awar_dispCfgs = ntw->awr->awar_int(GBS_global_string(AWAR_CL_DISPLAY_CONFIG_MARKERS, ntw_idx), 1, gb_main);
248    awar_dispCfgs->add_callback(makeRootCallback(selected_configs_display_awar_changed_cb, ntw));
249
250    awar_selCfgs->touch(); // force initial refresh
251    install_config_change_callbacks(gb_main);
252}
253
254// define where to store config-sets (using config-manager):
255#define MANAGED_CONFIGSET_SECTION "configmarkers"
256#define MANAGED_CONFIGSET_ENTRY   "selected_configs"
257
258static void setup_configmarker_config_cb(AWT_config_definition& config, int ntw_id) {
259    AW_awar *selcfg_awar = get_config_awar(ntw_id);
260    nt_assert(selcfg_awar);
261    if (selcfg_awar) {
262        config.add(selcfg_awar->awar_name, MANAGED_CONFIGSET_ENTRY);
263    }
264}
265
266struct ConfigModifier : virtual Noncopyable {
267    virtual ~ConfigModifier() {}
268    virtual const char *modify(const char *old) const = 0;
269
270    bool modifyConfig(ConstStrArray& config) const {
271        bool changed = false;
272        for (size_t i = 0; i<config.size(); ++i) {
273            const char *newContent = modify(config[i]);
274            if (!newContent) {
275                config.remove(i);
276                changed = true;
277            }
278            else if (strcmp(newContent, config[i]) != 0) {
279                config.replace(i, newContent);
280                changed = true;
281            }
282        }
283        return changed;
284    }
285};
286class ConfigRenamer : public ConfigModifier { // derived from Noncopyable
287    const char *oldName;
288    const char *newName;
289    const char *modify(const char *name) const OVERRIDE {
290        return strcmp(name, oldName) == 0 ? newName : name;
291    }
292public:
293    ConfigRenamer(const char *oldName_, const char *newName_)
294        : oldName(oldName_),
295          newName(newName_)
296    {}
297};
298class ConfigDeleter : public ConfigModifier { // derived from Noncopyable
299    const char *toDelete;
300    const char *modify(const char *name) const OVERRIDE {
301        return strcmp(name, toDelete) == 0 ? NULp : name;
302    }
303public:
304    ConfigDeleter(const char *toDelete_)
305        : toDelete(toDelete_)
306    {}
307};
308
309static char *correct_managed_configsets_cb(const char *key, const char *value, AW_CL cl_ConfigModifier) {
310    char *modified_value = NULp;
311    if (strcmp(key, MANAGED_CONFIGSET_ENTRY) == 0) {
312        const ConfigModifier *mod = (const ConfigModifier*)cl_ConfigModifier;
313        ConstStrArray         config;
314        GBT_split_string(config, value, CONFIG_SEPARATOR, SPLIT_DROPEMPTY);
315        if (mod->modifyConfig(config)) {
316            modified_value = GBT_join_strings(config, CONFIG_SEPARATOR[0]);
317        }
318    }
319    return modified_value ? modified_value : ARB_strdup(value);
320}
321static void modify_configurations(const ConfigModifier& mod) {
322    for (int canvas_id = 0; canvas_id<MAX_NT_WINDOWS; ++canvas_id) {
323        // modify currently selected configs:
324        SmartPtr<ConstStrArray> config = get_selected_configs_from_awar(canvas_id);
325        if (mod.modifyConfig(*config)) {
326            write_configs_to_awar(canvas_id, *config);
327        }
328    }
329    // change all configuration-sets stored in config-manager (shared by all windows)
330    AWT_modify_managed_configs(GLOBAL.gb_main, MANAGED_CONFIGSET_SECTION, correct_managed_configsets_cb, AW_CL(&mod));
331}
332
333static AW_window *create_configuration_marker_window(AW_root *root, TREE_canvas *ntw) {
334    AW_window_simple *aws = new AW_window_simple;
335
336    int ntw_id = ntw->get_index();
337    aws->init(root, GBS_global_string("MARK_CONFIGS_%i", ntw_id), "Highlight configurations in tree");
338    aws->load_xfig("mark_configs.fig");
339
340    aws->auto_space(10, 10);
341
342    aws->at("close");
343    aws->callback(AW_POPDOWN);
344    aws->create_button("CLOSE", "CLOSE", "C");
345
346    aws->at("help");
347    aws->callback(makeHelpCallback("species_configs_highlight.hlp"));
348    aws->create_button("HELP", "HELP", "H");
349
350
351    aws->at("list");
352    AW_DB_selection *all_configs = awt_create_CONFIG_selection_list(GLOBAL.gb_main, aws, AWAR_CONFIGURATION);
353    AW_selection *sub_sel;
354    {
355        LocallyModify<bool> avoid(allow_selection2awar_update, false); // avoid awar gets updated from empty sub-selectionlist
356        sub_sel = awt_create_subset_selection_list(aws, all_configs->get_sellist(), "selected", "add", "sort", false, configs_selectionlist_changed_cb, ntw->get_index());
357    }
358
359    awt_set_subset_selection_content(sub_sel, *get_selected_configs_from_awar(ntw_id));
360    selected_configs_list[ntw_id] = sub_sel;
361
362    // @@@ would like to use ntw-specific awar for this selection list (opening two lists links them)
363
364    aws->at("show");
365    aws->label("Display?");
366    aws->create_toggle(get_display_toggle_awar(ntw_id)->awar_name);
367
368    aws->at("settings");
369    aws->callback(TREE_create_marker_settings_window);
370    aws->create_autosize_button("SETTINGS", "Settings", "S");
371
372    AWT_insert_config_manager(aws, GLOBAL.gb_main, MANAGED_CONFIGSET_SECTION, makeConfigSetupCallback(setup_configmarker_config_cb, ntw_id));
373
374    return aws;
375}
376
377static void selected_config_changed_cb(AW_root *root) {
378    const char *config = root->awar(AWAR_CONFIGURATION)->read_char_pntr();
379
380    bool    nonexisting_config = false;
381    GBDATA *gb_target_commment = NULp;
382    if (config[0]) {
383        GBDATA *gb_configuration = GBT_find_configuration(GLOBAL.gb_main, config);
384        if (gb_configuration) {
385            gb_target_commment = GB_entry(gb_configuration, "comment");
386        }
387        else {
388            nonexisting_config = true;
389        }
390    }
391
392    AW_awar *awar_comment = root->awar(AWAR_CONFIG_COMMENT);
393    if (gb_target_commment) {
394        if (!awar_comment->is_mapped()) awar_comment->write_string("");
395        awar_comment->map(gb_target_commment);
396    }
397    else {
398        char *reuse_comment = nonexisting_config ? awar_comment->read_string() : ARB_strdup("");
399        if (awar_comment->is_mapped()) {
400            awar_comment->unmap();
401        }
402        awar_comment->write_string(reuse_comment);
403        free(reuse_comment);
404    }
405}
406static void config_comment_changed_cb(AW_root *root) {
407    // called when comment-awar changes or gets re-map-ped
408
409    AW_awar    *awar_comment = root->awar(AWAR_CONFIG_COMMENT);
410    const char *comment      = awar_comment->read_char_pntr();
411
412    const char *config           = root->awar(AWAR_CONFIGURATION)->read_char_pntr();
413    GBDATA     *gb_configuration = config[0] ? GBT_find_configuration(GLOBAL.gb_main, config) : NULp;
414
415    GB_ERROR error = NULp;
416    if (awar_comment->is_mapped()) {
417        if (!comment[0]) { // empty existing comment
418            nt_assert(gb_configuration);
419            GBDATA *gb_commment = GB_entry(gb_configuration, "comment");
420            nt_assert(gb_commment);
421            if (gb_commment) {
422                awar_comment->unmap();
423                error = GB_delete(gb_commment);
424            }
425        }
426    }
427    else {
428        if (comment[0]) { // ignore empty comment for unmapped awar
429            if (gb_configuration) {
430                nt_assert(!GB_entry(gb_configuration, "comment"));
431                error = GBT_write_string(gb_configuration, "comment", comment);
432                if (!error) {
433                    awar_comment->write_string("");
434                    selected_config_changed_cb(root);
435                }
436            }
437            else if (!config[0]) {
438                // do NOT warn if name field contains (not yet) existing name
439                // (allows to edit comment while creating new config)
440                error = "Please select an existing species selection to edit its comment";
441            }
442        }
443    }
444
445    aw_message_if(error);
446}
447
448static void init_config_admin_awars(AW_root *root) {
449    init_config_awars(root);
450    root->awar_string(AWAR_CONFIG_COMMENT, "", GLOBAL.gb_main)->add_callback(config_comment_changed_cb);
451    root->awar(AWAR_CONFIGURATION)->add_callback(selected_config_changed_cb)->touch();
452}
453
454class NtSelectionAdmin: public SelectionAdmin {
455    RefPtr<TREE_canvas> ntw;
456
457public:
458    NtSelectionAdmin(TREE_canvas *ntw_) : ntw(ntw_) {}
459
460    const char *get_macro_suffix() const { return GBS_global_string("%i", ntw->get_index()); }
461    GBDATA *get_gb_main() const { return ntw->get_graphic_tree()->get_gbmain(); }
462
463    const char *get_selection_awarname() const { return AWAR_CONFIGURATION; }
464    const char *get_selectionComment_awarname() const { return AWAR_CONFIG_COMMENT; }
465
466    const char *get_name_of_tree() const { return ntw->get_awar_tree()->read_char_pntr(); }
467    TreeNode *get_tree_root() const { return ntw->get_tree_root_node(); }
468
469    const char *get_toparea_SAIs() const {
470        return AW_root::SINGLETON->awar(AWAR_TOPAREA_SAIS)->read_char_pntr();
471    }
472
473    void speciesSelection_renamed_cb(const char *old_name, const char *new_name) const { modify_configurations(ConfigRenamer(old_name, new_name)); }
474    void speciesSelection_deleted_cb(const char *name)                           const { modify_configurations(ConfigDeleter(name));               }
475};
476
477
478void NT_popup_configuration_admin(AW_window *aw_main, TREE_canvas *ntw) {
479    // Note: these windows have to be tree-canvas-related,
480    // because species selections need to reflect the topology of the tree shown in canvas.
481    //
482    // We have to use a custom popup method, because there exist multiple callbacks for the same canvas.
483
484    static AW_window *existing_aws[MAX_NT_WINDOWS] = { MAX_NT_WINDOWS_NULLINIT };
485
486    int ntw_id = ntw->get_index();
487    if (!existing_aws[ntw_id]) {
488        AW_root *root           = aw_main->get_root();
489        init_config_admin_awars(root);
490
491        NtSelectionAdmin * const  admin = new NtSelectionAdmin(ntw); // bound to callbacks (inside create_species_selection_window)
492        AW_window                *aws   = create_species_selection_window(root, admin);
493
494        aws->at("highlight");
495        aws->callback(makeCreateWindowCallback(create_configuration_marker_window, ntw));
496        aws->create_autosize_button(GBS_global_string("HIGHLIGHT_%i", ntw_id), "Highlight in tree", "t");
497
498        existing_aws[ntw_id] = aws;
499    }
500    existing_aws[ntw_id]->activate();
501}
502
503// -----------------------------------------
504//      various ways to start the editor
505
506static void nt_start_editor_on_configuration(AW_window *aww) {
507    aww->hide();
508
509    const char *cfgName   = aww->get_root()->awar(AWAR_CONFIGURATION)->read_char_pntr();
510    char       *quotedCfg = GBK_singlequote(cfgName);
511
512    AW_system(GBS_global_string("arb_edit4 -c %s &", quotedCfg));
513
514    free(quotedCfg);
515}
516
517AW_window *NT_create_startEditorOnOldConfiguration_window(AW_root *awr) {
518    static AW_window_simple *aws = NULp;
519    if (!aws) {
520        init_config_awars(awr);
521
522        aws = new AW_window_simple;
523        aws->init(awr, "SELECT_CONFIGURATION", "SELECT A CONFIGURATION");
524        aws->at(10, 10);
525        aws->auto_space(0, 0);
526        awt_create_CONFIG_selection_list(GLOBAL.gb_main, aws, AWAR_CONFIGURATION);
527        aws->at_newline();
528
529        aws->callback(nt_start_editor_on_configuration);
530        aws->create_button("START", "START");
531
532        aws->callback(AW_POPDOWN);
533        aws->create_button("CLOSE", "CLOSE", "C");
534
535        aws->window_fit();
536    }
537    return aws;
538}
539
540void NT_start_editor_on_tree(AW_window *aww, int use_species_aside, TREE_canvas *ntw) {
541    init_config_awars(aww->get_root());
542    NtSelectionAdmin def(ntw);
543    GB_ERROR error    = create_species_selection(def, DEFAULT_CONFIGURATION, use_species_aside, BY_CALLING_THE_EDITOR);
544    if (!error) error = GBK_system("arb_edit4 -c " DEFAULT_CONFIGURATION " &");
545    aw_message_if(error);
546}
547
548inline void nt_create_config_after_import(TREE_canvas *ntw) {
549    init_config_awars(ntw->awr);
550
551    const char *dated_suffix = ARB_dateTime_suffix();
552    char       *configName   = GBS_global_string_copy("imported_%s", dated_suffix);
553
554    // ensure unique config-name
555    {
556        int unique = 1;
557        GB_transaction ta(ntw->gb_main);
558        while (GBT_find_configuration(ntw->gb_main, configName)) {
559            freeset(configName, GBS_global_string_copy("imported_%s_%i", dated_suffix, ++unique));
560        }
561    }
562
563    NtSelectionAdmin def(ntw);
564    GB_ERROR error = create_species_selection(def, configName, 0, FROM_IMPORTER);
565    aw_message_if(error);
566
567    free(configName);
568}
569
570void NT_create_config_after_import(TREE_canvas *ntw, bool imported_from_scratch) {
571    /*! create a new config after import
572     * @param imported_from_scratch if true -> DB was created from scratch, all species in DB are marked.
573     *                              if false -> data was imported into existing DB. Other species may be marked as well, imported species are "queried".
574     */
575
576    if (imported_from_scratch) {
577        nt_create_config_after_import(ntw);
578    }
579    else {
580        GB_transaction ta(ntw->gb_main);
581
582        // remember marks + mark queried species:
583        for (GBDATA *gb_species = GBT_first_species(ntw->gb_main); gb_species; gb_species = GBT_next_species(gb_species)) {
584            GB_write_user_flag(gb_species, GB_USERFLAG_WASMARKED, GB_read_flag(gb_species));
585            GB_write_flag(gb_species, GB_user_flag(gb_species, GB_USERFLAG_QUERY));
586        }
587
588        nt_create_config_after_import(ntw);
589
590        // restore old marks:
591        for (GBDATA *gb_species = GBT_first_species(ntw->gb_main); gb_species; gb_species = GBT_next_species(gb_species)) {
592            GB_write_flag(gb_species, GB_user_flag(gb_species, GB_USERFLAG_WASMARKED));
593            GB_clear_user_flag(gb_species, GB_USERFLAG_WASMARKED);
594        }
595    }
596}
597
Note: See TracBrowser for help on using the repository browser.