1 | #include <stdio.h> |
---|
2 | #include <stdlib.h> |
---|
3 | #include <unistd.h> |
---|
4 | #include <time.h> |
---|
5 | #include <string.h> |
---|
6 | // #include <malloc.h> |
---|
7 | #include <memory.h> |
---|
8 | #include <sys/stat.h> |
---|
9 | |
---|
10 | #include <arbdb.h> |
---|
11 | #include <arbdbt.h> |
---|
12 | #include <ad_config.h> |
---|
13 | #include <aw_root.hxx> |
---|
14 | #include <aw_device.hxx> |
---|
15 | #include <aw_window.hxx> |
---|
16 | #include <aw_awars.hxx> |
---|
17 | #include <aw_global.hxx> |
---|
18 | #include "awt.hxx" |
---|
19 | #include "awtlocal.hxx" |
---|
20 | #include "awt_sel_boxes.hxx" |
---|
21 | #include "awt_item_sel_list.hxx" |
---|
22 | |
---|
23 | // ******************** selection boxes on alignments ******************** |
---|
24 | |
---|
25 | static void awt_create_selection_list_on_ad_cb(GBDATA *, struct adawcbstruct *cbs) { |
---|
26 | cbs->aws->clear_selection_list(cbs->id); |
---|
27 | |
---|
28 | for (GBDATA * gb_alignment = GB_search(cbs->gb_main, "presets/alignment", GB_FIND); |
---|
29 | gb_alignment; |
---|
30 | gb_alignment = GB_nextEntry(gb_alignment)) |
---|
31 | { |
---|
32 | char *alignment_type = GBT_read_string(gb_alignment, "alignment_type"); |
---|
33 | char *alignment_name = GBT_read_string(gb_alignment, "alignment_name"); |
---|
34 | char *str = GBS_string_eval(alignment_type, cbs->comm, 0); |
---|
35 | |
---|
36 | if (!*str) { |
---|
37 | cbs->aws->insert_selection(cbs->id, alignment_name, alignment_name); |
---|
38 | } |
---|
39 | free(str); |
---|
40 | free(alignment_type); |
---|
41 | free(alignment_name); |
---|
42 | } |
---|
43 | cbs->aws->insert_default_selection(cbs->id, "????", "????"); |
---|
44 | cbs->aws->update_selection_list(cbs->id); |
---|
45 | } |
---|
46 | |
---|
47 | |
---|
48 | void awt_create_selection_list_on_ad(GBDATA *gb_main,AW_window *aws, const char *varname,const char *comm) |
---|
49 | // if comm is set then only those alignments are taken |
---|
50 | // which can be parsed by comm |
---|
51 | { |
---|
52 | AW_selection_list *id; |
---|
53 | GBDATA *gb_presets; |
---|
54 | |
---|
55 | GB_push_transaction(gb_main); |
---|
56 | |
---|
57 | id = aws->create_selection_list(varname,0,"",20,3); |
---|
58 | struct adawcbstruct *cbs = new adawcbstruct; |
---|
59 | memset(cbs, 0, sizeof(*cbs)); |
---|
60 | |
---|
61 | cbs->aws = aws; |
---|
62 | cbs->awr = aws->get_root(); |
---|
63 | cbs->gb_main = gb_main; |
---|
64 | cbs->id = id; |
---|
65 | cbs->comm = 0; if (comm) cbs->comm = strdup(comm); |
---|
66 | |
---|
67 | awt_create_selection_list_on_ad_cb(0,cbs); |
---|
68 | |
---|
69 | gb_presets = GB_search(gb_main,"presets",GB_CREATE_CONTAINER); |
---|
70 | GB_add_callback(gb_presets,GB_CB_CHANGED, (GB_CB)awt_create_selection_list_on_ad_cb, (int *)cbs); |
---|
71 | |
---|
72 | GB_pop_transaction(gb_main); |
---|
73 | } |
---|
74 | |
---|
75 | |
---|
76 | // ******************** selection boxes on trees ******************** |
---|
77 | |
---|
78 | void awt_create_selection_list_on_trees_cb(GBDATA *dummy, struct adawcbstruct *cbs) { |
---|
79 | AWUSE(dummy); |
---|
80 | |
---|
81 | cbs->aws->clear_selection_list(cbs->id); |
---|
82 | char **tree_names = GBT_get_tree_names(cbs->gb_main); |
---|
83 | if (tree_names) { |
---|
84 | int maxTreeNameLen = 0; |
---|
85 | for (char **tree= tree_names ; *tree; tree++){ |
---|
86 | int len = strlen(*tree); |
---|
87 | if (len>maxTreeNameLen) maxTreeNameLen = len; |
---|
88 | } |
---|
89 | for (char **tree= tree_names ; *tree; tree++){ |
---|
90 | const char *info = GBT_tree_info_string(cbs->gb_main, *tree, maxTreeNameLen); |
---|
91 | if (info) { |
---|
92 | cbs->aws->insert_selection( cbs->id, info, *tree ); |
---|
93 | } else { |
---|
94 | cbs->aws->insert_selection( cbs->id, *tree, *tree ); |
---|
95 | } |
---|
96 | } |
---|
97 | GBT_free_names(tree_names); |
---|
98 | } |
---|
99 | cbs->aws->insert_default_selection( cbs->id, "????", "????" ); |
---|
100 | cbs->aws->update_selection_list( cbs->id ); |
---|
101 | } |
---|
102 | |
---|
103 | void awt_create_selection_list_on_trees(GBDATA *gb_main,AW_window *aws,const char *varname) { |
---|
104 | AW_selection_list *id; |
---|
105 | GBDATA *gb_tree_data; |
---|
106 | |
---|
107 | GB_push_transaction(gb_main); |
---|
108 | |
---|
109 | id = aws->create_selection_list(varname,0,"",40,4); |
---|
110 | struct adawcbstruct *cbs = new adawcbstruct; |
---|
111 | memset(cbs, 0, sizeof(*cbs)); |
---|
112 | |
---|
113 | cbs->aws = aws; |
---|
114 | cbs->awr = aws->get_root(); |
---|
115 | cbs->gb_main = gb_main; |
---|
116 | cbs->id = id; |
---|
117 | |
---|
118 | awt_create_selection_list_on_trees_cb(0,cbs); |
---|
119 | |
---|
120 | gb_tree_data = GB_search(gb_main,"tree_data",GB_CREATE_CONTAINER); |
---|
121 | GB_add_callback(gb_tree_data,GB_CB_CHANGED, (GB_CB)awt_create_selection_list_on_trees_cb, (int *)cbs); |
---|
122 | |
---|
123 | GB_pop_transaction(gb_main); |
---|
124 | } |
---|
125 | |
---|
126 | // ******************** selection boxes on pt-servers ******************** |
---|
127 | |
---|
128 | #define PT_SERVERNAME_LENGTH 23 // that's for buttons |
---|
129 | #define PT_SERVERNAME_SELLIST_WIDTH 30 // this for lists |
---|
130 | #define PT_SERVER_TRACKLOG_TIMER 10000 // every 10 seconds |
---|
131 | |
---|
132 | struct selection_list_handle { |
---|
133 | AW_window *aws; |
---|
134 | AW_selection_list *sellst; |
---|
135 | struct selection_list_handle *next; |
---|
136 | }; |
---|
137 | |
---|
138 | static selection_list_handle *allPTserverSellists = 0; // all pt server selection lists |
---|
139 | |
---|
140 | static void fill_pt_server_selection_list(AW_window *aws, AW_selection_list *id) { |
---|
141 | aws->clear_selection_list(id); |
---|
142 | |
---|
143 | const char * const *pt_servers = GBS_get_arb_tcp_entries("ARB_PT_SERVER*"); |
---|
144 | |
---|
145 | int count = 0; |
---|
146 | while (pt_servers[count]) count++; |
---|
147 | |
---|
148 | for (int i=0; i<count; i++) { |
---|
149 | char *choice = GBS_ptserver_id_to_choice(i, 1); |
---|
150 | if (!choice) { |
---|
151 | aw_message(GB_await_error()); |
---|
152 | break; |
---|
153 | } |
---|
154 | aws->insert_selection(id,choice,(long)i); |
---|
155 | free(choice); |
---|
156 | } |
---|
157 | |
---|
158 | aws->insert_default_selection(id, "-undefined-", (long)-1); |
---|
159 | aws->update_selection_list(id); |
---|
160 | } |
---|
161 | |
---|
162 | void awt_refresh_all_pt_server_selection_lists() { |
---|
163 | // refresh content of all PT_server selection lists |
---|
164 | selection_list_handle *serverList = allPTserverSellists; |
---|
165 | |
---|
166 | while (serverList) { |
---|
167 | fill_pt_server_selection_list(serverList->aws, serverList->sellst); |
---|
168 | serverList = serverList->next; |
---|
169 | } |
---|
170 | } |
---|
171 | |
---|
172 | static void track_log_cb(AW_root *awr) { |
---|
173 | static long last_ptserverlog_mod = 0; |
---|
174 | const char *ptserverlog = GBS_ptserver_logname(); |
---|
175 | long ptserverlog_mod = GB_time_of_file(ptserverlog); |
---|
176 | |
---|
177 | if (ptserverlog_mod != last_ptserverlog_mod) { |
---|
178 | #if defined(DEBUG) |
---|
179 | fprintf(stderr, "%s modified!\n", ptserverlog); |
---|
180 | #endif // DEBUG |
---|
181 | awt_refresh_all_pt_server_selection_lists(); |
---|
182 | last_ptserverlog_mod = ptserverlog_mod; |
---|
183 | } |
---|
184 | |
---|
185 | awr->add_timed_callback(PT_SERVER_TRACKLOG_TIMER, track_log_cb); |
---|
186 | } |
---|
187 | |
---|
188 | static void announce_pt_server_selection_list(AW_window *aws, AW_selection_list *id) { |
---|
189 | #if defined(DEBUG) |
---|
190 | selection_list_handle *serverList = allPTserverSellists; |
---|
191 | while (serverList) { |
---|
192 | awt_assert(aws != serverList->aws || id != serverList->sellst); // oops - added twice |
---|
193 | serverList = serverList->next; |
---|
194 | } |
---|
195 | #endif // DEBUG |
---|
196 | |
---|
197 | if (!allPTserverSellists) { // first pt server selection list -> install log tracker |
---|
198 | aws->get_root()->add_timed_callback(PT_SERVER_TRACKLOG_TIMER, track_log_cb); |
---|
199 | } |
---|
200 | |
---|
201 | selection_list_handle *newServerList = (selection_list_handle *)malloc(sizeof(*newServerList)); |
---|
202 | |
---|
203 | newServerList->aws = aws; |
---|
204 | newServerList->sellst = id; |
---|
205 | newServerList->next = allPTserverSellists; |
---|
206 | |
---|
207 | allPTserverSellists = newServerList; |
---|
208 | } |
---|
209 | |
---|
210 | // -------------------------------------------------------------------------------- |
---|
211 | |
---|
212 | static char *readable_pt_servername(int index, int maxlength) { |
---|
213 | char *fullname = GBS_ptserver_id_to_choice(index, 0); |
---|
214 | if (!fullname) { |
---|
215 | #ifdef DEBUG |
---|
216 | printf("awar given to awt_create_selection_list_on_pt_servers() does not contain a valid index\n"); |
---|
217 | #endif |
---|
218 | // awt_assert(0); // awar given to awt_create_selection_list_on_pt_servers() does not contain a valid index |
---|
219 | return strdup("-undefined-"); |
---|
220 | } |
---|
221 | |
---|
222 | int len = strlen(fullname); |
---|
223 | if (len <= maxlength) { |
---|
224 | return fullname; |
---|
225 | } |
---|
226 | |
---|
227 | int remove = len-maxlength; |
---|
228 | fullname[0] = '.'; |
---|
229 | fullname[1] = '.'; |
---|
230 | strcpy(fullname+2, fullname+2+remove); |
---|
231 | |
---|
232 | return fullname; |
---|
233 | } |
---|
234 | |
---|
235 | static void update_ptserver_button(AW_root *aw_root, AW_CL cl_varname) { |
---|
236 | const char *varname = (const char *)cl_varname; |
---|
237 | char *awar_buttontext_name = GBS_global_string_copy("/tmp/%s_BUTTON", varname); |
---|
238 | char *readable_name = readable_pt_servername(aw_root->awar(varname)->read_int(), PT_SERVERNAME_LENGTH); |
---|
239 | |
---|
240 | aw_root->awar(awar_buttontext_name)->write_string(readable_name); |
---|
241 | |
---|
242 | free(readable_name); |
---|
243 | free(awar_buttontext_name); |
---|
244 | } |
---|
245 | |
---|
246 | AW_window *awt_popup_selection_list_on_pt_servers(AW_root *aw_root, const char *varname) { |
---|
247 | AW_window_simple *aw_popup = new AW_window_simple; |
---|
248 | |
---|
249 | aw_popup->init(aw_root, "SELECT_PT_SERVER", "Select a PT-Server"); |
---|
250 | aw_popup->auto_space(10, 10); |
---|
251 | |
---|
252 | aw_popup->at_newline(); |
---|
253 | aw_popup->callback((AW_CB0)AW_POPDOWN); |
---|
254 | AW_selection_list *id = aw_popup->create_selection_list(varname, 0, "", PT_SERVERNAME_SELLIST_WIDTH, 20); |
---|
255 | |
---|
256 | aw_popup->at_newline(); |
---|
257 | aw_popup->callback((AW_CB0)AW_POPDOWN); |
---|
258 | aw_popup->create_button("CLOSE", "CLOSE", "C"); |
---|
259 | |
---|
260 | aw_popup->window_fit(); |
---|
261 | |
---|
262 | announce_pt_server_selection_list(aw_popup, id); |
---|
263 | fill_pt_server_selection_list(aw_popup, id); |
---|
264 | |
---|
265 | return aw_popup; |
---|
266 | } |
---|
267 | |
---|
268 | void awt_create_selection_list_on_pt_servers(AW_window *aws, const char *varname, bool popup) |
---|
269 | { |
---|
270 | if (popup) { |
---|
271 | AW_root *aw_root = aws->get_root(); |
---|
272 | char *awar_buttontext_name = GBS_global_string_copy("/tmp/%s_BUTTON", varname); |
---|
273 | int ptserver_index = aw_root->awar(varname)->read_int(); |
---|
274 | |
---|
275 | if (ptserver_index<0) { // fix invalid pt_server indices |
---|
276 | ptserver_index = 0; |
---|
277 | aw_root->awar(varname)->write_int(ptserver_index); |
---|
278 | } |
---|
279 | |
---|
280 | char *readable_name = readable_pt_servername(ptserver_index, PT_SERVERNAME_LENGTH); |
---|
281 | |
---|
282 | AW_CL cl_varname = (AW_CL)strdup(varname); // make copy of awar_name for callbacks |
---|
283 | |
---|
284 | aw_root->awar_string(awar_buttontext_name, readable_name, AW_ROOT_DEFAULT); |
---|
285 | aw_root->awar(varname)->add_callback(update_ptserver_button, cl_varname); |
---|
286 | |
---|
287 | int old_button_length = aws->get_button_length(); |
---|
288 | |
---|
289 | aws->button_length(PT_SERVERNAME_LENGTH+1); |
---|
290 | aws->callback(AW_POPUP, (AW_CL)awt_popup_selection_list_on_pt_servers, cl_varname); |
---|
291 | aws->create_button("CURR_PT_SERVER", awar_buttontext_name); |
---|
292 | |
---|
293 | aws->button_length(old_button_length); |
---|
294 | |
---|
295 | free(readable_name); |
---|
296 | free(awar_buttontext_name); |
---|
297 | } |
---|
298 | else { |
---|
299 | AW_selection_list *id = aws->create_selection_list(varname); |
---|
300 | announce_pt_server_selection_list(aws, id); |
---|
301 | fill_pt_server_selection_list(aws, id); |
---|
302 | } |
---|
303 | } |
---|
304 | |
---|
305 | |
---|
306 | // ******************** selection boxes on tables ******************** |
---|
307 | |
---|
308 | void awt_create_selection_list_on_tables_cb(GBDATA *dummy, struct awt_sel_list_for_tables *cbs){ |
---|
309 | AWUSE(dummy); |
---|
310 | cbs->aws->clear_selection_list(cbs->id); |
---|
311 | GBDATA *gb_table; |
---|
312 | for (gb_table = GBT_first_table(cbs->gb_main); |
---|
313 | gb_table; |
---|
314 | gb_table = GBT_next_table(gb_table)){ |
---|
315 | |
---|
316 | GBDATA *gb_name = GB_entry(gb_table,"name"); |
---|
317 | GBDATA *gb_description = GB_search(gb_table,"description",GB_STRING); |
---|
318 | if (!gb_name) continue; |
---|
319 | char *table_name = GB_read_string(gb_name); |
---|
320 | char *description = GB_read_string(gb_description); |
---|
321 | const char *info_text = GBS_global_string("%s: %s",table_name,description); |
---|
322 | cbs->aws->insert_selection(cbs->id,info_text,table_name); |
---|
323 | free(table_name); |
---|
324 | free(description); |
---|
325 | } |
---|
326 | cbs->aws->insert_default_selection( cbs->id, "", "" ); |
---|
327 | cbs->aws->update_selection_list( cbs->id ); |
---|
328 | } |
---|
329 | |
---|
330 | void awt_create_selection_list_on_tables(GBDATA *gb_main,AW_window *aws,const char *varname) |
---|
331 | { |
---|
332 | AW_selection_list *id; |
---|
333 | GBDATA *gb_table_data; |
---|
334 | struct awt_sel_list_for_tables *cbs; |
---|
335 | GB_push_transaction(gb_main); |
---|
336 | |
---|
337 | id = aws->create_selection_list(varname,0,"",40,8); |
---|
338 | cbs = new awt_sel_list_for_tables; |
---|
339 | cbs->aws = aws; |
---|
340 | cbs->gb_main = gb_main; |
---|
341 | cbs->id = id; |
---|
342 | |
---|
343 | awt_create_selection_list_on_tables_cb(0,cbs); |
---|
344 | |
---|
345 | gb_table_data = GB_search(gb_main,"table_data",GB_CREATE_CONTAINER); |
---|
346 | GB_add_callback(gb_table_data,GB_CB_CHANGED,(GB_CB)awt_create_selection_list_on_tables_cb, (int *)cbs); |
---|
347 | |
---|
348 | GB_pop_transaction(gb_main); |
---|
349 | } |
---|
350 | // ******************** selection boxes on tables ******************** |
---|
351 | |
---|
352 | void awt_create_selection_list_on_table_fields_cb(GBDATA *dummy, struct awt_sel_list_for_tables *cbs){ |
---|
353 | AWUSE(dummy); |
---|
354 | cbs->aws->clear_selection_list(cbs->id); |
---|
355 | GBDATA *gb_table = GBT_open_table(cbs->gb_main,cbs->table_name, GB_TRUE); // read only |
---|
356 | GBDATA *gb_table_field; |
---|
357 | for (gb_table_field = GBT_first_table_field(gb_table); |
---|
358 | gb_table_field; |
---|
359 | gb_table_field = GBT_next_table_field(gb_table_field)) |
---|
360 | { |
---|
361 | GBDATA *gb_name = GB_entry(gb_table_field,"name"); |
---|
362 | GBDATA *gb_description = GB_search(gb_table_field,"description",GB_STRING); |
---|
363 | if (!gb_name) continue; |
---|
364 | char *table_name = GB_read_string(gb_name); |
---|
365 | char *description = GB_read_string(gb_description); |
---|
366 | const char *info_text = GBS_global_string("%s: %s",table_name,description); |
---|
367 | cbs->aws->insert_selection(cbs->id,info_text,table_name); |
---|
368 | free(table_name); |
---|
369 | free(description); |
---|
370 | } |
---|
371 | cbs->aws->insert_default_selection( cbs->id, "", "" ); |
---|
372 | cbs->aws->update_selection_list( cbs->id ); |
---|
373 | } |
---|
374 | |
---|
375 | void awt_create_selection_list_on_table_fields(GBDATA *gb_main,AW_window *aws,const char *table_name, const char *varname) |
---|
376 | { |
---|
377 | AW_selection_list *id; |
---|
378 | struct awt_sel_list_for_tables *cbs; |
---|
379 | GB_push_transaction(gb_main); |
---|
380 | |
---|
381 | id = aws->create_selection_list(varname,0,"",40,8); |
---|
382 | cbs = new awt_sel_list_for_tables; |
---|
383 | cbs->aws = aws; |
---|
384 | cbs->gb_main = gb_main; |
---|
385 | cbs->id = id; |
---|
386 | cbs->table_name = strdup(table_name); |
---|
387 | |
---|
388 | awt_create_selection_list_on_table_fields_cb(0,cbs); |
---|
389 | |
---|
390 | GBDATA *gb_table = GBT_open_table(gb_main,table_name, GB_TRUE); // read only |
---|
391 | if (gb_table){ |
---|
392 | GB_add_callback(gb_table,GB_CB_CHANGED,(GB_CB)awt_create_selection_list_on_table_fields_cb, (int *)cbs); |
---|
393 | } |
---|
394 | GB_pop_transaction(gb_main); |
---|
395 | } |
---|
396 | |
---|
397 | // ******************** selection boxes on editor configurations ******************** |
---|
398 | |
---|
399 | void awt_create_selection_list_on_configurations_cb(GBDATA*, struct adawcbstruct *cbs) { |
---|
400 | cbs->aws->clear_selection_list(cbs->id); |
---|
401 | |
---|
402 | int config_count; |
---|
403 | char **config = GBT_get_configuration_names_and_count(cbs->gb_main, &config_count); |
---|
404 | |
---|
405 | if (config) { |
---|
406 | for (int c = 0; c<config_count; c++) { |
---|
407 | cbs->aws->insert_selection(cbs->id, config[c], config[c]); |
---|
408 | } |
---|
409 | GBT_free_names(config); |
---|
410 | } |
---|
411 | |
---|
412 | cbs->aws->insert_default_selection(cbs->id, "????", "????"); |
---|
413 | cbs->aws->update_selection_list(cbs->id); |
---|
414 | } |
---|
415 | |
---|
416 | void awt_create_selection_list_on_configurations(GBDATA *gb_main,AW_window *aws,const char *varname) |
---|
417 | { |
---|
418 | AW_selection_list *id; |
---|
419 | GBDATA *gb_configuration_data; |
---|
420 | GB_push_transaction(gb_main); |
---|
421 | |
---|
422 | id = aws->create_selection_list(varname,0,"",40,15); |
---|
423 | |
---|
424 | struct adawcbstruct *cbs = new adawcbstruct; |
---|
425 | memset(cbs, 0, sizeof(*cbs)); |
---|
426 | |
---|
427 | cbs->aws = aws; |
---|
428 | cbs->awr = aws->get_root(); |
---|
429 | cbs->gb_main = gb_main; |
---|
430 | cbs->id = id; |
---|
431 | |
---|
432 | awt_create_selection_list_on_configurations_cb(0,cbs); |
---|
433 | |
---|
434 | gb_configuration_data = GB_search(gb_main,AWAR_CONFIG_DATA,GB_CREATE_CONTAINER); |
---|
435 | GB_add_callback(gb_configuration_data,GB_CB_CHANGED, |
---|
436 | (GB_CB)awt_create_selection_list_on_configurations_cb, (int *)cbs); |
---|
437 | |
---|
438 | GB_pop_transaction(gb_main); |
---|
439 | } |
---|
440 | |
---|
441 | char *awt_create_string_on_configurations(GBDATA *gb_main) { |
---|
442 | // returns semicolon-separated string containing configuration names |
---|
443 | // (or NULL if no configs exist) |
---|
444 | |
---|
445 | GB_push_transaction(gb_main); |
---|
446 | |
---|
447 | int config_count; |
---|
448 | char **config = GBT_get_configuration_names_and_count(gb_main, &config_count); |
---|
449 | char *result = 0; |
---|
450 | |
---|
451 | if (config) { |
---|
452 | GBS_strstruct *out = GBS_stropen(1000); |
---|
453 | for (int c = 0; c<config_count; c++) { |
---|
454 | if (c>0) GBS_chrcat(out, ';'); |
---|
455 | GBS_strcat(out, config[c]); |
---|
456 | } |
---|
457 | result = GBS_strclose(out); |
---|
458 | } |
---|
459 | |
---|
460 | GB_pop_transaction(gb_main); |
---|
461 | return result; |
---|
462 | } |
---|
463 | |
---|
464 | // ******************** selection boxes on SAIs ******************** |
---|
465 | |
---|
466 | void awt_create_selection_list_on_extendeds_update(GBDATA *dummy, void *cbsid) |
---|
467 | { |
---|
468 | #if defined(DEVEL_RALF) |
---|
469 | printf("start awt_create_selection_list_on_extendeds_update\n"); // @@@ |
---|
470 | #endif // DEVEL_RALF |
---|
471 | |
---|
472 | struct awt_sel_list_for_sai *cbs = (struct awt_sel_list_for_sai *)cbsid; |
---|
473 | |
---|
474 | AWUSE(dummy); |
---|
475 | cbs->aws->clear_selection_list(cbs->id); |
---|
476 | GB_transaction ta(cbs->gb_main); |
---|
477 | |
---|
478 | for (GBDATA *gb_extended = GBT_first_SAI(cbs->gb_main); |
---|
479 | gb_extended; |
---|
480 | gb_extended = GBT_next_SAI(gb_extended)) |
---|
481 | { |
---|
482 | if (cbs->filter_poc) { |
---|
483 | char *res = cbs->filter_poc(gb_extended,cbs->filter_cd); |
---|
484 | if (res) { |
---|
485 | cbs->aws->insert_selection( cbs->id, res, GBT_read_name(gb_extended)); |
---|
486 | free(res); |
---|
487 | } |
---|
488 | } |
---|
489 | else { |
---|
490 | const char *name = GBT_read_name(gb_extended); |
---|
491 | GBDATA *gb_group = GB_entry(gb_extended, "sai_group"); |
---|
492 | |
---|
493 | if (gb_group) { |
---|
494 | const char *group = GB_read_char_pntr(gb_group); |
---|
495 | char *group_and_name = GBS_global_string_copy("[%s] %s", group, name); |
---|
496 | |
---|
497 | cbs->aws->insert_selection(cbs->id, group_and_name, name); |
---|
498 | free(group_and_name); |
---|
499 | } |
---|
500 | else { |
---|
501 | cbs->aws->insert_selection( cbs->id, name, name ); |
---|
502 | } |
---|
503 | } |
---|
504 | } |
---|
505 | cbs->aws->sort_selection_list(cbs->id, 0, 0); |
---|
506 | |
---|
507 | if (cbs->add_selected_species) { |
---|
508 | GBDATA *gb_sel = GB_search(cbs->gb_main,AWAR_SPECIES_NAME,GB_STRING); |
---|
509 | char *name = GB_read_string(gb_sel); |
---|
510 | if (strlen(name)){ |
---|
511 | char *sname = (char *)calloc(1, strlen(name)+2); |
---|
512 | sprintf(sname+1,"%s",name); |
---|
513 | sname[0] = 1; |
---|
514 | char *text = (char *)GBS_global_string("Selected Species: '%s'",name); |
---|
515 | cbs->aws->insert_selection( cbs->id, text, sname ); |
---|
516 | delete name; |
---|
517 | } |
---|
518 | delete name; |
---|
519 | } |
---|
520 | cbs->aws->insert_default_selection( cbs->id, "- none -", "none" ); |
---|
521 | cbs->aws->update_selection_list( cbs->id ); |
---|
522 | |
---|
523 | #if defined(DEVEL_RALF) |
---|
524 | printf("done awt_create_selection_list_on_extendeds_update\n"); // @@@ |
---|
525 | #endif // DEVEL_RALF |
---|
526 | } |
---|
527 | |
---|
528 | void *awt_create_selection_list_on_extendeds(GBDATA *gb_main,AW_window *aws, const char *varname, |
---|
529 | char *(*filter_poc)(GBDATA *gb_ext, AW_CL), AW_CL filter_cd, |
---|
530 | bool add_sel_species) |
---|
531 | { |
---|
532 | AW_selection_list *id; |
---|
533 | struct awt_sel_list_for_sai *cbs; |
---|
534 | |
---|
535 | GB_push_transaction(gb_main); |
---|
536 | |
---|
537 | id = aws->create_selection_list(varname,0,"",40,4); |
---|
538 | cbs = new awt_sel_list_for_sai; |
---|
539 | |
---|
540 | cbs->aws = aws; |
---|
541 | cbs->gb_main = gb_main; |
---|
542 | cbs->id = id; |
---|
543 | cbs->filter_poc = filter_poc; |
---|
544 | cbs->filter_cd = filter_cd; |
---|
545 | cbs->add_selected_species = add_sel_species; |
---|
546 | |
---|
547 | awt_create_selection_list_on_extendeds_update(0,(void *)cbs); |
---|
548 | |
---|
549 | GBDATA *gb_sai_data = GBT_get_SAI_data(gb_main); |
---|
550 | GB_add_callback(gb_sai_data,GB_CB_CHANGED, (GB_CB)awt_create_selection_list_on_extendeds_update, (int *)cbs); |
---|
551 | |
---|
552 | if (add_sel_species){ // update box if another species is selected |
---|
553 | GBDATA *gb_sel = GB_search(gb_main,AWAR_SPECIES_NAME,GB_STRING); |
---|
554 | GB_add_callback(gb_sel,GB_CB_CHANGED, (GB_CB)awt_create_selection_list_on_extendeds_update, (int *)cbs); |
---|
555 | } |
---|
556 | GB_pop_transaction(gb_main); |
---|
557 | |
---|
558 | return (void *)cbs; |
---|
559 | } |
---|
560 | |
---|
561 | |
---|
562 | |
---|
563 | |
---|
564 | // ******************** selection boxes on saving selection lists ******************** |
---|
565 | |
---|
566 | void create_save_box_for_selection_lists_save(AW_window *aws,AW_CL selidcd,AW_CL basenamecd) |
---|
567 | { |
---|
568 | AW_selection_list *selid = (AW_selection_list *)selidcd; |
---|
569 | char *awar_prefix = (char *)basenamecd; |
---|
570 | |
---|
571 | char bline_anz[GB_PATH_MAX]; |
---|
572 | sprintf(bline_anz,"%s/line_anz",awar_prefix); |
---|
573 | |
---|
574 | AW_root *aw_root = aws->get_root(); |
---|
575 | long lineanz = aw_root->awar(bline_anz)->read_int(); |
---|
576 | char *filename = awt_get_selected_fullname(aw_root, awar_prefix); |
---|
577 | |
---|
578 | GB_ERROR error = aws->save_selection_list(selid,filename,lineanz); |
---|
579 | |
---|
580 | if (!error) awt_refresh_selection_box(aw_root, awar_prefix); |
---|
581 | aws->hide_or_notify(error); |
---|
582 | free(filename); |
---|
583 | } |
---|
584 | |
---|
585 | AW_window *create_save_box_for_selection_lists(AW_root *aw_root,AW_CL selid) |
---|
586 | { |
---|
587 | AW_selection_list *selection_list = (AW_selection_list*)selid; |
---|
588 | |
---|
589 | char *var_id = GBS_string_2_key(selection_list->variable_name); |
---|
590 | char *awar_base_name = GBS_global_string_copy("tmp/save_box_sel_%s", var_id); // don't free (passed to callback) |
---|
591 | char *awar_line_anz = GBS_global_string_copy("%s/line_anz", awar_base_name); |
---|
592 | { |
---|
593 | aw_create_selection_box_awars(aw_root, awar_base_name, ".", GBS_global_string("noname.list"), "list"); |
---|
594 | aw_root->awar_int(awar_line_anz, 0, AW_ROOT_DEFAULT); |
---|
595 | } |
---|
596 | |
---|
597 | AW_window_simple *aws = new AW_window_simple; |
---|
598 | char *window_id = GBS_global_string_copy("SAVE_SELECTION_BOX_%s", var_id); |
---|
599 | |
---|
600 | aws->init(aw_root, window_id, "SAVE BOX"); |
---|
601 | aws->load_xfig("sl_s_box.fig"); |
---|
602 | |
---|
603 | aws->at("close");aws->callback((AW_CB0)AW_POPDOWN); |
---|
604 | aws->create_button("CLOSE", "CLOSE","C"); |
---|
605 | |
---|
606 | aws->at("save"); |
---|
607 | aws->highlight(); |
---|
608 | aws->callback(create_save_box_for_selection_lists_save,selid,(AW_CL)awar_base_name); // loose ownership of awar_base_name! |
---|
609 | aws->create_button("SAVE", "SAVE","S"); |
---|
610 | |
---|
611 | aws->at("nlines"); |
---|
612 | aws->create_option_menu(awar_line_anz, 0, ""); |
---|
613 | aws->insert_default_option("all","a",0); |
---|
614 | aws->insert_option( "50", "a", 50); |
---|
615 | aws->insert_option( "100", "a", 100); |
---|
616 | aws->insert_option( "500", "a", 500); |
---|
617 | aws->insert_option( "1000", "a", 1000); |
---|
618 | aws->insert_option( "5000", "a", 5000); |
---|
619 | aws->insert_option("10000", "a", 10000); |
---|
620 | aws->update_option_menu(); |
---|
621 | |
---|
622 | awt_create_selection_box(aws,awar_base_name); |
---|
623 | |
---|
624 | free(window_id); |
---|
625 | free(awar_line_anz); |
---|
626 | free(var_id); |
---|
627 | |
---|
628 | return aws; |
---|
629 | } |
---|
630 | |
---|
631 | void AWT_load_list(AW_window *aww, AW_CL sel_id, AW_CL ibase_name) |
---|
632 | { |
---|
633 | AW_selection_list * selid = (AW_selection_list *)sel_id; |
---|
634 | char *basename = (char *)ibase_name; |
---|
635 | |
---|
636 | AW_root *aw_root = aww->get_root(); |
---|
637 | GB_ERROR error; |
---|
638 | |
---|
639 | // char bfile_name[GB_PATH_MAX]; |
---|
640 | // sprintf(bfile_name,"%s/file_name",basename); |
---|
641 | // char *filename = aw_root->awar(bfile_name)->read_string(); |
---|
642 | |
---|
643 | char *filename = awt_get_selected_fullname(aw_root, basename); |
---|
644 | error = aww->load_selection_list(selid,filename); |
---|
645 | |
---|
646 | if (error) aw_message(error); |
---|
647 | |
---|
648 | AW_POPDOWN(aww); |
---|
649 | |
---|
650 | delete filename; |
---|
651 | } |
---|
652 | |
---|
653 | AW_window *create_load_box_for_selection_lists(AW_root *aw_root, AW_CL selid) |
---|
654 | { |
---|
655 | char base_name[100]; |
---|
656 | sprintf(base_name,"tmp/load_box_sel_%li",(long)selid); |
---|
657 | |
---|
658 | aw_create_selection_box_awars(aw_root, base_name, ".", "list", ""); |
---|
659 | |
---|
660 | AW_window_simple *aws = new AW_window_simple; |
---|
661 | aws->init( aw_root, "LOAD_SELECTION_BOX", "Load box"); |
---|
662 | aws->load_xfig("sl_l_box.fig"); |
---|
663 | |
---|
664 | aws->at("close"); |
---|
665 | aws->callback((AW_CB0)AW_POPDOWN); |
---|
666 | aws->create_button("CLOSE", "CLOSE","C"); |
---|
667 | |
---|
668 | aws->at("load"); |
---|
669 | aws->highlight(); |
---|
670 | aws->callback(AWT_load_list,selid,(AW_CL)strdup(base_name)); |
---|
671 | aws->create_button("LOAD", "LOAD","L"); |
---|
672 | |
---|
673 | awt_create_selection_box((AW_window *)aws,base_name); |
---|
674 | return (AW_window*) aws; |
---|
675 | } |
---|
676 | |
---|
677 | |
---|
678 | void create_print_box_for_selection_lists(AW_window *aw_window,AW_CL selid){ |
---|
679 | AW_root *aw_root = aw_window->get_root(); |
---|
680 | char *data = aw_window->get_selection_list_contents((AW_selection_list *)selid); |
---|
681 | AWT_create_ascii_print_window(aw_root,data,"no title"); |
---|
682 | delete data; |
---|
683 | } |
---|
684 | |
---|
685 | |
---|
686 | |
---|
687 | /* ************************************************** */ |
---|
688 | AW_window *awt_create_load_box(AW_root *aw_root, const char *load_what, const char *file_extension, char **set_file_name_awar, |
---|
689 | void (*callback)(AW_window*), |
---|
690 | AW_window* (*create_popup)(AW_root *, AW_default)) |
---|
691 | |
---|
692 | /* You can either provide a normal callback or a create_popup-callback |
---|
693 | * (the not-used callback has to be 0) |
---|
694 | */ |
---|
695 | |
---|
696 | |
---|
697 | { |
---|
698 | char *base_name = GBS_global_string_copy("tmp/load_box_%s",load_what); |
---|
699 | |
---|
700 | aw_create_selection_box_awars(aw_root, base_name, ".", file_extension, ""); |
---|
701 | |
---|
702 | if (set_file_name_awar) { |
---|
703 | *set_file_name_awar = GBS_global_string_copy("%s/file_name", base_name); |
---|
704 | } |
---|
705 | |
---|
706 | AW_window_simple *aws = new AW_window_simple; |
---|
707 | { |
---|
708 | char title[100]; |
---|
709 | sprintf(title, "Load %s", load_what); |
---|
710 | aws->init( aw_root, title, title); |
---|
711 | aws->load_xfig("load_box.fig"); |
---|
712 | } |
---|
713 | |
---|
714 | aws->at("close"); |
---|
715 | aws->callback((AW_CB0)AW_POPDOWN); |
---|
716 | aws->create_button("CLOSE", "CLOSE","C"); |
---|
717 | |
---|
718 | aws->at("help"); |
---|
719 | aws->callback(AW_POPUP_HELP,(AW_CL)""); |
---|
720 | aws->create_button("HELP","HELP"); |
---|
721 | |
---|
722 | aws->at("go"); |
---|
723 | aws->highlight(); |
---|
724 | |
---|
725 | if (callback) { |
---|
726 | awt_assert(!create_popup); |
---|
727 | aws->callback((AW_CB0)callback); |
---|
728 | } |
---|
729 | else { |
---|
730 | awt_assert(create_popup); |
---|
731 | aws->callback((AW_CB1)AW_POPUP, (AW_CL)create_popup); |
---|
732 | } |
---|
733 | |
---|
734 | aws->create_button("LOAD", "LOAD","L"); |
---|
735 | |
---|
736 | awt_create_selection_box((AW_window *)aws,base_name); |
---|
737 | free(base_name); |
---|
738 | return (AW_window*) aws; |
---|
739 | } |
---|
740 | |
---|
741 | /* ************************************************** */ |
---|
742 | |
---|
743 | |
---|
744 | |
---|
745 | void awt_set_long(AW_window *aws, AW_CL varname, AW_CL value) // set an awar |
---|
746 | { |
---|
747 | aws->get_root()->awar((char *)varname)->write_int((long) value); |
---|
748 | } |
---|
749 | |
---|
750 | void awt_write_string( AW_window *aws, AW_CL varname, AW_CL value) // set an awar |
---|
751 | { |
---|
752 | aws->get_root()->awar((char *)varname)->write_string((char *)value); |
---|
753 | } |
---|
754 | |
---|
755 | struct fileChanged_cb_data { |
---|
756 | char *fpath; // full name of edited file |
---|
757 | int lastModtime; // last known modification time of 'fpath' |
---|
758 | bool editorTerminated; // do not free before this has been set to 'true' |
---|
759 | awt_fileChanged_cb callback; |
---|
760 | |
---|
761 | fileChanged_cb_data(char **fpath_ptr, awt_fileChanged_cb cb) { |
---|
762 | fpath = *fpath_ptr; |
---|
763 | *fpath_ptr = 0; // take ownage |
---|
764 | lastModtime = getModtime(); |
---|
765 | editorTerminated = false; |
---|
766 | callback = cb; |
---|
767 | } |
---|
768 | |
---|
769 | ~fileChanged_cb_data() { |
---|
770 | free(fpath); |
---|
771 | } |
---|
772 | |
---|
773 | int getModtime() { |
---|
774 | struct stat st; |
---|
775 | if (stat(fpath, &st) == 0) return st.st_mtime; |
---|
776 | return 0; |
---|
777 | } |
---|
778 | |
---|
779 | bool fileWasChanged() { |
---|
780 | int modtime = getModtime(); |
---|
781 | bool changed = modtime != lastModtime; |
---|
782 | lastModtime = modtime; |
---|
783 | return changed; |
---|
784 | } |
---|
785 | }; |
---|
786 | |
---|
787 | static void editor_terminated_cb(const char *IF_DEBUG(message), void *cb_data) { |
---|
788 | fileChanged_cb_data *data = (fileChanged_cb_data*)cb_data; |
---|
789 | |
---|
790 | #if defined(DEBUG) |
---|
791 | printf("editor_terminated_cb: message='%s' fpath='%s'\n", message, data->fpath); |
---|
792 | #endif // DEBUG |
---|
793 | |
---|
794 | data->callback(data->fpath, data->fileWasChanged(), true); |
---|
795 | data->editorTerminated = true; // trigger removal of check_file_changed_cb |
---|
796 | } |
---|
797 | |
---|
798 | #define AWT_CHECK_FILE_TIMER 700 // in ms |
---|
799 | |
---|
800 | static void check_file_changed_cb(AW_root *aw_root, AW_CL cl_cbdata) { |
---|
801 | fileChanged_cb_data *data = (fileChanged_cb_data*)cl_cbdata; |
---|
802 | |
---|
803 | if (data->editorTerminated) { |
---|
804 | delete data; |
---|
805 | } |
---|
806 | else { |
---|
807 | bool changed = data->fileWasChanged(); |
---|
808 | |
---|
809 | if (changed) data->callback(data->fpath, true, false); |
---|
810 | aw_root->add_timed_callback(AWT_CHECK_FILE_TIMER, check_file_changed_cb, cl_cbdata); |
---|
811 | } |
---|
812 | } |
---|
813 | |
---|
814 | void AWT_edit(const char *path, awt_fileChanged_cb callback, AW_window *aww, GBDATA *gb_main) { |
---|
815 | // Start external editor on file 'path' (asynchronously) |
---|
816 | // if 'callback' is specified, it is called everytime the file is changed |
---|
817 | // [aww and gb_main may be 0 if callback is 0] |
---|
818 | |
---|
819 | const char *editor = GB_getenvARB_TEXTEDIT(); |
---|
820 | char *fpath = GBS_eval_env(path); |
---|
821 | char *command = 0; |
---|
822 | fileChanged_cb_data *cb_data = 0; |
---|
823 | GB_ERROR error = 0; |
---|
824 | |
---|
825 | if (callback) { |
---|
826 | awt_assert(aww); |
---|
827 | awt_assert(gb_main); |
---|
828 | |
---|
829 | cb_data = new fileChanged_cb_data(&fpath, callback); // fpath now is 0 and belongs to cb_data |
---|
830 | |
---|
831 | char *arb_notify = GB_generate_notification(gb_main, editor_terminated_cb, "editor terminated", (void*)cb_data); |
---|
832 | if (!arb_notify) error = GB_await_error(); |
---|
833 | else { |
---|
834 | char *arb_message = GBS_global_string_copy("arb_message \"Could not start editor '%s'\"", editor); |
---|
835 | |
---|
836 | command = GBS_global_string_copy("((%s %s || %s); %s)&", editor, cb_data->fpath, arb_message, arb_notify); |
---|
837 | free(arb_message); |
---|
838 | free(arb_notify); |
---|
839 | } |
---|
840 | } |
---|
841 | else { |
---|
842 | command = GBS_global_string_copy("%s %s &", editor, fpath); |
---|
843 | } |
---|
844 | |
---|
845 | if (command) { |
---|
846 | awt_assert(!error); |
---|
847 | error = GB_system(command); |
---|
848 | if (error) { |
---|
849 | aw_message(error); error = NULL; |
---|
850 | if (callback) error = GB_remove_last_notification(gb_main); |
---|
851 | } |
---|
852 | else { // successfully started editor |
---|
853 | // Can't be sure editor really started when callback is used (see command above). |
---|
854 | // But it doesn't matter, cause arb_notify is called anyway and removes all callbacks |
---|
855 | if (callback) { |
---|
856 | // add timed callback tracking file change |
---|
857 | AW_root *aw_root = aww->get_root(); |
---|
858 | aw_root->add_timed_callback(AWT_CHECK_FILE_TIMER, check_file_changed_cb, (AW_CL)cb_data); |
---|
859 | cb_data = 0; // now belongs to check_file_changed_cb |
---|
860 | } |
---|
861 | } |
---|
862 | } |
---|
863 | |
---|
864 | if (error) aw_message(error); |
---|
865 | |
---|
866 | free(command); |
---|
867 | delete cb_data; |
---|
868 | free(fpath); |
---|
869 | } |
---|
870 | |
---|
871 | |
---|
872 | void AWT_popup_select_species_field_window(AW_window *aww, AW_CL cl_awar_name, AW_CL cl_gb_main) |
---|
873 | { |
---|
874 | static AW_window_simple *aws = 0; |
---|
875 | |
---|
876 | // everytime map selection awar to latest user awar: |
---|
877 | AW_root *aw_root = aww->get_root(); |
---|
878 | const char *awar_name = (const char *)cl_awar_name; |
---|
879 | aw_root->awar("tmp/viewkeys/key_text_select")->map(awar_name); |
---|
880 | |
---|
881 | if (!aws) { |
---|
882 | aws = new AW_window_simple; |
---|
883 | |
---|
884 | aws->init( aw_root, "SELECT_SPECIES_FIELD", "Select species field"); |
---|
885 | aws->load_xfig("awt/nds_sel.fig"); |
---|
886 | aws->button_length(13); |
---|
887 | |
---|
888 | aws->callback( AW_POPDOWN); |
---|
889 | aws->at("close"); |
---|
890 | aws->create_button("CLOSE", "CLOSE","C"); |
---|
891 | |
---|
892 | awt_create_selection_list_on_scandb((GBDATA *)cl_gb_main, |
---|
893 | aws, |
---|
894 | "tmp/viewkeys/key_text_select", |
---|
895 | AWT_NDS_FILTER, |
---|
896 | "scandb","rescandb", &AWT_species_selector, 20, 10); |
---|
897 | } |
---|
898 | aws->activate(); |
---|
899 | } |
---|
900 | |
---|