| 1 | // =============================================================== // | 
|---|
| 2 | //                                                                 // | 
|---|
| 3 | //   File      : ui_species.cxx                                    // | 
|---|
| 4 | //   Purpose   :                                                   // | 
|---|
| 5 | //                                                                 // | 
|---|
| 6 | //   Institute of Microbiology (Technical University Munich)       // | 
|---|
| 7 | //   http://www.arb-home.de/                                       // | 
|---|
| 8 | //                                                                 // | 
|---|
| 9 | // =============================================================== // | 
|---|
| 10 |  | 
|---|
| 11 | #include "dbui.h" | 
|---|
| 12 |  | 
|---|
| 13 | #include <awt_sel_boxes.hxx> | 
|---|
| 14 | #include <arb_strbuf.h> | 
|---|
| 15 | #include <cmath> | 
|---|
| 16 | #include <probe_design.hxx> | 
|---|
| 17 | #include <arb_defs.h> | 
|---|
| 18 | #include <awtc_next_neighbours.hxx> | 
|---|
| 19 | #include <db_scanner.hxx> | 
|---|
| 20 | #include <db_query.h> | 
|---|
| 21 | #include <AW_rename.hxx> | 
|---|
| 22 | #include <aw_awar_defs.hxx> | 
|---|
| 23 | #include <aw_awar.hxx> | 
|---|
| 24 | #include <aw_root.hxx> | 
|---|
| 25 | #include <aw_msg.hxx> | 
|---|
| 26 | #include <aw_question.hxx> | 
|---|
| 27 | #include <algorithm> | 
|---|
| 28 | #include <arb_progress.h> | 
|---|
| 29 | #include <item_sel_list.h> | 
|---|
| 30 | #include <map> | 
|---|
| 31 | #include <info_window.h> | 
|---|
| 32 |  | 
|---|
| 33 | using namespace DBUI; | 
|---|
| 34 | using namespace QUERY; | 
|---|
| 35 |  | 
|---|
| 36 | #define ui_assert(cond) arb_assert(cond) | 
|---|
| 37 |  | 
|---|
| 38 | #define AWAR_SPECIES_DEST "tmp/adspec/dest" | 
|---|
| 39 | #define AWAR_SPECIES_INFO "tmp/adspec/info" | 
|---|
| 40 | #define AWAR_SPECIES_KEY  "tmp/adspec/key" | 
|---|
| 41 |  | 
|---|
| 42 | #define AWAR_FIELD_REORDER_SOURCE "tmp/ad_reorder/source" | 
|---|
| 43 | #define AWAR_FIELD_REORDER_DEST   "tmp/ad_reorder/dest" | 
|---|
| 44 | #define AWAR_FIELD_REORDER_ORDER  "tmp/ad_reorder/order" | 
|---|
| 45 |  | 
|---|
| 46 | #define AWAR_FIELD_CREATE_NAME "tmp/adfield/name" | 
|---|
| 47 | #define AWAR_FIELD_CREATE_TYPE "tmp/adfield/type" | 
|---|
| 48 | #define AWAR_FIELD_DELETE      "tmp/adfield/source" | 
|---|
| 49 |  | 
|---|
| 50 | #define AWAR_FIELD_CONVERT_SOURCE "tmp/adconvert/source" | 
|---|
| 51 | #define AWAR_FIELD_CONVERT_NAME   "tmp/adconvert/name" | 
|---|
| 52 | #define AWAR_FIELD_CONVERT_TYPE   "tmp/adconvert/type" | 
|---|
| 53 |  | 
|---|
| 54 | // next neighbours of listed and selected: | 
|---|
| 55 | // more defined in ../../AWTC/awtc_next_neighbours.hxx@AWAR_NN_BASE | 
|---|
| 56 | #define AWAR_NN_COMPLEMENT  AWAR_NN_BASE "complement" | 
|---|
| 57 | #define AWAR_NN_RANGE_START AWAR_NN_BASE "range_start" | 
|---|
| 58 | #define AWAR_NN_RANGE_END   AWAR_NN_BASE "range_end" | 
|---|
| 59 | #define AWAR_NN_MIN_SCORE   AWAR_NN_BASE "min_scored" | 
|---|
| 60 | #define AWAR_NN_MAX_HITS    AWAR_NN_BASE "max_hits" | 
|---|
| 61 |  | 
|---|
| 62 | // next neighbours of selected only: | 
|---|
| 63 | #define AWAR_NN_BASE_SELECTED        AWAR_NN_BASE "selected/" | 
|---|
| 64 | #define AWAR_NN_SELECTED_HIT_COUNT   "tmp/" AWAR_NN_BASE_SELECTED "hit_count" | 
|---|
| 65 | #define AWAR_NN_SELECTED_AUTO_SEARCH "tmp/" AWAR_NN_BASE_SELECTED "auto_search" | 
|---|
| 66 | #define AWAR_NN_SELECTED_AUTO_MARK   "tmp/" AWAR_NN_BASE_SELECTED "auto_mark" | 
|---|
| 67 |  | 
|---|
| 68 | // next neighbours of listed only: | 
|---|
| 69 | #define AWAR_NN_BASE_LISTED           AWAR_NN_BASE "listed/" | 
|---|
| 70 | #define AWAR_NN_LISTED_DEST_FIELD     AWAR_NN_BASE_LISTED "dest_field" | 
|---|
| 71 | #define AWAR_NN_LISTED_SCORED_ENTRIES AWAR_NN_BASE_LISTED "scored_entries" | 
|---|
| 72 |  | 
|---|
| 73 | enum ReorderMode { | 
|---|
| 74 | // real orders | 
|---|
| 75 | ORDER_ALPHA, | 
|---|
| 76 | ORDER_TYPE, | 
|---|
| 77 | ORDER_FREQ, | 
|---|
| 78 |  | 
|---|
| 79 | // special modes | 
|---|
| 80 | RIGHT_BEHIND_LEFT, | 
|---|
| 81 | REVERSE_ORDER, | 
|---|
| 82 | }; | 
|---|
| 83 |  | 
|---|
| 84 | void DBUI::create_dbui_awars(AW_root *aw_root, AW_default aw_def) { | 
|---|
| 85 | aw_root->awar_string(AWAR_SPECIES_DEST,         "",          aw_def); | 
|---|
| 86 | aw_root->awar_string(AWAR_SPECIES_INFO,         "",          aw_def); | 
|---|
| 87 | aw_root->awar_string(AWAR_SPECIES_KEY,          "",          aw_def); | 
|---|
| 88 | aw_root->awar_string(AWAR_FIELD_REORDER_SOURCE, "",          aw_def); | 
|---|
| 89 | aw_root->awar_string(AWAR_FIELD_REORDER_DEST,   "",          aw_def); | 
|---|
| 90 | aw_root->awar_int   (AWAR_FIELD_REORDER_ORDER,  ORDER_ALPHA, aw_def); | 
|---|
| 91 | aw_root->awar_string(AWAR_FIELD_CREATE_NAME,    "",          aw_def); | 
|---|
| 92 | aw_root->awar_int   (AWAR_FIELD_CREATE_TYPE,    GB_STRING,   aw_def); | 
|---|
| 93 | aw_root->awar_string(AWAR_FIELD_DELETE,         "",          aw_def); | 
|---|
| 94 | aw_root->awar_string(AWAR_FIELD_CONVERT_SOURCE, "",          aw_def); | 
|---|
| 95 | aw_root->awar_int   (AWAR_FIELD_CONVERT_TYPE,   GB_STRING,   aw_def); | 
|---|
| 96 | aw_root->awar_string(AWAR_FIELD_CONVERT_NAME,   "",          aw_def); | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | static void move_species_to_extended(AW_window *aww, AW_CL cl_gb_main, AW_CL) { | 
|---|
| 100 | GBDATA   *gb_main = (GBDATA*)cl_gb_main; | 
|---|
| 101 | char     *source  = aww->get_root()->awar(AWAR_SPECIES_NAME)->read_string(); | 
|---|
| 102 | GB_ERROR  error   = GB_begin_transaction(gb_main); | 
|---|
| 103 |  | 
|---|
| 104 | if (!error) { | 
|---|
| 105 | GBDATA *gb_sai_data     = GBT_get_SAI_data(gb_main); | 
|---|
| 106 | if (!gb_sai_data) error = GB_await_error(); | 
|---|
| 107 | else { | 
|---|
| 108 | GBDATA *gb_species = GBT_find_species(gb_main, source); | 
|---|
| 109 | GBDATA *gb_dest    = GBT_find_SAI_rel_SAI_data(gb_sai_data, source); | 
|---|
| 110 |  | 
|---|
| 111 | if (gb_dest) error = GBS_global_string("SAI '%s' already exists", source); | 
|---|
| 112 | else if (gb_species) { | 
|---|
| 113 | gb_dest             = GB_create_container(gb_sai_data, "extended"); | 
|---|
| 114 | if (!gb_dest) error = GB_await_error(); | 
|---|
| 115 | else { | 
|---|
| 116 | error = GB_copy(gb_dest, gb_species); | 
|---|
| 117 | if (!error) { | 
|---|
| 118 | error = GB_delete(gb_species); | 
|---|
| 119 | if (!error) aww->get_root()->awar(AWAR_SPECIES_NAME)->write_string(""); | 
|---|
| 120 | } | 
|---|
| 121 | } | 
|---|
| 122 | } | 
|---|
| 123 | else error = "Please select a species"; | 
|---|
| 124 | } | 
|---|
| 125 | } | 
|---|
| 126 | GB_end_transaction_show_error(gb_main, error, aw_message); | 
|---|
| 127 | free(source); | 
|---|
| 128 | } | 
|---|
| 129 |  | 
|---|
| 130 |  | 
|---|
| 131 | static void species_create_cb(AW_window * aww, AW_CL cl_gb_main) { | 
|---|
| 132 | GBDATA   *gb_main = (GBDATA*)cl_gb_main; | 
|---|
| 133 | char     *dest    = aww->get_root()->awar(AWAR_SPECIES_DEST)->read_string(); | 
|---|
| 134 | GB_ERROR  error   = GB_begin_transaction(gb_main); | 
|---|
| 135 |  | 
|---|
| 136 | if (!error) { | 
|---|
| 137 | GBDATA *gb_species_data     = GBT_get_species_data(gb_main); | 
|---|
| 138 | if (!gb_species_data) error = GB_await_error(); | 
|---|
| 139 | else { | 
|---|
| 140 | GBDATA *gb_dest = GBT_find_species_rel_species_data(gb_species_data, dest); | 
|---|
| 141 |  | 
|---|
| 142 | if (gb_dest) error = GBS_global_string("Species '%s' already exists", dest); | 
|---|
| 143 | else { | 
|---|
| 144 | gb_dest             = GBT_find_or_create_species_rel_species_data(gb_species_data, dest); | 
|---|
| 145 | if (!gb_dest) error = GB_await_error(); | 
|---|
| 146 | else aww->get_root()->awar(AWAR_SPECIES_NAME)->write_string(dest); | 
|---|
| 147 | } | 
|---|
| 148 | } | 
|---|
| 149 | } | 
|---|
| 150 | GB_end_transaction_show_error(gb_main, error, aw_message); | 
|---|
| 151 | free(dest); | 
|---|
| 152 | } | 
|---|
| 153 |  | 
|---|
| 154 | static AW_window *create_species_create_window(AW_root *root, AW_CL cl_gb_main) { | 
|---|
| 155 | AW_window_simple *aws = new AW_window_simple; | 
|---|
| 156 |  | 
|---|
| 157 | aws->init(root, "CREATE_SPECIES", "SPECIES CREATE"); | 
|---|
| 158 | aws->load_xfig("ad_al_si.fig"); | 
|---|
| 159 |  | 
|---|
| 160 | aws->callback((AW_CB0)AW_POPDOWN); | 
|---|
| 161 | aws->at("close"); | 
|---|
| 162 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 163 |  | 
|---|
| 164 | aws->at("label"); | 
|---|
| 165 | aws->create_autosize_button(0, "Please enter the name\nof the new species"); | 
|---|
| 166 |  | 
|---|
| 167 | aws->at("input"); | 
|---|
| 168 | aws->create_input_field(AWAR_SPECIES_DEST, 15); | 
|---|
| 169 |  | 
|---|
| 170 | aws->at("ok"); | 
|---|
| 171 | aws->callback(species_create_cb, cl_gb_main); | 
|---|
| 172 | aws->create_button("GO", "Go", "G"); | 
|---|
| 173 |  | 
|---|
| 174 | return (AW_window *)aws; | 
|---|
| 175 | } | 
|---|
| 176 |  | 
|---|
| 177 | static GBDATA *expect_species_selected(AW_root *aw_root, GBDATA *gb_main, char **give_name = 0) { | 
|---|
| 178 | GB_transaction  ta(gb_main); | 
|---|
| 179 | char           *name       = aw_root->awar(AWAR_SPECIES_NAME)->read_string(); | 
|---|
| 180 | GBDATA         *gb_species = GBT_find_species(gb_main, name); | 
|---|
| 181 |  | 
|---|
| 182 | if (!gb_species) { | 
|---|
| 183 | if (name && name[0]) aw_message(GBS_global_string("Species '%s' does not exist.", name)); | 
|---|
| 184 | else aw_message("Please select a species first"); | 
|---|
| 185 | } | 
|---|
| 186 |  | 
|---|
| 187 | if (give_name) *give_name = name; | 
|---|
| 188 | else free(name); | 
|---|
| 189 |  | 
|---|
| 190 | return gb_species; | 
|---|
| 191 | } | 
|---|
| 192 |  | 
|---|
| 193 | static void species_copy_cb(AW_window *aww, AW_CL cl_gb_main, AW_CL) { | 
|---|
| 194 | AW_root *aw_root    = aww->get_root(); | 
|---|
| 195 | GBDATA  *gb_main    = (GBDATA*)cl_gb_main; | 
|---|
| 196 | char    *name; | 
|---|
| 197 | GBDATA  *gb_species = expect_species_selected(aw_root, gb_main, &name); | 
|---|
| 198 |  | 
|---|
| 199 | if (gb_species) { | 
|---|
| 200 | GB_transaction      ta(gb_main); | 
|---|
| 201 | GBDATA             *gb_species_data = GB_get_father(gb_species); | 
|---|
| 202 | UniqueNameDetector  und(gb_species_data); | 
|---|
| 203 | GB_ERROR            error           = 0; | 
|---|
| 204 | char               *copy_name       = AWTC_makeUniqueShortName(GBS_global_string("c%s", name), und); | 
|---|
| 205 |  | 
|---|
| 206 | if (!copy_name) error = GB_await_error(); | 
|---|
| 207 | else { | 
|---|
| 208 | GBDATA *gb_new_species = GB_create_container(gb_species_data, "species"); | 
|---|
| 209 |  | 
|---|
| 210 | if (!gb_new_species) error = GB_await_error(); | 
|---|
| 211 | else { | 
|---|
| 212 | error = GB_copy(gb_new_species, gb_species); | 
|---|
| 213 | if (!error) { | 
|---|
| 214 | error = GBT_write_string(gb_new_species, "name", copy_name); | 
|---|
| 215 | if (!error) aw_root->awar(AWAR_SPECIES_NAME)->write_string(copy_name); // set focus | 
|---|
| 216 | } | 
|---|
| 217 | } | 
|---|
| 218 |  | 
|---|
| 219 | free(copy_name); | 
|---|
| 220 | } | 
|---|
| 221 | if (error) { | 
|---|
| 222 | error = ta.close(error); | 
|---|
| 223 | aw_message(error); | 
|---|
| 224 | } | 
|---|
| 225 | } | 
|---|
| 226 | } | 
|---|
| 227 |  | 
|---|
| 228 | static void species_rename_cb(AW_window *aww, AW_CL cl_gb_main, AW_CL) { | 
|---|
| 229 | AW_root *aw_root    = aww->get_root(); | 
|---|
| 230 | GBDATA  *gb_main    = (GBDATA*)cl_gb_main; | 
|---|
| 231 | GBDATA  *gb_species = expect_species_selected(aw_root, gb_main); | 
|---|
| 232 | if (gb_species) { | 
|---|
| 233 | GB_transaction  ta(gb_main); | 
|---|
| 234 | GBDATA         *gb_full_name  = GB_search(gb_species, "full_name", GB_STRING); | 
|---|
| 235 | const char     *full_name     = gb_full_name ? GB_read_char_pntr(gb_full_name) : ""; | 
|---|
| 236 | char           *new_full_name = aw_input("Enter new 'full_name' of species:", full_name); | 
|---|
| 237 |  | 
|---|
| 238 | if (new_full_name) { | 
|---|
| 239 | GB_ERROR error = 0; | 
|---|
| 240 |  | 
|---|
| 241 | if (strcmp(full_name, new_full_name) != 0) { | 
|---|
| 242 | error = GB_write_string(gb_full_name, new_full_name); | 
|---|
| 243 | } | 
|---|
| 244 | if (!error) { | 
|---|
| 245 | bool recreateID = ARB_in_expert_mode(aw_root) && // never re-create ID in novice mode | 
|---|
| 246 | aw_ask_sure("recreate_name_field", | 
|---|
| 247 | "Regenerate species identifier ('name')?\n" | 
|---|
| 248 | "(only do this if you know what you're doing)"); | 
|---|
| 249 | if (recreateID) { | 
|---|
| 250 | arb_progress progress("Regenerating species ID", 1); | 
|---|
| 251 | error = AWTC_recreate_name(gb_species); | 
|---|
| 252 | if (!error) aw_root->awar(AWAR_SPECIES_NAME)->write_string(GBT_read_name(gb_species)); // set focus | 
|---|
| 253 | } | 
|---|
| 254 | } | 
|---|
| 255 |  | 
|---|
| 256 | if (error) { | 
|---|
| 257 | error = ta.close(error); | 
|---|
| 258 | aw_message(error); | 
|---|
| 259 | } | 
|---|
| 260 | } | 
|---|
| 261 | } | 
|---|
| 262 | } | 
|---|
| 263 |  | 
|---|
| 264 | static void species_delete_cb(AW_window *aww, AW_CL cl_gb_main, AW_CL) { | 
|---|
| 265 | AW_root  *aw_root    = aww->get_root(); | 
|---|
| 266 | GBDATA   *gb_main    = (GBDATA*)cl_gb_main; | 
|---|
| 267 | char     *name; | 
|---|
| 268 | GBDATA   *gb_species = expect_species_selected(aw_root, gb_main, &name); | 
|---|
| 269 | GB_ERROR  error      = 0; | 
|---|
| 270 |  | 
|---|
| 271 | if (!gb_species) { | 
|---|
| 272 | error = "Please select a species first"; | 
|---|
| 273 | } | 
|---|
| 274 | else if (aw_ask_sure("info_delete_species", GBS_global_string("Are you sure to delete the species '%s'?", name))) { | 
|---|
| 275 | GB_transaction ta(gb_main); | 
|---|
| 276 | error = GB_delete(gb_species); | 
|---|
| 277 | error = ta.close(error); | 
|---|
| 278 | if (!error) aw_root->awar(AWAR_SPECIES_NAME)->write_string(""); | 
|---|
| 279 | } | 
|---|
| 280 |  | 
|---|
| 281 | if (error) aw_message(error); | 
|---|
| 282 | free(name); | 
|---|
| 283 | } | 
|---|
| 284 |  | 
|---|
| 285 | static long count_field_occurrance(BoundItemSel *bsel, const char *field_name) { | 
|---|
| 286 | QUERY_RANGE   RANGE = QUERY_ALL_ITEMS; | 
|---|
| 287 | long          count = 0; | 
|---|
| 288 | ItemSelector& sel   = bsel->selector; | 
|---|
| 289 |  | 
|---|
| 290 | for (GBDATA *gb_container = sel.get_first_item_container(bsel->gb_main, NULL, RANGE); | 
|---|
| 291 | gb_container; | 
|---|
| 292 | gb_container = sel.get_next_item_container(gb_container, RANGE)) | 
|---|
| 293 | { | 
|---|
| 294 | for (GBDATA *gb_item = sel.get_first_item(gb_container, RANGE); | 
|---|
| 295 | gb_item; | 
|---|
| 296 | gb_item = sel.get_next_item(gb_item, RANGE)) | 
|---|
| 297 | { | 
|---|
| 298 | GBDATA *gb_field = GB_entry(gb_item, field_name); | 
|---|
| 299 | if (gb_field) ++count; | 
|---|
| 300 | } | 
|---|
| 301 | } | 
|---|
| 302 | return count; | 
|---|
| 303 | } | 
|---|
| 304 |  | 
|---|
| 305 | class KeySorter : virtual Noncopyable { | 
|---|
| 306 | int      key_count; | 
|---|
| 307 | GBDATA **key; | 
|---|
| 308 |  | 
|---|
| 309 | int field_count; // = key_count - container_count | 
|---|
| 310 |  | 
|---|
| 311 | bool order_changed; | 
|---|
| 312 |  | 
|---|
| 313 | // helper variables for sorting | 
|---|
| 314 | static GB_HASH      *order_hash; | 
|---|
| 315 | static BoundItemSel *bitem_selector; | 
|---|
| 316 | static arb_progress *sort_progress; | 
|---|
| 317 |  | 
|---|
| 318 | bool legal_pos(int p) { return p >= 0 && p<key_count; } | 
|---|
| 319 | bool legal_field_pos(int p) const { return p >= 0 && p<field_count; } | 
|---|
| 320 | bool legal_field_pos(int p1, int p2) const { return legal_field_pos(p1) && legal_field_pos(p2); } | 
|---|
| 321 |  | 
|---|
| 322 | void swap(int p1, int p2) { | 
|---|
| 323 | ui_assert(legal_pos(p1)); | 
|---|
| 324 | ui_assert(legal_pos(p2)); | 
|---|
| 325 |  | 
|---|
| 326 | GBDATA *k = key[p1]; | 
|---|
| 327 | key[p1]   = key[p2]; | 
|---|
| 328 | key[p2]   = k; | 
|---|
| 329 |  | 
|---|
| 330 | order_changed = true; | 
|---|
| 331 | } | 
|---|
| 332 |  | 
|---|
| 333 | const char *field_name(int p) const { | 
|---|
| 334 | GBDATA *gb_key_name = GB_entry(key[p], "key_name"); | 
|---|
| 335 | if (gb_key_name) return GB_read_char_pntr(gb_key_name); | 
|---|
| 336 | return NULL; | 
|---|
| 337 | } | 
|---|
| 338 | GB_TYPES field_type(int p) const { | 
|---|
| 339 | GBDATA *gb_key_type = GB_entry(key[p], "key_type"); | 
|---|
| 340 | if (gb_key_type) return GB_TYPES(GB_read_int(gb_key_type)); | 
|---|
| 341 | return GB_NONE; | 
|---|
| 342 | } | 
|---|
| 343 | int field_freq(int p) const { | 
|---|
| 344 | const char *name            = field_name(p); | 
|---|
| 345 | if (!order_hash) order_hash = GBS_create_hash(key_count, GB_IGNORE_CASE); | 
|---|
| 346 |  | 
|---|
| 347 | long freq = GBS_read_hash(order_hash, name); | 
|---|
| 348 | if (!freq) { | 
|---|
| 349 | freq = 1+count_field_occurrance(bitem_selector, name); | 
|---|
| 350 | GBS_write_hash(order_hash, name, freq); | 
|---|
| 351 | if (sort_progress) sort_progress->inc(); | 
|---|
| 352 | } | 
|---|
| 353 | return freq; | 
|---|
| 354 | } | 
|---|
| 355 |  | 
|---|
| 356 | int compare(int p1, int p2, ReorderMode mode) { | 
|---|
| 357 | switch (mode) { | 
|---|
| 358 | case RIGHT_BEHIND_LEFT: | 
|---|
| 359 | case REVERSE_ORDER: | 
|---|
| 360 | ui_assert(0); // illegal ReorderMode | 
|---|
| 361 | break; | 
|---|
| 362 |  | 
|---|
| 363 | case ORDER_TYPE:  return field_type(p2)-field_type(p1); | 
|---|
| 364 | case ORDER_ALPHA: return strcasecmp(field_name(p1), field_name(p2)); | 
|---|
| 365 | case ORDER_FREQ:  return field_freq(p2)-field_freq(p1); | 
|---|
| 366 | } | 
|---|
| 367 | return p2-p1; // keep order | 
|---|
| 368 | } | 
|---|
| 369 |  | 
|---|
| 370 | public: | 
|---|
| 371 | KeySorter(GBDATA *gb_key_data) { | 
|---|
| 372 | key_count   = 0; | 
|---|
| 373 | field_count = 0; | 
|---|
| 374 | key         = NULL; | 
|---|
| 375 |  | 
|---|
| 376 | for (GBDATA *gb_key = GB_child(gb_key_data); gb_key; gb_key = GB_nextChild(gb_key)) { | 
|---|
| 377 | key_count++; | 
|---|
| 378 | } | 
|---|
| 379 |  | 
|---|
| 380 | if (key_count) { | 
|---|
| 381 | key = (GBDATA**)malloc(key_count*sizeof(*key)); | 
|---|
| 382 |  | 
|---|
| 383 | int container_count = 0; | 
|---|
| 384 | for (GBDATA *gb_key = GB_child(gb_key_data); gb_key; gb_key = GB_nextChild(gb_key)) { | 
|---|
| 385 | GBDATA   *gb_type = GB_entry(gb_key, CHANGEKEY_TYPE); | 
|---|
| 386 | GB_TYPES  type    = GB_TYPES(GB_read_int(gb_type)); | 
|---|
| 387 |  | 
|---|
| 388 | if (type == GB_DB) { // move containers behind fields | 
|---|
| 389 | key[key_count-1-container_count++] = gb_key; | 
|---|
| 390 | } | 
|---|
| 391 | else { | 
|---|
| 392 | key[field_count++] = gb_key; | 
|---|
| 393 | } | 
|---|
| 394 | } | 
|---|
| 395 | ui_assert((container_count+field_count) == key_count); | 
|---|
| 396 | reverse_order(field_count, key_count-1); // of containers | 
|---|
| 397 | } | 
|---|
| 398 | order_changed = false; | 
|---|
| 399 | } | 
|---|
| 400 | ~KeySorter() { | 
|---|
| 401 | ui_assert(!order_changed); // order changed but not written | 
|---|
| 402 | free(key); | 
|---|
| 403 | } | 
|---|
| 404 |  | 
|---|
| 405 | int get_field_count() const { return field_count; } | 
|---|
| 406 |  | 
|---|
| 407 | void bubble_sort(int p1, int p2, ReorderMode mode, BoundItemSel *selector) { | 
|---|
| 408 | if (p1>p2) std::swap(p1, p2); | 
|---|
| 409 | if (legal_field_pos(p1, p2)) { | 
|---|
| 410 | if (mode == ORDER_FREQ) { | 
|---|
| 411 | sort_progress = new arb_progress("Calculating field frequencies", p2-p1+1); | 
|---|
| 412 | } | 
|---|
| 413 | bitem_selector = selector; | 
|---|
| 414 | while (p1<p2) { | 
|---|
| 415 | bool changed = false; | 
|---|
| 416 |  | 
|---|
| 417 | int i = p2; | 
|---|
| 418 | while (i>p1) { | 
|---|
| 419 | if (compare(i-1, i, mode)>0) { | 
|---|
| 420 | swap(i-1, i); | 
|---|
| 421 | changed = true; | 
|---|
| 422 | } | 
|---|
| 423 | --i; | 
|---|
| 424 | } | 
|---|
| 425 | if (!changed) break; | 
|---|
| 426 | ++p1; | 
|---|
| 427 | } | 
|---|
| 428 | if (order_hash) { | 
|---|
| 429 | GBS_free_hash(order_hash); | 
|---|
| 430 | order_hash = NULL; | 
|---|
| 431 | } | 
|---|
| 432 | if (sort_progress) { | 
|---|
| 433 | delete sort_progress; | 
|---|
| 434 | sort_progress = NULL; | 
|---|
| 435 | } | 
|---|
| 436 | } | 
|---|
| 437 | } | 
|---|
| 438 | void reverse_order(int p1, int p2) { | 
|---|
| 439 | if (p1>p2) std::swap(p1, p2); | 
|---|
| 440 | if (legal_field_pos(p1, p2)) while (p1<p2) swap(p1++, p2--); | 
|---|
| 441 | } | 
|---|
| 442 |  | 
|---|
| 443 | int index_of(GBDATA *gb_key) { | 
|---|
| 444 | int i; | 
|---|
| 445 | for (i = 0; i<key_count; i++) { | 
|---|
| 446 | if (gb_key == key[i]) break; | 
|---|
| 447 | } | 
|---|
| 448 | if (i == key_count) { | 
|---|
| 449 | ui_assert(0); | 
|---|
| 450 | i = -1; | 
|---|
| 451 | } | 
|---|
| 452 | return i; | 
|---|
| 453 | } | 
|---|
| 454 |  | 
|---|
| 455 | void move_to(int to_move, int wanted_position) { | 
|---|
| 456 | if (legal_field_pos(to_move, wanted_position)) { | 
|---|
| 457 | while (to_move<wanted_position) { | 
|---|
| 458 | swap(to_move, to_move+1); | 
|---|
| 459 | to_move++; | 
|---|
| 460 | } | 
|---|
| 461 | while (to_move>wanted_position) { | 
|---|
| 462 | swap(to_move, to_move-1); | 
|---|
| 463 | to_move--; | 
|---|
| 464 | } | 
|---|
| 465 | } | 
|---|
| 466 | } | 
|---|
| 467 |  | 
|---|
| 468 | __ATTR__USERESULT GB_ERROR save_changes() { | 
|---|
| 469 | GB_ERROR warning = NULL; | 
|---|
| 470 | if (order_changed) { | 
|---|
| 471 | if (key_count) { | 
|---|
| 472 | GBDATA *gb_main = GB_get_root(key[0]); | 
|---|
| 473 | warning         = GB_resort_data_base(gb_main, key, key_count); | 
|---|
| 474 | } | 
|---|
| 475 | order_changed = false; | 
|---|
| 476 | } | 
|---|
| 477 | return warning; | 
|---|
| 478 | } | 
|---|
| 479 | }; | 
|---|
| 480 |  | 
|---|
| 481 | GB_HASH      *KeySorter::order_hash     = NULL; | 
|---|
| 482 | BoundItemSel *KeySorter::bitem_selector = NULL; | 
|---|
| 483 | arb_progress *KeySorter::sort_progress  = NULL; | 
|---|
| 484 |  | 
|---|
| 485 | static void reorder_keys(AW_window *aws, ReorderMode mode, Itemfield_Selection *sel_left, Itemfield_Selection *sel_right) { | 
|---|
| 486 | ItemSelector& selector = sel_left->get_selector(); | 
|---|
| 487 | ui_assert(&selector == &sel_right->get_selector()); | 
|---|
| 488 |  | 
|---|
| 489 | int left_index  = sel_left->get_sellist()->get_index_of_selected(); | 
|---|
| 490 | int right_index = sel_right->get_sellist()->get_index_of_selected(); | 
|---|
| 491 |  | 
|---|
| 492 | GB_ERROR warning = 0; | 
|---|
| 493 |  | 
|---|
| 494 | GBDATA  *gb_main = sel_left->get_gb_main(); | 
|---|
| 495 | AW_root *awr     = aws->get_root(); | 
|---|
| 496 |  | 
|---|
| 497 | GB_begin_transaction(gb_main); | 
|---|
| 498 |  | 
|---|
| 499 | GBDATA *gb_left_field  = GBT_get_changekey(gb_main, awr->awar(AWAR_FIELD_REORDER_SOURCE)->read_char_pntr(), selector.change_key_path); | 
|---|
| 500 | GBDATA *gb_right_field = GBT_get_changekey(gb_main, awr->awar(AWAR_FIELD_REORDER_DEST)->read_char_pntr(), selector.change_key_path); | 
|---|
| 501 |  | 
|---|
| 502 | if (!gb_left_field || !gb_right_field || gb_left_field == gb_right_field) { | 
|---|
| 503 | warning = "Please select different fields in both list"; | 
|---|
| 504 | } | 
|---|
| 505 | else { | 
|---|
| 506 | GBDATA    *gb_key_data = GB_search(gb_main, selector.change_key_path, GB_CREATE_CONTAINER); | 
|---|
| 507 | KeySorter  sorter(gb_key_data); | 
|---|
| 508 |  | 
|---|
| 509 | int left_key_idx  = sorter.index_of(gb_left_field); | 
|---|
| 510 | int right_key_idx = sorter.index_of(gb_right_field); | 
|---|
| 511 |  | 
|---|
| 512 | switch (mode) { | 
|---|
| 513 | case RIGHT_BEHIND_LEFT: | 
|---|
| 514 | sorter.move_to(right_key_idx, left_key_idx+(left_key_idx<right_key_idx)); | 
|---|
| 515 | if (right_index>left_index) { left_index++; right_index++; } // make it simple to move several consecutive keys | 
|---|
| 516 | break; | 
|---|
| 517 | case REVERSE_ORDER: | 
|---|
| 518 | sorter.reverse_order(left_key_idx, right_key_idx); | 
|---|
| 519 | std::swap(left_index, right_index); | 
|---|
| 520 | break; | 
|---|
| 521 | default: { | 
|---|
| 522 | BoundItemSel bis(gb_main, selector); | 
|---|
| 523 | sorter.bubble_sort(left_key_idx, right_key_idx, mode, &bis); | 
|---|
| 524 | break; | 
|---|
| 525 | } | 
|---|
| 526 | } | 
|---|
| 527 |  | 
|---|
| 528 | warning = sorter.save_changes(); | 
|---|
| 529 | } | 
|---|
| 530 | GB_commit_transaction(gb_main); | 
|---|
| 531 |  | 
|---|
| 532 | if (warning) { | 
|---|
| 533 | aw_message(warning); | 
|---|
| 534 | } | 
|---|
| 535 | else { | 
|---|
| 536 | sel_left->get_sellist()->select_element_at(left_index); | 
|---|
| 537 | sel_right->get_sellist()->select_element_at(right_index); | 
|---|
| 538 | } | 
|---|
| 539 | } | 
|---|
| 540 |  | 
|---|
| 541 | static void reorder_right_behind_left(AW_window *aws, AW_CL cl_selleft, AW_CL cl_selright) { reorder_keys(aws, RIGHT_BEHIND_LEFT, (Itemfield_Selection*)cl_selleft, (Itemfield_Selection*)cl_selright); } | 
|---|
| 542 | static void reverse_key_order        (AW_window *aws, AW_CL cl_selleft, AW_CL cl_selright) { reorder_keys(aws, REVERSE_ORDER,     (Itemfield_Selection*)cl_selleft, (Itemfield_Selection*)cl_selright); } | 
|---|
| 543 |  | 
|---|
| 544 | static void sort_keys(AW_window *aws, AW_CL cl_selleft, AW_CL cl_selright) { | 
|---|
| 545 | ReorderMode mode = ReorderMode(aws->get_root()->awar(AWAR_FIELD_REORDER_ORDER)->read_int()); | 
|---|
| 546 | reorder_keys(aws, mode, (Itemfield_Selection*)cl_selleft, (Itemfield_Selection*)cl_selright); | 
|---|
| 547 | } | 
|---|
| 548 |  | 
|---|
| 549 | static void reorder_up_down(AW_window *aws, AW_CL cl_selright, AW_CL cl_dir) { | 
|---|
| 550 | int                  dir       = (int)cl_dir; | 
|---|
| 551 | Itemfield_Selection *sel_right = (Itemfield_Selection*)cl_selright; | 
|---|
| 552 | GBDATA              *gb_main   = sel_right->get_gb_main(); | 
|---|
| 553 |  | 
|---|
| 554 | GB_begin_transaction(gb_main); | 
|---|
| 555 | ItemSelector& selector   = sel_right->get_selector(); | 
|---|
| 556 | int           list_index = sel_right->get_sellist()->get_index_of_selected(); | 
|---|
| 557 |  | 
|---|
| 558 | const char *field_name = aws->get_root()->awar(AWAR_FIELD_REORDER_DEST)->read_char_pntr(); | 
|---|
| 559 | GBDATA     *gb_field   = GBT_get_changekey(gb_main, field_name, selector.change_key_path); | 
|---|
| 560 | GB_ERROR    warning    = 0; | 
|---|
| 561 |  | 
|---|
| 562 | if (!gb_field) { | 
|---|
| 563 | warning = "Please select the item to move in the right box"; | 
|---|
| 564 | } | 
|---|
| 565 | else { | 
|---|
| 566 | GBDATA    *gb_key_data = GB_search(gb_main, selector.change_key_path, GB_CREATE_CONTAINER); | 
|---|
| 567 | KeySorter  sorter(gb_key_data); | 
|---|
| 568 |  | 
|---|
| 569 | int curr_index = sorter.index_of(gb_field); | 
|---|
| 570 | int dest_index = -1; | 
|---|
| 571 | if (abs(dir) == 1) { | 
|---|
| 572 | dest_index = curr_index+dir; | 
|---|
| 573 | list_index = -1; | 
|---|
| 574 | } | 
|---|
| 575 | else { | 
|---|
| 576 | dest_index = dir<0 ? 0 : sorter.get_field_count()-1; | 
|---|
| 577 | } | 
|---|
| 578 |  | 
|---|
| 579 | sorter.move_to(curr_index, dest_index); | 
|---|
| 580 | warning = sorter.save_changes(); | 
|---|
| 581 |  | 
|---|
| 582 | } | 
|---|
| 583 |  | 
|---|
| 584 | GB_commit_transaction(gb_main); | 
|---|
| 585 | if (list_index >= 0) sel_right->get_sellist()->select_element_at(list_index); | 
|---|
| 586 | if (warning) aw_message(warning); | 
|---|
| 587 | } | 
|---|
| 588 |  | 
|---|
| 589 | AW_window *DBUI::create_fields_reorder_window(AW_root *root, AW_CL cl_bound_item_selector) { | 
|---|
| 590 | BoundItemSel  *bound_selector = (BoundItemSel*)cl_bound_item_selector; | 
|---|
| 591 | ItemSelector&  selector       = bound_selector->selector; | 
|---|
| 592 |  | 
|---|
| 593 | static AW_window_simple *awsa[QUERY_ITEM_TYPES]; | 
|---|
| 594 | if (!awsa[selector.type]) { | 
|---|
| 595 | AW_window_simple *aws = new AW_window_simple; | 
|---|
| 596 | awsa[selector.type]  = aws; | 
|---|
| 597 |  | 
|---|
| 598 | aws->init(root, "REORDER_FIELDS", "REORDER FIELDS"); | 
|---|
| 599 | aws->load_xfig("ad_kreo.fig"); | 
|---|
| 600 |  | 
|---|
| 601 | aws->callback((AW_CB0)AW_POPDOWN); | 
|---|
| 602 | aws->at("close"); | 
|---|
| 603 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 604 |  | 
|---|
| 605 | const char *HELPFILE = "spaf_reorder.hlp"; | 
|---|
| 606 | aws->callback(makeHelpCallback(HELPFILE)); | 
|---|
| 607 | aws->at("help"); | 
|---|
| 608 | aws->create_button("HELP", "Help", "H"); | 
|---|
| 609 |  | 
|---|
| 610 | Itemfield_Selection *sel1 = create_selection_list_on_itemfields(bound_selector->gb_main, aws, AWAR_FIELD_REORDER_SOURCE, true, FIELD_FILTER_NDS, "source", 0, selector, 20, 10, SF_STANDARD, NULL); | 
|---|
| 611 | Itemfield_Selection *sel2 = create_selection_list_on_itemfields(bound_selector->gb_main, aws, AWAR_FIELD_REORDER_DEST,   true, FIELD_FILTER_NDS, "dest",   0, selector, 20, 10, SF_STANDARD, NULL); | 
|---|
| 612 |  | 
|---|
| 613 | aws->button_length(8); | 
|---|
| 614 |  | 
|---|
| 615 | aws->at("sort"); | 
|---|
| 616 | aws->callback(sort_keys, (AW_CL)sel1, (AW_CL)sel2); | 
|---|
| 617 | aws->help_text(HELPFILE); | 
|---|
| 618 | aws->create_button("SORT", "Sort by"); | 
|---|
| 619 |  | 
|---|
| 620 | aws->at("sorttype"); | 
|---|
| 621 | aws->create_option_menu(AWAR_FIELD_REORDER_ORDER, true); | 
|---|
| 622 | aws->insert_option("name",      "a", ORDER_ALPHA); | 
|---|
| 623 | aws->insert_option("type",      "t", ORDER_TYPE); | 
|---|
| 624 | aws->insert_option("frequency", "f", ORDER_FREQ); | 
|---|
| 625 | aws->update_option_menu(); | 
|---|
| 626 |  | 
|---|
| 627 | aws->at("leftright"); | 
|---|
| 628 | aws->callback(reorder_right_behind_left, (AW_CL)sel1, (AW_CL)sel2); | 
|---|
| 629 | aws->help_text(HELPFILE); | 
|---|
| 630 | aws->create_autosize_button("MOVE_RIGHT_BEHIND_LEFT", "Move right\nbehind left"); | 
|---|
| 631 |  | 
|---|
| 632 | aws->at("reverse"); | 
|---|
| 633 | aws->callback(reverse_key_order, (AW_CL)sel1, (AW_CL)sel2); | 
|---|
| 634 | aws->help_text(HELPFILE); | 
|---|
| 635 | aws->create_autosize_button("REVERSE", "Reverse"); | 
|---|
| 636 |  | 
|---|
| 637 | aws->button_length(6); | 
|---|
| 638 | struct { | 
|---|
| 639 | const char *tag; | 
|---|
| 640 | const char *macro; | 
|---|
| 641 | int         dir; | 
|---|
| 642 | } reorder[4] = { | 
|---|
| 643 | { "Top",    "MOVE_TOP_RIGHT",  -2 }, | 
|---|
| 644 | { "Up",     "MOVE_UP_RIGHT",   -1 }, | 
|---|
| 645 | { "Down",   "MOVE_DOWN_RIGHT", +1 }, | 
|---|
| 646 | { "Bottom", "MOVE_BOT_RIGHT",  +2 }, | 
|---|
| 647 | }; | 
|---|
| 648 |  | 
|---|
| 649 | for (int i = 0; i<4; ++i) { | 
|---|
| 650 | aws->at(reorder[i].tag); | 
|---|
| 651 | aws->callback(reorder_up_down, (AW_CL)sel2, reorder[i].dir); | 
|---|
| 652 | aws->help_text(HELPFILE); | 
|---|
| 653 | aws->create_button(reorder[i].macro, reorder[i].tag); | 
|---|
| 654 | } | 
|---|
| 655 | } | 
|---|
| 656 |  | 
|---|
| 657 | return awsa[selector.type]; | 
|---|
| 658 | } | 
|---|
| 659 |  | 
|---|
| 660 | static void hide_field_cb(AW_window *aws, AW_CL cl_sel, AW_CL cl_hide) { | 
|---|
| 661 | Itemfield_Selection *item_sel = (Itemfield_Selection*)cl_sel; | 
|---|
| 662 |  | 
|---|
| 663 | GBDATA   *gb_main = item_sel->get_gb_main(); | 
|---|
| 664 | GB_ERROR  error   = GB_begin_transaction(gb_main); | 
|---|
| 665 |  | 
|---|
| 666 | if (!error) { | 
|---|
| 667 | char          *source    = aws->get_root()->awar(AWAR_FIELD_DELETE)->read_string(); | 
|---|
| 668 | ItemSelector&  selector  = item_sel->get_selector(); | 
|---|
| 669 | GBDATA        *gb_source = GBT_get_changekey(gb_main, source, selector.change_key_path); | 
|---|
| 670 |  | 
|---|
| 671 | if (!gb_source) error = "Please select the field you want to (un)hide"; | 
|---|
| 672 | else error            = GBT_write_int(gb_source, CHANGEKEY_HIDDEN, int(cl_hide)); | 
|---|
| 673 |  | 
|---|
| 674 | free(source); | 
|---|
| 675 | } | 
|---|
| 676 | GB_end_transaction_show_error(gb_main, error, aw_message); | 
|---|
| 677 | if (!error) item_sel->get_sellist()->move_selection(1); | 
|---|
| 678 | } | 
|---|
| 679 |  | 
|---|
| 680 | static void field_delete_cb(AW_window *aws, AW_CL cl_sel) { | 
|---|
| 681 | Itemfield_Selection *item_sel = (Itemfield_Selection*)cl_sel; | 
|---|
| 682 |  | 
|---|
| 683 | GBDATA   *gb_main = item_sel->get_gb_main(); | 
|---|
| 684 | GB_ERROR  error   = GB_begin_transaction(gb_main); | 
|---|
| 685 |  | 
|---|
| 686 | if (!error) { | 
|---|
| 687 | char              *source     = aws->get_root()->awar(AWAR_FIELD_DELETE)->read_string(); | 
|---|
| 688 | ItemSelector&      selector   = item_sel->get_selector(); | 
|---|
| 689 | AW_selection_list *sellist    = item_sel->get_sellist(); | 
|---|
| 690 | int                curr_index = sellist->get_index_of_selected(); | 
|---|
| 691 | GBDATA            *gb_source  = GBT_get_changekey(gb_main, source, selector.change_key_path); | 
|---|
| 692 |  | 
|---|
| 693 | if (!gb_source) error = "Please select the field you want to delete"; | 
|---|
| 694 | else error            = GB_delete(gb_source); | 
|---|
| 695 |  | 
|---|
| 696 | for (GBDATA *gb_item_container = selector.get_first_item_container(gb_main, aws->get_root(), QUERY_ALL_ITEMS); | 
|---|
| 697 | !error && gb_item_container; | 
|---|
| 698 | gb_item_container = selector.get_next_item_container(gb_item_container, QUERY_ALL_ITEMS)) | 
|---|
| 699 | { | 
|---|
| 700 | for (GBDATA * gb_item = selector.get_first_item(gb_item_container, QUERY_ALL_ITEMS); | 
|---|
| 701 | !error && gb_item; | 
|---|
| 702 | gb_item = selector.get_next_item(gb_item, QUERY_ALL_ITEMS)) | 
|---|
| 703 | { | 
|---|
| 704 | GBDATA *gbd = GB_search(gb_item, source, GB_FIND); | 
|---|
| 705 |  | 
|---|
| 706 | if (gbd) { | 
|---|
| 707 | error = GB_delete(gbd); | 
|---|
| 708 | if (!error) { | 
|---|
| 709 | // item has disappeared, this selects the next one: | 
|---|
| 710 | sellist->select_element_at(curr_index); | 
|---|
| 711 | } | 
|---|
| 712 | } | 
|---|
| 713 | } | 
|---|
| 714 | } | 
|---|
| 715 |  | 
|---|
| 716 | free(source); | 
|---|
| 717 | } | 
|---|
| 718 |  | 
|---|
| 719 | GB_end_transaction_show_error(gb_main, error, aw_message); | 
|---|
| 720 | } | 
|---|
| 721 |  | 
|---|
| 722 |  | 
|---|
| 723 | AW_window *DBUI::create_field_delete_window(AW_root *root, AW_CL cl_bound_item_selector) { | 
|---|
| 724 | BoundItemSel  *bound_selector = (BoundItemSel*)cl_bound_item_selector; | 
|---|
| 725 | ItemSelector&  selector       = bound_selector->selector; | 
|---|
| 726 |  | 
|---|
| 727 | static AW_window_simple *awsa[QUERY_ITEM_TYPES]; | 
|---|
| 728 | if (!awsa[selector.type]) { | 
|---|
| 729 | AW_window_simple *aws = new AW_window_simple; | 
|---|
| 730 | awsa[selector.type]  = aws; | 
|---|
| 731 |  | 
|---|
| 732 | aws->init(root, "DELETE_FIELD", "DELETE FIELD"); | 
|---|
| 733 | aws->load_xfig("ad_delof.fig"); | 
|---|
| 734 | aws->button_length(6); | 
|---|
| 735 |  | 
|---|
| 736 | aws->at("close"); aws->callback(AW_POPDOWN); | 
|---|
| 737 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 738 |  | 
|---|
| 739 | aws->at("help"); aws->callback(makeHelpCallback("spaf_delete.hlp")); | 
|---|
| 740 | aws->create_button("HELP", "Help", "H"); | 
|---|
| 741 |  | 
|---|
| 742 | Itemfield_Selection *item_sel = create_selection_list_on_itemfields(bound_selector->gb_main, aws, AWAR_FIELD_DELETE, true, -1, "source", 0, selector, 20, 10, SF_HIDDEN, NULL); | 
|---|
| 743 |  | 
|---|
| 744 | aws->button_length(13); | 
|---|
| 745 | aws->at("hide"); | 
|---|
| 746 | aws->callback(hide_field_cb, (AW_CL)item_sel, (AW_CL)1); | 
|---|
| 747 | aws->help_text("rm_field_only.hlp"); | 
|---|
| 748 | aws->create_button("HIDE_FIELD", "Hide field", "H"); | 
|---|
| 749 |  | 
|---|
| 750 | aws->at("unhide"); | 
|---|
| 751 | aws->callback(hide_field_cb, (AW_CL)item_sel, (AW_CL)0); | 
|---|
| 752 | aws->help_text("rm_field_only.hlp"); | 
|---|
| 753 | aws->create_button("UNHIDE_FIELD", "Unhide field", "U"); | 
|---|
| 754 |  | 
|---|
| 755 | aws->at("delf"); | 
|---|
| 756 | aws->callback(field_delete_cb, (AW_CL)item_sel); | 
|---|
| 757 | aws->help_text("rm_field_cmpt.hlp"); | 
|---|
| 758 | aws->create_button("DELETE_FIELD", "Delete field\n(data deleted)", "C"); | 
|---|
| 759 | } | 
|---|
| 760 |  | 
|---|
| 761 | return awsa[selector.type]; | 
|---|
| 762 | } | 
|---|
| 763 |  | 
|---|
| 764 | static void field_create_cb(AW_window *aws, AW_CL cl_bound_item_selector) { | 
|---|
| 765 | BoundItemSel  *bound_selector = (BoundItemSel*)cl_bound_item_selector; | 
|---|
| 766 | ItemSelector&  selector       = bound_selector->selector; | 
|---|
| 767 |  | 
|---|
| 768 | GB_push_transaction(bound_selector->gb_main); | 
|---|
| 769 | char     *name   = aws->get_root()->awar(AWAR_FIELD_CREATE_NAME)->read_string(); | 
|---|
| 770 | GB_ERROR  error  = GB_check_key(name); | 
|---|
| 771 | GB_ERROR  error2 = GB_check_hkey(name); | 
|---|
| 772 | if (error && !error2) { | 
|---|
| 773 | aw_message("Warning: Your key contain a '/' character,\n" | 
|---|
| 774 | "    that means it is a hierarchical key"); | 
|---|
| 775 | error = 0; | 
|---|
| 776 | } | 
|---|
| 777 |  | 
|---|
| 778 | int type = (int)aws->get_root()->awar(AWAR_FIELD_CREATE_TYPE)->read_int(); | 
|---|
| 779 |  | 
|---|
| 780 | if (!error) error = GBT_add_new_changekey_to_keypath(bound_selector->gb_main, name, type, selector.change_key_path); | 
|---|
| 781 | aws->hide_or_notify(error); | 
|---|
| 782 | free(name); | 
|---|
| 783 | GB_pop_transaction(bound_selector->gb_main); | 
|---|
| 784 | } | 
|---|
| 785 |  | 
|---|
| 786 | AW_window *DBUI::create_field_create_window(AW_root *root, AW_CL cl_bound_item_selector) { | 
|---|
| 787 | BoundItemSel  *bound_selector = (BoundItemSel*)cl_bound_item_selector; | 
|---|
| 788 | ItemSelector&  selector       = bound_selector->selector; | 
|---|
| 789 |  | 
|---|
| 790 | static AW_window_simple *awsa[QUERY_ITEM_TYPES]; | 
|---|
| 791 | if (awsa[selector.type]) return (AW_window *)awsa[selector.type]; | 
|---|
| 792 |  | 
|---|
| 793 | AW_window_simple *aws = new AW_window_simple; | 
|---|
| 794 | awsa[selector.type]  = aws; | 
|---|
| 795 |  | 
|---|
| 796 | aws->init(root, "CREATE_FIELD", "CREATE A NEW FIELD"); | 
|---|
| 797 | aws->load_xfig("ad_fcrea.fig"); | 
|---|
| 798 |  | 
|---|
| 799 | aws->callback((AW_CB0)AW_POPDOWN); | 
|---|
| 800 | aws->at("close"); | 
|---|
| 801 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 802 |  | 
|---|
| 803 | aws->at("input"); | 
|---|
| 804 | aws->label("FIELD NAME"); | 
|---|
| 805 | aws->create_input_field(AWAR_FIELD_CREATE_NAME, 15); | 
|---|
| 806 |  | 
|---|
| 807 | aws->at("type"); | 
|---|
| 808 | aws->create_toggle_field(AWAR_FIELD_CREATE_TYPE, "FIELD TYPE", "F"); | 
|---|
| 809 | aws->insert_toggle("Ascii Text",        "S", (int)GB_STRING); | 
|---|
| 810 | aws->insert_toggle("Link",              "L", (int)GB_LINK); | 
|---|
| 811 | aws->insert_toggle("Rounded Numerical", "N", (int)GB_INT); | 
|---|
| 812 | aws->insert_toggle("Numerical",         "R", (int)GB_FLOAT); | 
|---|
| 813 | aws->insert_toggle("MASK = 01 Text",    "0", (int)GB_BITS); | 
|---|
| 814 | aws->update_toggle_field(); | 
|---|
| 815 |  | 
|---|
| 816 | aws->at("ok"); | 
|---|
| 817 | aws->callback(field_create_cb, cl_bound_item_selector); | 
|---|
| 818 | aws->create_button("CREATE", "Create", "C"); | 
|---|
| 819 |  | 
|---|
| 820 | return (AW_window *)aws; | 
|---|
| 821 | } | 
|---|
| 822 |  | 
|---|
| 823 | #if defined(WARN_TODO) | 
|---|
| 824 | #warning GBT_convert_changekey currently only works for species fields, make it work with genes/exp/... as well (use selector) | 
|---|
| 825 | #endif | 
|---|
| 826 |  | 
|---|
| 827 | static void field_convert_commit_cb(AW_window *aws, AW_CL cl_bound_item_selector) { | 
|---|
| 828 | BoundItemSel *bound_selector = (BoundItemSel*)cl_bound_item_selector; | 
|---|
| 829 |  | 
|---|
| 830 | AW_root *root    = aws->get_root(); | 
|---|
| 831 | GBDATA  *gb_main = bound_selector->gb_main; | 
|---|
| 832 |  | 
|---|
| 833 | GB_push_transaction(gb_main); | 
|---|
| 834 | GB_ERROR error = GBT_convert_changekey(gb_main, | 
|---|
| 835 | root->awar(AWAR_FIELD_CONVERT_SOURCE)->read_char_pntr(), | 
|---|
| 836 | (GB_TYPES)root->awar(AWAR_FIELD_CONVERT_TYPE)->read_int()); | 
|---|
| 837 |  | 
|---|
| 838 | GB_end_transaction_show_error(gb_main, error, aw_message); | 
|---|
| 839 | } | 
|---|
| 840 |  | 
|---|
| 841 | static void field_convert_update_typesel_cb(AW_window *aws, AW_CL cl_bound_item_selector) { | 
|---|
| 842 | BoundItemSel  *bound_selector = (BoundItemSel*)cl_bound_item_selector; | 
|---|
| 843 | ItemSelector&  selector       = bound_selector->selector; | 
|---|
| 844 |  | 
|---|
| 845 | AW_root *root    = aws->get_root(); | 
|---|
| 846 | GBDATA  *gb_main = bound_selector->gb_main; | 
|---|
| 847 |  | 
|---|
| 848 | GB_push_transaction(gb_main); | 
|---|
| 849 | int type = GBT_get_type_of_changekey(gb_main, | 
|---|
| 850 | root->awar(AWAR_FIELD_CONVERT_SOURCE)->read_char_pntr(), | 
|---|
| 851 | selector.change_key_path); | 
|---|
| 852 | GB_pop_transaction(gb_main); | 
|---|
| 853 |  | 
|---|
| 854 | root->awar(AWAR_FIELD_CONVERT_TYPE)->write_int(type); | 
|---|
| 855 | } | 
|---|
| 856 |  | 
|---|
| 857 | static AW_window *create_field_convert_window(AW_root *root, AW_CL cl_bound_item_selector) { | 
|---|
| 858 | BoundItemSel  *bound_selector = (BoundItemSel*)cl_bound_item_selector; | 
|---|
| 859 | ItemSelector&  selector       = bound_selector->selector; | 
|---|
| 860 |  | 
|---|
| 861 | static AW_window_simple *awsa[QUERY_ITEM_TYPES]; | 
|---|
| 862 | if (awsa[selector.type]) return (AW_window *)awsa[selector.type]; | 
|---|
| 863 |  | 
|---|
| 864 | AW_window_simple *aws = new AW_window_simple; | 
|---|
| 865 | awsa[selector.type]  = aws; | 
|---|
| 866 |  | 
|---|
| 867 | aws->init(root, "CONVERT_FIELD", "CONVERT FIELDS"); | 
|---|
| 868 | aws->load_xfig("ad_conv.fig"); | 
|---|
| 869 |  | 
|---|
| 870 | aws->at("close"); | 
|---|
| 871 | aws->callback((AW_CB0)AW_POPDOWN); | 
|---|
| 872 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 873 |  | 
|---|
| 874 | aws->at("help"); | 
|---|
| 875 | aws->callback(makeHelpCallback("spaf_convert.hlp")); | 
|---|
| 876 | aws->create_button("HELP", "Help", "H"); | 
|---|
| 877 |  | 
|---|
| 878 | aws->callback(field_convert_update_typesel_cb, cl_bound_item_selector); | 
|---|
| 879 | create_selection_list_on_itemfields(bound_selector->gb_main, aws, AWAR_FIELD_CONVERT_SOURCE, true, -1, "source", 0, selector, 40, 20, SF_HIDDEN, NULL); | 
|---|
| 880 |  | 
|---|
| 881 | aws->at("typesel"); | 
|---|
| 882 | aws->create_toggle_field(AWAR_FIELD_CONVERT_TYPE, NULL, "F"); | 
|---|
| 883 | aws->insert_toggle("Ascii Text",        "S", (int)GB_STRING); | 
|---|
| 884 | aws->insert_toggle("Link",              "L", (int)GB_LINK); | 
|---|
| 885 | aws->insert_toggle("Rounded Numerical", "N", (int)GB_INT); | 
|---|
| 886 | aws->insert_toggle("Numerical",         "R", (int)GB_FLOAT); | 
|---|
| 887 | aws->insert_toggle("MASK = 01 Text",    "0", (int)GB_BITS); | 
|---|
| 888 | aws->update_toggle_field(); | 
|---|
| 889 |  | 
|---|
| 890 | aws->at("convert"); | 
|---|
| 891 | aws->callback(field_convert_commit_cb, cl_bound_item_selector); | 
|---|
| 892 | aws->create_button("CONVERT", "Convert", "T"); | 
|---|
| 893 |  | 
|---|
| 894 | return (AW_window*)aws; | 
|---|
| 895 | } | 
|---|
| 896 |  | 
|---|
| 897 | void DBUI::insert_field_admin_menuitems(AW_window *aws, GBDATA *gb_main) { | 
|---|
| 898 | static BoundItemSel *bis = new BoundItemSel(gb_main, SPECIES_get_selector()); | 
|---|
| 899 | ui_assert(bis->gb_main == gb_main); | 
|---|
| 900 |  | 
|---|
| 901 | aws->insert_menu_topic("spec_reorder_fields", "Reorder fields ...",     "R", "spaf_reorder.hlp", AWM_ALL, AW_POPUP, (AW_CL)create_fields_reorder_window,  (AW_CL)bis); | 
|---|
| 902 | aws->insert_menu_topic("spec_delete_field",   "Delete/Hide fields ...", "D", "spaf_delete.hlp",  AWM_EXP, AW_POPUP, (AW_CL)create_field_delete_window,  (AW_CL)bis); | 
|---|
| 903 | aws->insert_menu_topic("spec_create_field",   "Create fields ...",      "C", "spaf_create.hlp",  AWM_ALL, AW_POPUP, (AW_CL)create_field_create_window,  (AW_CL)bis); | 
|---|
| 904 | aws->insert_menu_topic("spec_convert_field",  "Convert fields ...",     "t", "spaf_convert.hlp", AWM_EXP, AW_POPUP, (AW_CL)create_field_convert_window, (AW_CL)bis); | 
|---|
| 905 | aws->sep______________(); | 
|---|
| 906 | aws->insert_menu_topic("spec_unhide_fields",  "Show all hidden fields", "S", "scandb.hlp", AWM_ALL, makeWindowCallback(species_field_selection_list_unhide_all_cb, gb_main, FIELD_FILTER_NDS)); | 
|---|
| 907 | aws->insert_menu_topic("spec_refresh_fields", "Refresh fields",         "f", "scandb.hlp", AWM_ALL, makeWindowCallback(species_field_selection_list_update_cb,     gb_main, FIELD_FILTER_NDS)); | 
|---|
| 908 | } | 
|---|
| 909 |  | 
|---|
| 910 | inline int get_and_fix_range_from_awar(AW_awar *awar) { | 
|---|
| 911 | const char *input = awar->read_char_pntr(); | 
|---|
| 912 | int         bpos = atoi(input); | 
|---|
| 913 | int         ipos; | 
|---|
| 914 |  | 
|---|
| 915 | if (bpos>0) { | 
|---|
| 916 | awar->write_string(GBS_global_string("%i", bpos)); | 
|---|
| 917 | ipos = bio2info(bpos); | 
|---|
| 918 | } | 
|---|
| 919 | else { | 
|---|
| 920 | ipos = -1; | 
|---|
| 921 | awar->write_string(""); | 
|---|
| 922 | } | 
|---|
| 923 | return ipos; | 
|---|
| 924 | } | 
|---|
| 925 |  | 
|---|
| 926 | class NN_GlobalData { | 
|---|
| 927 | DbQuery           *query; | 
|---|
| 928 | AW_selection_list *resultList;     // result list from create_next_neighbours_selected_window() | 
|---|
| 929 |  | 
|---|
| 930 | public: | 
|---|
| 931 | NN_GlobalData() : query(0), resultList(0) {} | 
|---|
| 932 |  | 
|---|
| 933 | void set_query(DbQuery *new_query) { | 
|---|
| 934 | if (new_query != query) { | 
|---|
| 935 | ui_assert(!query); // need redesign b4 changing query works | 
|---|
| 936 | query = new_query; | 
|---|
| 937 | } | 
|---|
| 938 | } | 
|---|
| 939 | void set_result_list(AW_selection_list *new_resultList) { | 
|---|
| 940 | if (new_resultList != resultList) { | 
|---|
| 941 | ui_assert(!resultList); // need redesign b4 changing query works | 
|---|
| 942 | resultList = new_resultList; | 
|---|
| 943 | } | 
|---|
| 944 | } | 
|---|
| 945 |  | 
|---|
| 946 | DbQuery *get_query() const { ui_assert(query); return query; } | 
|---|
| 947 |  | 
|---|
| 948 | AW_selection_list *get_result_list() const { ui_assert(resultList); return resultList; } | 
|---|
| 949 | GBDATA *get_gb_main() const { return query_get_gb_main(get_query()); } | 
|---|
| 950 | }; | 
|---|
| 951 | static NN_GlobalData NN_GLOBAL; | 
|---|
| 952 |  | 
|---|
| 953 | static PosRange get_nn_range_from_awars(AW_root *aw_root) { | 
|---|
| 954 | int start = get_and_fix_range_from_awar(aw_root->awar(AWAR_NN_RANGE_START)); | 
|---|
| 955 | int end   = get_and_fix_range_from_awar(aw_root->awar(AWAR_NN_RANGE_END)); | 
|---|
| 956 |  | 
|---|
| 957 | return PosRange(start, end); | 
|---|
| 958 | } | 
|---|
| 959 |  | 
|---|
| 960 | inline char *read_sequence_region(GBDATA *gb_data, const PosRange& range) { | 
|---|
| 961 | return range.dup_corresponding_part(GB_read_char_pntr(gb_data), GB_read_count(gb_data)); | 
|---|
| 962 | } | 
|---|
| 963 |  | 
|---|
| 964 | static void awtc_nn_search_all_listed(AW_window *aww) { | 
|---|
| 965 | DbQuery *query   = NN_GLOBAL.get_query(); | 
|---|
| 966 | GBDATA  *gb_main = query_get_gb_main(query); | 
|---|
| 967 |  | 
|---|
| 968 | ui_assert(get_queried_itemtype(query).type == QUERY_ITEM_SPECIES); | 
|---|
| 969 |  | 
|---|
| 970 | GB_begin_transaction(gb_main); | 
|---|
| 971 |  | 
|---|
| 972 | AW_root *aw_root    = aww->get_root(); | 
|---|
| 973 | char    *dest_field = aw_root->awar(AWAR_NN_LISTED_DEST_FIELD)->read_string(); | 
|---|
| 974 |  | 
|---|
| 975 | GB_ERROR error     = 0; | 
|---|
| 976 | GB_TYPES dest_type = GBT_get_type_of_changekey(gb_main, dest_field, CHANGE_KEY_PATH); | 
|---|
| 977 | if (!dest_type) { | 
|---|
| 978 | error = GB_export_error("Please select a valid field"); | 
|---|
| 979 | } | 
|---|
| 980 |  | 
|---|
| 981 | if (strcmp(dest_field, "name")==0) { | 
|---|
| 982 | int answer = aw_question(NULL, "CAUTION! This will destroy all name-fields of the listed species.\n", | 
|---|
| 983 | "Continue and destroy all name-fields,Abort"); | 
|---|
| 984 |  | 
|---|
| 985 | if (answer==1) { | 
|---|
| 986 | error = GB_export_error("Aborted by user"); | 
|---|
| 987 | } | 
|---|
| 988 | } | 
|---|
| 989 |  | 
|---|
| 990 | long max = count_queried_items(query, QUERY_ALL_ITEMS); | 
|---|
| 991 | if (!max) { | 
|---|
| 992 | error = "No species listed in query"; | 
|---|
| 993 | } | 
|---|
| 994 | else { | 
|---|
| 995 | arb_progress progress("Searching next neighbours", max); | 
|---|
| 996 | progress.auto_subtitles("Species"); | 
|---|
| 997 |  | 
|---|
| 998 | int     pts            = aw_root->awar(AWAR_PROBE_ADMIN_PT_SERVER)->read_int(); | 
|---|
| 999 | char   *ali_name       = aw_root->awar(AWAR_DEFAULT_ALIGNMENT)->read_string(); | 
|---|
| 1000 | int     oligo_len      = aw_root->awar(AWAR_NN_OLIGO_LEN)->read_int(); | 
|---|
| 1001 | int     mismatches     = aw_root->awar(AWAR_NN_MISMATCHES)->read_int(); | 
|---|
| 1002 | bool    fast_mode      = aw_root->awar(AWAR_NN_FAST_MODE)->read_int(); | 
|---|
| 1003 | bool    rel_matches    = aw_root->awar(AWAR_NN_REL_MATCHES)->read_int(); | 
|---|
| 1004 | int     wanted_entries = aw_root->awar(AWAR_NN_MAX_HITS)->read_int(); | 
|---|
| 1005 | bool    scored_entries = aw_root->awar(AWAR_NN_LISTED_SCORED_ENTRIES)->read_int(); | 
|---|
| 1006 | double  min_score      = aw_root->awar(AWAR_NN_MIN_SCORE)->read_float(); | 
|---|
| 1007 |  | 
|---|
| 1008 | FF_complement        compl_mode  = static_cast<FF_complement>(aw_root->awar(AWAR_NN_COMPLEMENT)->read_int()); | 
|---|
| 1009 | RelativeScoreScaling rel_scaling = static_cast<RelativeScoreScaling>(aw_root->awar(AWAR_NN_REL_SCALING)->read_int()); | 
|---|
| 1010 |  | 
|---|
| 1011 | PosRange org_range = get_nn_range_from_awars(aw_root); | 
|---|
| 1012 |  | 
|---|
| 1013 | for (GBDATA *gb_species = GBT_first_species(gb_main); | 
|---|
| 1014 | !error && gb_species; | 
|---|
| 1015 | gb_species = GBT_next_species(gb_species)) | 
|---|
| 1016 | { | 
|---|
| 1017 | if (!IS_QUERIED(gb_species, query)) continue; | 
|---|
| 1018 | GBDATA *gb_data = GBT_find_sequence(gb_species, ali_name); | 
|---|
| 1019 | if (gb_data) { | 
|---|
| 1020 | PosRange         range    = org_range; // modified by read_sequence_region | 
|---|
| 1021 | char            *sequence = read_sequence_region(gb_data, range); | 
|---|
| 1022 | PT_FamilyFinder  ff(gb_main, pts, oligo_len, mismatches, fast_mode, rel_matches, rel_scaling); | 
|---|
| 1023 |  | 
|---|
| 1024 | ff.restrict_2_region(range); | 
|---|
| 1025 |  | 
|---|
| 1026 | error = ff.searchFamily(sequence, compl_mode, wanted_entries, min_score); | 
|---|
| 1027 | if (!error) { | 
|---|
| 1028 | const FamilyList *fm = ff.getFamilyList(); | 
|---|
| 1029 |  | 
|---|
| 1030 | GBS_strstruct *value = NULL; | 
|---|
| 1031 | while (fm) { | 
|---|
| 1032 | const char *thisValue = 0; | 
|---|
| 1033 | if (rel_matches) { | 
|---|
| 1034 | ui_assert((fm->rel_matches*100) >= min_score); // filtered by ptserver | 
|---|
| 1035 | thisValue = scored_entries | 
|---|
| 1036 | ? GBS_global_string("%.1f%%:%s", fm->rel_matches*100, fm->name) | 
|---|
| 1037 | : fm->name; | 
|---|
| 1038 | } | 
|---|
| 1039 | else { | 
|---|
| 1040 | ui_assert(fm->matches >= min_score); // filtered by ptserver | 
|---|
| 1041 | thisValue = scored_entries | 
|---|
| 1042 | ? GBS_global_string("%li:%s", fm->matches, fm->name) | 
|---|
| 1043 | : fm->name; | 
|---|
| 1044 | } | 
|---|
| 1045 |  | 
|---|
| 1046 | if (thisValue) { | 
|---|
| 1047 | if (value == NULL) { // first entry | 
|---|
| 1048 | value = GBS_stropen(1000); | 
|---|
| 1049 | } | 
|---|
| 1050 | else { | 
|---|
| 1051 | GBS_chrcat(value, ';'); | 
|---|
| 1052 | } | 
|---|
| 1053 | GBS_strcat(value, thisValue); | 
|---|
| 1054 | } | 
|---|
| 1055 |  | 
|---|
| 1056 | fm = fm->next; | 
|---|
| 1057 | } | 
|---|
| 1058 |  | 
|---|
| 1059 | if (value) { | 
|---|
| 1060 | GBDATA *gb_dest = GB_search(gb_species, dest_field, dest_type); | 
|---|
| 1061 |  | 
|---|
| 1062 | error = GB_write_as_string(gb_dest, GBS_mempntr(value)); | 
|---|
| 1063 | GBS_strforget(value); | 
|---|
| 1064 | } | 
|---|
| 1065 | else { | 
|---|
| 1066 | GBDATA *gb_dest = GB_search(gb_species, dest_field, GB_FIND); | 
|---|
| 1067 | if (gb_dest) error = GB_delete(gb_dest); | 
|---|
| 1068 | } | 
|---|
| 1069 | } | 
|---|
| 1070 | free(sequence); | 
|---|
| 1071 | } | 
|---|
| 1072 | progress.inc_and_check_user_abort(error); | 
|---|
| 1073 | } | 
|---|
| 1074 | free(ali_name); | 
|---|
| 1075 | } | 
|---|
| 1076 | GB_end_transaction_show_error(gb_main, error, aw_message); | 
|---|
| 1077 | free(dest_field); | 
|---|
| 1078 | } | 
|---|
| 1079 |  | 
|---|
| 1080 | static void awtc_mark_hits(AW_window *) { | 
|---|
| 1081 | AW_selection_list *resultList = NN_GLOBAL.get_result_list(); | 
|---|
| 1082 | GB_HASH           *list_hash  = resultList->to_hash(false); | 
|---|
| 1083 | GBDATA            *gb_main    = NN_GLOBAL.get_gb_main(); | 
|---|
| 1084 |  | 
|---|
| 1085 | GB_transaction ta(gb_main); | 
|---|
| 1086 | for (GBDATA *gb_species = GBT_first_species(gb_main); | 
|---|
| 1087 | gb_species; | 
|---|
| 1088 | gb_species = GBT_next_species(gb_species)) | 
|---|
| 1089 | { | 
|---|
| 1090 | int hit = GBS_read_hash(list_hash, GBT_get_name(gb_species)); | 
|---|
| 1091 | GB_write_flag(gb_species, hit); | 
|---|
| 1092 | } | 
|---|
| 1093 | } | 
|---|
| 1094 |  | 
|---|
| 1095 | static void awtc_nn_search(AW_window *aww) { | 
|---|
| 1096 | AW_root  *aw_root  = aww->get_root(); | 
|---|
| 1097 | GBDATA   *gb_main  = NN_GLOBAL.get_gb_main(); | 
|---|
| 1098 | GB_ERROR  error    = 0; | 
|---|
| 1099 | PosRange  range    = get_nn_range_from_awars(aw_root); | 
|---|
| 1100 | char     *sequence = 0; | 
|---|
| 1101 | { | 
|---|
| 1102 | GB_transaction  ta(gb_main); | 
|---|
| 1103 |  | 
|---|
| 1104 | char   *sel_species = aw_root->awar(AWAR_SPECIES_NAME)->read_string(); | 
|---|
| 1105 | GBDATA *gb_species  = GBT_find_species(gb_main, sel_species); | 
|---|
| 1106 |  | 
|---|
| 1107 | if (!gb_species) { | 
|---|
| 1108 | error = "Select a species first"; | 
|---|
| 1109 | } | 
|---|
| 1110 | else { | 
|---|
| 1111 | char   *ali_name = aw_root->awar(AWAR_DEFAULT_ALIGNMENT)->read_string(); | 
|---|
| 1112 | GBDATA *gb_data  = GBT_find_sequence(gb_species, ali_name); | 
|---|
| 1113 |  | 
|---|
| 1114 | if (gb_data) { | 
|---|
| 1115 | sequence = read_sequence_region(gb_data, range); | 
|---|
| 1116 | } | 
|---|
| 1117 | else { | 
|---|
| 1118 | error = GBS_global_string("Species '%s' has no sequence '%s'", sel_species, ali_name); | 
|---|
| 1119 | } | 
|---|
| 1120 | free(ali_name); | 
|---|
| 1121 | } | 
|---|
| 1122 | free(sel_species); | 
|---|
| 1123 | } | 
|---|
| 1124 |  | 
|---|
| 1125 | int    pts         = aw_root->awar(AWAR_PROBE_ADMIN_PT_SERVER)->read_int(); | 
|---|
| 1126 | int    oligo_len   = aw_root->awar(AWAR_NN_OLIGO_LEN)->read_int(); | 
|---|
| 1127 | int    mismatches  = aw_root->awar(AWAR_NN_MISMATCHES)->read_int(); | 
|---|
| 1128 | bool   fast_mode   = aw_root->awar(AWAR_NN_FAST_MODE)->read_int(); | 
|---|
| 1129 | bool   rel_matches = aw_root->awar(AWAR_NN_REL_MATCHES)->read_int(); | 
|---|
| 1130 | double min_score   = aw_root->awar(AWAR_NN_MIN_SCORE)->read_float(); | 
|---|
| 1131 |  | 
|---|
| 1132 | RelativeScoreScaling rel_scaling = static_cast<RelativeScoreScaling>(aw_root->awar(AWAR_NN_REL_SCALING)->read_int()); | 
|---|
| 1133 |  | 
|---|
| 1134 | PT_FamilyFinder ff(gb_main, pts, oligo_len, mismatches, fast_mode, rel_matches, rel_scaling); | 
|---|
| 1135 |  | 
|---|
| 1136 | ff.restrict_2_region(range); | 
|---|
| 1137 |  | 
|---|
| 1138 | int max_hits = 0; // max wanted hits | 
|---|
| 1139 |  | 
|---|
| 1140 | if (!error) { | 
|---|
| 1141 | FF_complement compl_mode = static_cast<FF_complement>(aw_root->awar(AWAR_NN_COMPLEMENT)->read_int()); | 
|---|
| 1142 | max_hits                 = aw_root->awar(AWAR_NN_MAX_HITS)->read_int(); | 
|---|
| 1143 |  | 
|---|
| 1144 | error = ff.searchFamily(sequence, compl_mode, max_hits, min_score); | 
|---|
| 1145 | } | 
|---|
| 1146 |  | 
|---|
| 1147 | // update result list | 
|---|
| 1148 | { | 
|---|
| 1149 | AW_selection_list* sel = NN_GLOBAL.get_result_list(); | 
|---|
| 1150 | sel->clear(); | 
|---|
| 1151 |  | 
|---|
| 1152 | int hits = 0; | 
|---|
| 1153 | if (error) { | 
|---|
| 1154 | aw_message(error); | 
|---|
| 1155 | sel->insert_default("<Error>", ""); | 
|---|
| 1156 | } | 
|---|
| 1157 | else { | 
|---|
| 1158 | int count     = 1; | 
|---|
| 1159 | int shownHits = max_hits>0 ? max_hits : ff.getRealHits(); | 
|---|
| 1160 | int numWidth  = log(shownHits)/log(10)+1; | 
|---|
| 1161 |  | 
|---|
| 1162 | for (const FamilyList *fm = ff.getFamilyList(); fm; fm = fm->next) { | 
|---|
| 1163 | const char *dis; | 
|---|
| 1164 | if (rel_matches) { | 
|---|
| 1165 | dis = GBS_global_string("#%0*i %-12s Rel.hits: %5.1f%%", numWidth, count, fm->name, fm->rel_matches*100); | 
|---|
| 1166 | } | 
|---|
| 1167 | else { | 
|---|
| 1168 | dis = GBS_global_string("#%0*i %-12s Hits: %4li", numWidth, count, fm->name, fm->matches); | 
|---|
| 1169 | } | 
|---|
| 1170 |  | 
|---|
| 1171 | sel->insert(dis, fm->name); | 
|---|
| 1172 | count++; | 
|---|
| 1173 | } | 
|---|
| 1174 |  | 
|---|
| 1175 | sel->insert_default(ff.hits_were_truncated() ? "<List truncated>" : "<No more hits>", ""); | 
|---|
| 1176 | hits = ff.getRealHits(); | 
|---|
| 1177 | } | 
|---|
| 1178 | aw_root->awar(AWAR_NN_SELECTED_HIT_COUNT)->write_int(hits); | 
|---|
| 1179 | if (aw_root->awar(AWAR_NN_SELECTED_AUTO_MARK)->read_int()) { | 
|---|
| 1180 | awtc_mark_hits(NULL); | 
|---|
| 1181 | aw_root->awar(AWAR_TREE_REFRESH)->touch(); | 
|---|
| 1182 | } | 
|---|
| 1183 | sel->update(); | 
|---|
| 1184 | } | 
|---|
| 1185 |  | 
|---|
| 1186 | free(sequence); | 
|---|
| 1187 | } | 
|---|
| 1188 |  | 
|---|
| 1189 | static void awtc_move_hits(AW_window *aww) { | 
|---|
| 1190 | AW_root *aw_root         = aww->get_root(); | 
|---|
| 1191 | char    *current_species = aw_root->awar(AWAR_SPECIES_NAME)->read_string(); | 
|---|
| 1192 |  | 
|---|
| 1193 | if (!current_species) current_species = strdup("<unknown>"); | 
|---|
| 1194 |  | 
|---|
| 1195 | char *hit_description = GBS_global_string_copy("<neighbour of %s: %%s>", current_species); | 
|---|
| 1196 |  | 
|---|
| 1197 | copy_selection_list_2_query_box(NN_GLOBAL.get_query(), NN_GLOBAL.get_result_list(), hit_description); | 
|---|
| 1198 |  | 
|---|
| 1199 | free(hit_description); | 
|---|
| 1200 | free(current_species); | 
|---|
| 1201 | } | 
|---|
| 1202 |  | 
|---|
| 1203 | static void nn_do_autosearch_cb(AW_root *) { | 
|---|
| 1204 | awtc_nn_search(NULL); | 
|---|
| 1205 | } | 
|---|
| 1206 |  | 
|---|
| 1207 | static void nn_auto_search_changed_cb(AW_root *awr) { | 
|---|
| 1208 | int auto_search = awr->awar(AWAR_NN_SELECTED_AUTO_SEARCH)->read_int(); | 
|---|
| 1209 |  | 
|---|
| 1210 | AW_awar *awar_sel_species = awr->awar(AWAR_SPECIES_NAME); | 
|---|
| 1211 | if (auto_search) { | 
|---|
| 1212 | awar_sel_species->add_callback(nn_do_autosearch_cb); | 
|---|
| 1213 | } | 
|---|
| 1214 | else { | 
|---|
| 1215 | awar_sel_species->remove_callback(nn_do_autosearch_cb); | 
|---|
| 1216 | } | 
|---|
| 1217 | } | 
|---|
| 1218 |  | 
|---|
| 1219 | static void create_next_neighbours_vars(AW_root *aw_root) { | 
|---|
| 1220 | static bool created = false; | 
|---|
| 1221 |  | 
|---|
| 1222 | if (!created) { | 
|---|
| 1223 | aw_root->awar_int(AWAR_PROBE_ADMIN_PT_SERVER); | 
|---|
| 1224 | aw_root->awar_int(AWAR_NN_COMPLEMENT,  FF_FORWARD); | 
|---|
| 1225 |  | 
|---|
| 1226 | aw_root->awar_string(AWAR_NN_RANGE_START, ""); | 
|---|
| 1227 | aw_root->awar_string(AWAR_NN_RANGE_END,   ""); | 
|---|
| 1228 | aw_root->awar_int   (AWAR_NN_MAX_HITS,    10); | 
|---|
| 1229 | aw_root->awar_float (AWAR_NN_MIN_SCORE,   80); | 
|---|
| 1230 |  | 
|---|
| 1231 | aw_root->awar_int(AWAR_NN_SELECTED_HIT_COUNT,   0); | 
|---|
| 1232 | aw_root->awar_int(AWAR_NN_SELECTED_AUTO_SEARCH, 0)->add_callback(nn_auto_search_changed_cb); | 
|---|
| 1233 | aw_root->awar_int(AWAR_NN_SELECTED_AUTO_MARK,   0); | 
|---|
| 1234 |  | 
|---|
| 1235 | aw_root->awar_string(AWAR_NN_LISTED_DEST_FIELD,     "tmp"); | 
|---|
| 1236 | aw_root->awar_int   (AWAR_NN_LISTED_SCORED_ENTRIES, 1); | 
|---|
| 1237 |  | 
|---|
| 1238 | AWTC_create_common_next_neighbour_vars(aw_root); | 
|---|
| 1239 |  | 
|---|
| 1240 | created = true; | 
|---|
| 1241 | } | 
|---|
| 1242 | } | 
|---|
| 1243 |  | 
|---|
| 1244 | static void create_common_next_neighbour_fields(AW_window *aws) { | 
|---|
| 1245 | aws->at("pt_server"); | 
|---|
| 1246 | awt_create_PTSERVER_selection_button(aws, AWAR_PROBE_ADMIN_PT_SERVER); | 
|---|
| 1247 |  | 
|---|
| 1248 | AWTC_create_common_next_neighbour_fields(aws); | 
|---|
| 1249 |  | 
|---|
| 1250 | aws->auto_space(5, 5); | 
|---|
| 1251 |  | 
|---|
| 1252 | aws->at("range"); | 
|---|
| 1253 | aws->create_input_field(AWAR_NN_RANGE_START, 6); | 
|---|
| 1254 | aws->create_input_field(AWAR_NN_RANGE_END,   6); | 
|---|
| 1255 |  | 
|---|
| 1256 | aws->at("compl"); | 
|---|
| 1257 | aws->create_option_menu(AWAR_NN_COMPLEMENT, true); | 
|---|
| 1258 | aws->insert_default_option("forward",            "", FF_FORWARD); | 
|---|
| 1259 | aws->insert_option        ("reverse",            "", FF_REVERSE); | 
|---|
| 1260 | aws->insert_option        ("complement",         "", FF_COMPLEMENT); | 
|---|
| 1261 | aws->insert_option        ("reverse-complement", "", FF_REVERSE_COMPLEMENT); | 
|---|
| 1262 | aws->insert_option        ("fwd + rev-compl",    "", FF_FORWARD|FF_REVERSE_COMPLEMENT); | 
|---|
| 1263 | aws->insert_option        ("rev + compl",        "", FF_REVERSE|FF_COMPLEMENT); | 
|---|
| 1264 | aws->insert_option        ("any",                "", FF_FORWARD|FF_REVERSE|FF_COMPLEMENT|FF_REVERSE_COMPLEMENT); | 
|---|
| 1265 | aws->update_option_menu(); | 
|---|
| 1266 |  | 
|---|
| 1267 | aws->at("results"); | 
|---|
| 1268 | aws->create_input_field(AWAR_NN_MAX_HITS, 3); | 
|---|
| 1269 |  | 
|---|
| 1270 | aws->at("min_score"); | 
|---|
| 1271 | aws->create_input_field(AWAR_NN_MIN_SCORE, 6); | 
|---|
| 1272 | } | 
|---|
| 1273 |  | 
|---|
| 1274 | static AW_window *create_next_neighbours_listed_window(AW_root *aw_root, AW_CL cl_query) { | 
|---|
| 1275 | static AW_window_simple *aws = 0; | 
|---|
| 1276 | NN_GLOBAL.set_query((DbQuery*)cl_query); | 
|---|
| 1277 | if (!aws) { | 
|---|
| 1278 | create_next_neighbours_vars(aw_root); | 
|---|
| 1279 |  | 
|---|
| 1280 | aws = new AW_window_simple; | 
|---|
| 1281 | aws->init(aw_root, "SEARCH_NEXT_RELATIVES_OF_LISTED", "Search Next Neighbours of Listed"); | 
|---|
| 1282 | aws->load_xfig("ad_spec_nnm.fig"); | 
|---|
| 1283 |  | 
|---|
| 1284 | aws->at("close"); | 
|---|
| 1285 | aws->callback((AW_CB0)AW_POPDOWN); | 
|---|
| 1286 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 1287 |  | 
|---|
| 1288 | aws->at("help"); | 
|---|
| 1289 | aws->callback(makeHelpCallback("next_neighbours_listed.hlp")); | 
|---|
| 1290 | aws->create_button("HELP", "Help", "H"); | 
|---|
| 1291 |  | 
|---|
| 1292 | create_common_next_neighbour_fields(aws); | 
|---|
| 1293 |  | 
|---|
| 1294 | aws->at("add_score"); | 
|---|
| 1295 | aws->create_toggle(AWAR_NN_LISTED_SCORED_ENTRIES); | 
|---|
| 1296 |  | 
|---|
| 1297 | aws->at("field"); | 
|---|
| 1298 | create_selection_list_on_itemfields(query_get_gb_main((DbQuery*)cl_query), aws, AWAR_NN_LISTED_DEST_FIELD, true, (1<<GB_INT) | (1<<GB_STRING), "field", 0, SPECIES_get_selector(), 20, 10, SF_STANDARD, NULL); | 
|---|
| 1299 |  | 
|---|
| 1300 | aws->at("go"); | 
|---|
| 1301 | aws->callback(awtc_nn_search_all_listed); | 
|---|
| 1302 | aws->create_autosize_button("WRITE_FIELDS", "Write to field"); | 
|---|
| 1303 | } | 
|---|
| 1304 | return aws; | 
|---|
| 1305 | } | 
|---|
| 1306 |  | 
|---|
| 1307 | static AW_window *create_next_neighbours_selected_window(AW_root *aw_root, AW_CL cl_query) { | 
|---|
| 1308 | static AW_window_simple *aws = 0; | 
|---|
| 1309 | NN_GLOBAL.set_query((DbQuery*)cl_query); | 
|---|
| 1310 | if (!aws) { | 
|---|
| 1311 | create_next_neighbours_vars(aw_root); | 
|---|
| 1312 |  | 
|---|
| 1313 | aws = new AW_window_simple; | 
|---|
| 1314 | aws->init(aw_root, "SEARCH_NEXT_RELATIVE_OF_SELECTED", "Search Next Neighbours of Selected"); | 
|---|
| 1315 | aws->load_xfig("ad_spec_nn.fig"); | 
|---|
| 1316 |  | 
|---|
| 1317 | aws->at("close"); | 
|---|
| 1318 | aws->callback((AW_CB0)AW_POPDOWN); | 
|---|
| 1319 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 1320 |  | 
|---|
| 1321 | aws->at("help"); | 
|---|
| 1322 | aws->callback(makeHelpCallback("next_neighbours.hlp")); | 
|---|
| 1323 | aws->create_button("HELP", "Help", "H"); | 
|---|
| 1324 |  | 
|---|
| 1325 | create_common_next_neighbour_fields(aws); | 
|---|
| 1326 |  | 
|---|
| 1327 | aws->at("hit_count"); | 
|---|
| 1328 | aws->create_button(0, AWAR_NN_SELECTED_HIT_COUNT, 0, "+"); | 
|---|
| 1329 |  | 
|---|
| 1330 | aws->at("hits"); | 
|---|
| 1331 | AW_selection_list *resultList = aws->create_selection_list(AWAR_SPECIES_NAME, false); | 
|---|
| 1332 | NN_GLOBAL.set_result_list(resultList); | 
|---|
| 1333 | resultList->insert_default("No hits found", ""); | 
|---|
| 1334 | resultList->update(); | 
|---|
| 1335 |  | 
|---|
| 1336 | aws->at("go"); | 
|---|
| 1337 | aws->callback(awtc_nn_search); | 
|---|
| 1338 | aws->create_button("SEARCH", "Search"); | 
|---|
| 1339 |  | 
|---|
| 1340 | aws->at("auto_go"); | 
|---|
| 1341 | aws->label("Auto on selection change"); | 
|---|
| 1342 | aws->create_toggle(AWAR_NN_SELECTED_AUTO_SEARCH); | 
|---|
| 1343 |  | 
|---|
| 1344 | aws->at("mark"); | 
|---|
| 1345 | aws->callback(awtc_mark_hits); | 
|---|
| 1346 | aws->create_autosize_button("MARK_HITS", "Mark hits"); | 
|---|
| 1347 |  | 
|---|
| 1348 | aws->at("auto_mark"); | 
|---|
| 1349 | aws->label("Auto"); | 
|---|
| 1350 | aws->create_toggle(AWAR_NN_SELECTED_AUTO_MARK); | 
|---|
| 1351 |  | 
|---|
| 1352 | aws->at("move"); | 
|---|
| 1353 | aws->callback(awtc_move_hits); | 
|---|
| 1354 | aws->create_autosize_button("MOVE_TO_HITLIST", "Move to hitlist"); | 
|---|
| 1355 |  | 
|---|
| 1356 | } | 
|---|
| 1357 | return aws; | 
|---|
| 1358 | } | 
|---|
| 1359 |  | 
|---|
| 1360 | // --------------------------------------------- | 
|---|
| 1361 | //      species/organism specific callbacks | 
|---|
| 1362 |  | 
|---|
| 1363 | static AW_window *popup_new_speciesOrganismWindow(AW_root *aw_root, GBDATA *gb_main, bool organismWindow, int detach_id); | 
|---|
| 1364 |  | 
|---|
| 1365 | static void popup_detached_speciesOrganismWindow(AW_window *aw_parent, const InfoWindow *infoWin) { | 
|---|
| 1366 | const InfoWindow *reusable = InfoWindowRegistry::infowin.find_reusable_of_same_type_as(*infoWin); | 
|---|
| 1367 | if (reusable) reusable->reuse(); | 
|---|
| 1368 | else { // create a new window if none is reusable | 
|---|
| 1369 | popup_new_speciesOrganismWindow(aw_parent->get_root(), | 
|---|
| 1370 | infoWin->get_gbmain(), | 
|---|
| 1371 | infoWin->mapsOrganism(), | 
|---|
| 1372 | InfoWindowRegistry::infowin.allocate_detach_id(*infoWin)); | 
|---|
| 1373 | } | 
|---|
| 1374 | } | 
|---|
| 1375 |  | 
|---|
| 1376 | static AW_window *popup_new_speciesOrganismWindow(AW_root *aw_root, GBDATA *gb_main, bool organismWindow, int detach_id) { // INFO_WINDOW_CREATOR | 
|---|
| 1377 | // if detach_id is MAIN_WINDOW -> create main window (not detached) | 
|---|
| 1378 |  | 
|---|
| 1379 | AW_window_simple_menu *aws      = new AW_window_simple_menu; | 
|---|
| 1380 | const ItemSelector&    itemType = organismWindow ? ORGANISM_get_selector() : SPECIES_get_selector(); | 
|---|
| 1381 |  | 
|---|
| 1382 | init_info_window(aw_root, aws, itemType, detach_id); | 
|---|
| 1383 |  | 
|---|
| 1384 | aws->load_xfig("ad_spec.fig"); | 
|---|
| 1385 |  | 
|---|
| 1386 | aws->button_length(8); | 
|---|
| 1387 |  | 
|---|
| 1388 | aws->at("close"); | 
|---|
| 1389 | aws->callback(AW_POPDOWN); | 
|---|
| 1390 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 1391 |  | 
|---|
| 1392 | aws->at("search"); | 
|---|
| 1393 | aws->callback(makeCreateWindowCallback(DBUI::create_species_query_window, gb_main)); | 
|---|
| 1394 | aws->create_autosize_button("SEARCH", "Search...", "S"); | 
|---|
| 1395 |  | 
|---|
| 1396 | aws->at("help"); | 
|---|
| 1397 | aws->callback(makeHelpCallback(detach_id ? "sp_info_locked.hlp" : "sp_info.hlp")); // uses_hlp_res("sp_info_locked.hlp", "sp_info.hlp"); see ../../SOURCE_TOOLS/check_ressources.pl@uses_hlp_res | 
|---|
| 1398 | aws->create_button("HELP", "Help", "H"); | 
|---|
| 1399 |  | 
|---|
| 1400 | DbScanner         *scanner = create_db_scanner(gb_main, aws, "box", 0, "field", "enable", DB_VIEWER, 0, "mark", FIELD_FILTER_NDS, itemType); | 
|---|
| 1401 | const InfoWindow&  infoWin = InfoWindowRegistry::infowin.registerInfoWindow(aws, scanner, detach_id); | 
|---|
| 1402 |  | 
|---|
| 1403 | if (organismWindow) aws->create_menu("ORGANISM",    "O", AWM_ALL); | 
|---|
| 1404 | else                aws->create_menu("SPECIES",     "S", AWM_ALL); | 
|---|
| 1405 |  | 
|---|
| 1406 | aws->insert_menu_topic("species_delete",        "Delete",         "D", "spa_delete.hlp",  AWM_ALL, species_delete_cb,        (AW_CL)gb_main,                      0); | 
|---|
| 1407 | aws->insert_menu_topic("species_rename",        "Rename",         "R", "spa_rename.hlp",  AWM_ALL, species_rename_cb,        (AW_CL)gb_main,                      0); | 
|---|
| 1408 | aws->insert_menu_topic("species_copy",          "Copy",           "y", "spa_copy.hlp",    AWM_ALL, species_copy_cb,          (AW_CL)gb_main,                      0); | 
|---|
| 1409 | aws->insert_menu_topic("species_create",        "Create",         "C", "spa_create.hlp",  AWM_ALL, AW_POPUP,                 (AW_CL)create_species_create_window, (AW_CL)gb_main); | 
|---|
| 1410 | aws->insert_menu_topic("species_convert_2_sai", "Convert to SAI", "S", "sp_sp_2_ext.hlp", AWM_ALL, move_species_to_extended, (AW_CL)gb_main,                      0); | 
|---|
| 1411 | aws->sep______________(); | 
|---|
| 1412 |  | 
|---|
| 1413 | aws->create_menu("FIELDS", "F", AWM_ALL); | 
|---|
| 1414 | insert_field_admin_menuitems(aws, gb_main); | 
|---|
| 1415 |  | 
|---|
| 1416 | aws->at("detach"); | 
|---|
| 1417 | infoWin.add_detachOrGet_button(popup_detached_speciesOrganismWindow); | 
|---|
| 1418 |  | 
|---|
| 1419 | aws->show(); | 
|---|
| 1420 | infoWin.attach_selected_item(); | 
|---|
| 1421 | return aws; | 
|---|
| 1422 | } | 
|---|
| 1423 |  | 
|---|
| 1424 | static void popup_speciesOrganismWindow(AW_root *aw_root, GBDATA *gb_main, bool organismWindow) { | 
|---|
| 1425 | int windowIdx = (int)organismWindow; | 
|---|
| 1426 |  | 
|---|
| 1427 | static AW_window *AWS[2] = { 0, 0 }; | 
|---|
| 1428 | if (!AWS[windowIdx]) { | 
|---|
| 1429 | AWS[windowIdx] = popup_new_speciesOrganismWindow(aw_root, gb_main, organismWindow, InfoWindow::MAIN_WINDOW); | 
|---|
| 1430 | } | 
|---|
| 1431 | else { | 
|---|
| 1432 | AWS[windowIdx]->activate(); | 
|---|
| 1433 | } | 
|---|
| 1434 | } | 
|---|
| 1435 |  | 
|---|
| 1436 | void DBUI::popup_species_info_window (AW_root *aw_root, GBDATA *gb_main) { popup_speciesOrganismWindow(aw_root, gb_main, false); } | 
|---|
| 1437 | void DBUI::popup_organism_info_window(AW_root *aw_root, GBDATA *gb_main) { popup_speciesOrganismWindow(aw_root, gb_main, true);  } | 
|---|
| 1438 |  | 
|---|
| 1439 | static DbQuery *GLOBAL_species_query = NULL; // @@@ fix design | 
|---|
| 1440 |  | 
|---|
| 1441 | void DBUI::unquery_all() { | 
|---|
| 1442 | QUERY::unquery_all(0, GLOBAL_species_query); | 
|---|
| 1443 | } | 
|---|
| 1444 |  | 
|---|
| 1445 | void DBUI::query_update_list() { | 
|---|
| 1446 | DbQuery_update_list(GLOBAL_species_query); | 
|---|
| 1447 | } | 
|---|
| 1448 |  | 
|---|
| 1449 | AW_window *DBUI::create_species_query_window(AW_root *aw_root, GBDATA *gb_main) { | 
|---|
| 1450 | static AW_window_simple_menu *aws = 0; | 
|---|
| 1451 | if (!aws) { | 
|---|
| 1452 | aws = new AW_window_simple_menu; | 
|---|
| 1453 | aws->init(aw_root, "SPECIES_QUERY", "SEARCH and QUERY"); | 
|---|
| 1454 | aws->create_menu("More functions", "f"); | 
|---|
| 1455 | aws->load_xfig("ad_query.fig"); | 
|---|
| 1456 |  | 
|---|
| 1457 |  | 
|---|
| 1458 | query_spec awtqs(SPECIES_get_selector()); | 
|---|
| 1459 |  | 
|---|
| 1460 | awtqs.gb_main             = gb_main; | 
|---|
| 1461 | awtqs.species_name        = AWAR_SPECIES_NAME; | 
|---|
| 1462 | awtqs.tree_name           = AWAR_TREE; | 
|---|
| 1463 | awtqs.select_bit          = GB_USERFLAG_QUERY; | 
|---|
| 1464 | awtqs.use_menu            = 1; | 
|---|
| 1465 | awtqs.ere_pos_fig         = "ere2"; | 
|---|
| 1466 | awtqs.by_pos_fig          = "by2"; | 
|---|
| 1467 | awtqs.qbox_pos_fig        = "qbox"; | 
|---|
| 1468 | awtqs.rescan_pos_fig      = 0; | 
|---|
| 1469 | awtqs.key_pos_fig         = 0; | 
|---|
| 1470 | awtqs.query_pos_fig       = "content"; | 
|---|
| 1471 | awtqs.result_pos_fig      = "result"; | 
|---|
| 1472 | awtqs.count_pos_fig       = "count"; | 
|---|
| 1473 | awtqs.do_query_pos_fig    = "doquery"; | 
|---|
| 1474 | awtqs.config_pos_fig      = "doconfig"; | 
|---|
| 1475 | awtqs.do_mark_pos_fig     = "domark"; | 
|---|
| 1476 | awtqs.do_unmark_pos_fig   = "dounmark"; | 
|---|
| 1477 | awtqs.do_delete_pos_fig   = "dodelete"; | 
|---|
| 1478 | awtqs.do_set_pos_fig      = "doset"; | 
|---|
| 1479 | awtqs.do_refresh_pos_fig  = "dorefresh"; | 
|---|
| 1480 | awtqs.open_parser_pos_fig = "openparser"; | 
|---|
| 1481 | awtqs.popup_info_window   = popup_species_info_window; | 
|---|
| 1482 |  | 
|---|
| 1483 | DbQuery *query           = create_query_box(aws, &awtqs, "spec"); | 
|---|
| 1484 | GLOBAL_species_query = query; | 
|---|
| 1485 |  | 
|---|
| 1486 | aws->create_menu("More search",     "s"); | 
|---|
| 1487 | aws->insert_menu_topic("spec_search_equal_fields_within_db", "Search For Equal Fields and Mark Duplicates",                "E", "search_duplicates.hlp", AWM_ALL, (AW_CB)search_duplicated_field_content, (AW_CL)query,                                  0); | 
|---|
| 1488 | aws->insert_menu_topic("spec_search_equal_words_within_db",  "Search For Equal Words Between Fields and Mark Duplicates",  "W", "search_duplicates.hlp", AWM_ALL, (AW_CB)search_duplicated_field_content, (AW_CL)query,                                  1); | 
|---|
| 1489 | aws->insert_menu_topic("spec_search_next_relativ_of_sel",    "Search Next Relatives of SELECTED Species in PT_Server ...", "R", 0,                       AWM_ALL, (AW_CB)AW_POPUP,                 (AW_CL)create_next_neighbours_selected_window, (AW_CL)query); | 
|---|
| 1490 | aws->insert_menu_topic("spec_search_next_relativ_of_listed", "Search Next Relatives of LISTED Species in PT_Server ...",   "L", 0,                       AWM_ALL, (AW_CB)AW_POPUP,                 (AW_CL)create_next_neighbours_listed_window,   (AW_CL)query); | 
|---|
| 1491 |  | 
|---|
| 1492 | aws->button_length(7); | 
|---|
| 1493 |  | 
|---|
| 1494 | aws->at("close"); | 
|---|
| 1495 | aws->callback((AW_CB0)AW_POPDOWN); | 
|---|
| 1496 | aws->create_button("CLOSE", "Close", "C"); | 
|---|
| 1497 |  | 
|---|
| 1498 | aws->at("help"); | 
|---|
| 1499 | aws->callback(makeHelpCallback("sp_search.hlp")); | 
|---|
| 1500 | aws->create_button("HELP", "Help", "H"); | 
|---|
| 1501 | } | 
|---|
| 1502 | return aws; | 
|---|
| 1503 | } | 
|---|
| 1504 |  | 
|---|
| 1505 |  | 
|---|