1 | #include <stdio.h> |
---|
2 | #include <stdlib.h> |
---|
3 | #include <string.h> |
---|
4 | #include <memory.h> |
---|
5 | // #include <malloc.h> |
---|
6 | #include <math.h> |
---|
7 | |
---|
8 | #include <arbdb.h> |
---|
9 | #include <arbdbt.h> |
---|
10 | |
---|
11 | #include <aw_root.hxx> |
---|
12 | #include <aw_device.hxx> |
---|
13 | #include <aw_keysym.hxx> |
---|
14 | #include <aw_window.hxx> |
---|
15 | #include <aw_preset.hxx> |
---|
16 | |
---|
17 | #include "ed4_class.hxx" |
---|
18 | #include "ed4_awars.hxx" |
---|
19 | #include "ed4_edit_string.hxx" |
---|
20 | #include "ed4_tools.hxx" |
---|
21 | #include "ed4_ProteinViewer.hxx" |
---|
22 | #include "ed4_protein_2nd_structure.hxx" |
---|
23 | |
---|
24 | //#define TEST_REFRESH_FLAG |
---|
25 | |
---|
26 | |
---|
27 | // ----------------------------------------------------------------- |
---|
28 | // Manager static properties (used by manager-constructors) |
---|
29 | // ----------------------------------------------------------------- |
---|
30 | |
---|
31 | // Each manager should either be ED4_P_HORIZONTAL or ED4_P_VERTICAL - never both !!! |
---|
32 | |
---|
33 | ED4_object_specification main_manager_spec = { |
---|
34 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props |
---|
35 | ED4_L_ROOT, // level |
---|
36 | ED4_L_GROUP, // allowed children level |
---|
37 | ED4_L_NO_LEVEL, // handled object |
---|
38 | ED4_L_NO_LEVEL, // restriction level |
---|
39 | 0 // justification value (0 means left-aligned, 1.0 means right-aligned) |
---|
40 | }; |
---|
41 | |
---|
42 | ED4_object_specification device_manager_spec = { |
---|
43 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props |
---|
44 | ED4_L_DEVICE, // level |
---|
45 | (ED4_level)(ED4_L_AREA | ED4_L_SPACER), // allowed children level |
---|
46 | ED4_L_NO_LEVEL, // handled object |
---|
47 | ED4_L_NO_LEVEL, // restriction level |
---|
48 | 0 // justification value (0 means left-aligned) |
---|
49 | }; |
---|
50 | |
---|
51 | ED4_object_specification area_manager_spec = { |
---|
52 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL), // static props |
---|
53 | ED4_L_AREA, // level |
---|
54 | (ED4_level)(ED4_L_MULTI_SPECIES | ED4_L_TREE | ED4_L_SPACER), // allowed children level |
---|
55 | ED4_L_NO_LEVEL, // handled object |
---|
56 | ED4_L_NO_LEVEL, // restriction level |
---|
57 | 0 // justification value (0 means top-aligned) |
---|
58 | }; |
---|
59 | |
---|
60 | ED4_object_specification multi_species_manager_spec = { |
---|
61 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props |
---|
62 | ED4_L_MULTI_SPECIES, // level |
---|
63 | (ED4_level)(ED4_L_SPECIES | ED4_L_GROUP | ED4_L_SPACER), // allowed children level |
---|
64 | ED4_L_NO_LEVEL, // handled object |
---|
65 | ED4_L_NO_LEVEL, // restriction level |
---|
66 | 0 // justification value (0 means left-aligned) |
---|
67 | }; |
---|
68 | |
---|
69 | ED4_object_specification species_manager_spec = { |
---|
70 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL), // static props |
---|
71 | ED4_L_SPECIES, // level |
---|
72 | (ED4_level)(ED4_L_MULTI_SEQUENCE | ED4_L_MULTI_NAME), // allowed children level |
---|
73 | ED4_L_NO_LEVEL, // handled object |
---|
74 | ED4_L_NO_LEVEL, // restriction level |
---|
75 | 0 // justification value (0 means top-aligned) |
---|
76 | }; |
---|
77 | ED4_object_specification multi_sequence_manager_spec = { |
---|
78 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props |
---|
79 | ED4_L_MULTI_SEQUENCE, // level |
---|
80 | ED4_L_SEQUENCE, // allowed children level |
---|
81 | ED4_L_NO_LEVEL, // handled object |
---|
82 | ED4_L_NO_LEVEL, // restriction level |
---|
83 | 0 // justification value (0 means left-aligned) |
---|
84 | }; |
---|
85 | |
---|
86 | ED4_object_specification sequence_manager_spec = { |
---|
87 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL), // static props |
---|
88 | ED4_L_SEQUENCE, // level |
---|
89 | (ED4_level)(ED4_L_SEQUENCE_INFO | ED4_L_SEQUENCE_STRING | |
---|
90 | ED4_L_AA_SEQUENCE_STRING), // allowed children level |
---|
91 | ED4_L_NO_LEVEL, // handled object |
---|
92 | ED4_L_SPECIES, // restriction level |
---|
93 | 0 // justification value (0 means top-aligned) |
---|
94 | }; |
---|
95 | |
---|
96 | ED4_object_specification multi_name_manager_spec = { |
---|
97 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props |
---|
98 | ED4_L_MULTI_NAME, // level |
---|
99 | ED4_L_NAME_MANAGER, // allowed children level |
---|
100 | ED4_L_NO_LEVEL, // handled object |
---|
101 | ED4_L_NO_LEVEL, // restriction level |
---|
102 | 0 // justification value (0 means left-aligned) |
---|
103 | }; |
---|
104 | |
---|
105 | ED4_object_specification name_manager_spec = { |
---|
106 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL), // static props |
---|
107 | ED4_L_NAME_MANAGER, // level |
---|
108 | (ED4_level)(ED4_L_SPECIES_NAME), // allowed children level |
---|
109 | ED4_L_NO_LEVEL, // handled object |
---|
110 | ED4_L_SPECIES, // restriction level |
---|
111 | 0 // justification value (0 means top-aligned) |
---|
112 | }; |
---|
113 | |
---|
114 | ED4_object_specification group_manager_spec = { |
---|
115 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL), // static props |
---|
116 | ED4_L_GROUP, // level |
---|
117 | (ED4_level)(ED4_L_MULTI_SPECIES | ED4_L_BRACKET | ED4_L_DEVICE), // allowed children level |
---|
118 | ED4_L_NO_LEVEL, // handled object |
---|
119 | ED4_L_NO_LEVEL, // restriction level |
---|
120 | 0 // justification value (0 means top-aligned) |
---|
121 | }; |
---|
122 | |
---|
123 | ED4_object_specification root_group_manager_spec = { |
---|
124 | (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL), // static props |
---|
125 | ED4_L_GROUP, // level |
---|
126 | (ED4_level)(ED4_L_DEVICE), // allowed children level |
---|
127 | ED4_L_NO_LEVEL, // handled object |
---|
128 | ED4_L_NO_LEVEL, // restriction level |
---|
129 | 0 // justification value (0 means top-aligned) |
---|
130 | }; |
---|
131 | |
---|
132 | // ---------------------------- |
---|
133 | // ED4_manager methods |
---|
134 | // ---------------------------- |
---|
135 | |
---|
136 | ED4_returncode ED4_manager::rebuild_consensi(ED4_base *start_species, ED4_update_flag update_flag) { |
---|
137 | int i; |
---|
138 | ED4_base *temp_parent; |
---|
139 | ED4_multi_species_manager *multi_species_manager = NULL; |
---|
140 | ED4_group_manager *first_group_manager = NULL; |
---|
141 | |
---|
142 | temp_parent = start_species; |
---|
143 | |
---|
144 | switch (update_flag) { |
---|
145 | case ED4_U_UP: // rebuild consensus from a certain starting point upwards |
---|
146 | while (temp_parent && !(temp_parent->is_area_manager())) { |
---|
147 | if (temp_parent->is_group_manager()) { |
---|
148 | ED4_group_manager *group_manager = temp_parent->to_group_manager(); |
---|
149 | multi_species_manager = group_manager->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager(); |
---|
150 | for (i=0; i<multi_species_manager->children->members(); i++) { |
---|
151 | if (multi_species_manager->children->member(i)->flag.is_consensus) { |
---|
152 | rebuild_consensus(NULL, NULL, multi_species_manager->children->member(i)); |
---|
153 | } |
---|
154 | } |
---|
155 | } |
---|
156 | temp_parent = temp_parent->parent; |
---|
157 | } |
---|
158 | break; |
---|
159 | case ED4_U_UP_DOWN: // only search first groupmanager and update consensi recursively downwards |
---|
160 | while (temp_parent && !(temp_parent->is_area_manager())) { |
---|
161 | if (temp_parent->is_group_manager()){ |
---|
162 | first_group_manager = temp_parent->to_group_manager(); |
---|
163 | } |
---|
164 | temp_parent = temp_parent->parent; |
---|
165 | } |
---|
166 | if (first_group_manager) |
---|
167 | first_group_manager->route_down_hierarchy(NULL, NULL, rebuild_consensus); |
---|
168 | break; |
---|
169 | } |
---|
170 | return ED4_R_OK; |
---|
171 | } |
---|
172 | |
---|
173 | ED4_returncode ED4_manager::check_in_bases(ED4_base *added_base, int start_pos, int end_pos) { |
---|
174 | if (added_base->is_species_manager()) { // add a sequence |
---|
175 | ED4_species_manager *species_manager = added_base->to_species_manager(); |
---|
176 | ED4_terminal *sequence_terminal = species_manager->get_consensus_relevant_terminal(); |
---|
177 | |
---|
178 | if (sequence_terminal) { |
---|
179 | int seq_len; |
---|
180 | char *seq = sequence_terminal->resolve_pointer_to_string_copy(&seq_len); |
---|
181 | ED4_returncode res = check_bases(0, 0, seq, seq_len, start_pos, end_pos); |
---|
182 | free(seq); |
---|
183 | return res; |
---|
184 | } |
---|
185 | } |
---|
186 | |
---|
187 | if (added_base->is_group_manager()) { // add a group |
---|
188 | return check_bases(0, &added_base->to_group_manager()->table(), start_pos, end_pos); |
---|
189 | } |
---|
190 | |
---|
191 | return ED4_R_OK; |
---|
192 | } |
---|
193 | |
---|
194 | ED4_returncode ED4_manager::check_out_bases(ED4_base *subbed_base, int start_pos, int end_pos) { |
---|
195 | if (subbed_base->is_species_manager()) { // sub a sequence |
---|
196 | ED4_species_manager *species_manager = subbed_base->to_species_manager(); |
---|
197 | ED4_terminal *sequence_terminal = species_manager->get_consensus_relevant_terminal(); |
---|
198 | |
---|
199 | if (sequence_terminal) { |
---|
200 | int seq_len; |
---|
201 | char *seq = sequence_terminal->resolve_pointer_to_string_copy(&seq_len); |
---|
202 | ED4_returncode res = check_bases(seq, seq_len, 0, 0, start_pos, end_pos); |
---|
203 | free(seq); |
---|
204 | return res; |
---|
205 | } |
---|
206 | } |
---|
207 | |
---|
208 | if (subbed_base->is_group_manager()) { // sub a group |
---|
209 | return check_bases(&subbed_base->to_group_manager()->table(), 0, start_pos, end_pos); |
---|
210 | } |
---|
211 | |
---|
212 | return ED4_R_OK; |
---|
213 | } |
---|
214 | |
---|
215 | ED4_returncode ED4_manager::check_bases(const char *old_sequence, int old_len, const ED4_base *new_base, int start_pos, int end_pos) { |
---|
216 | if (!new_base) { |
---|
217 | return check_bases(old_sequence, old_len, 0, 0, start_pos, end_pos); |
---|
218 | } |
---|
219 | |
---|
220 | e4_assert(new_base->is_species_manager()); |
---|
221 | |
---|
222 | ED4_species_manager *new_species_manager = new_base->to_species_manager(); |
---|
223 | ED4_terminal *new_sequence_terminal = new_species_manager->get_consensus_relevant_terminal(); |
---|
224 | |
---|
225 | int new_len; |
---|
226 | char *new_sequence = new_sequence_terminal->resolve_pointer_to_string_copy(&new_len); |
---|
227 | |
---|
228 | if (end_pos==-1) { |
---|
229 | ED4_char_table::changed_range(old_sequence, new_sequence, min(old_len, new_len), &start_pos, &end_pos); |
---|
230 | } |
---|
231 | |
---|
232 | ED4_returncode res = check_bases(old_sequence, old_len, new_sequence, new_len, start_pos, end_pos); |
---|
233 | free(new_sequence); |
---|
234 | return res; |
---|
235 | } |
---|
236 | |
---|
237 | ED4_returncode ED4_manager::check_bases_and_rebuild_consensi(const char *old_sequence, int old_len, ED4_base *new_base, |
---|
238 | ED4_update_flag update_flag, int start_pos, int end_pos) |
---|
239 | { |
---|
240 | e4_assert(new_base); |
---|
241 | e4_assert(new_base->is_species_manager()); |
---|
242 | |
---|
243 | ED4_species_manager *new_species_manager = new_base->to_species_manager(); |
---|
244 | ED4_terminal *new_sequence_terminal = new_species_manager->get_consensus_relevant_terminal(); |
---|
245 | |
---|
246 | int new_len; |
---|
247 | char *new_sequence = new_sequence_terminal->resolve_pointer_to_string_copy(&new_len); |
---|
248 | |
---|
249 | #if defined(DEBUG) |
---|
250 | printf("old: %s\n", old_sequence); |
---|
251 | printf("new: %s\n", new_sequence); |
---|
252 | #endif // DEBUG |
---|
253 | |
---|
254 | if (end_pos==-1) { |
---|
255 | ED4_char_table::changed_range(old_sequence, new_sequence, min(old_len, new_len), &start_pos, &end_pos); |
---|
256 | } |
---|
257 | |
---|
258 | ED4_returncode result1 = check_bases(old_sequence, old_len, new_sequence, new_len, start_pos, end_pos); |
---|
259 | ED4_returncode result2 = rebuild_consensi(new_base, update_flag); |
---|
260 | ED4_returncode result = (result1 != ED4_R_OK) ? result1 : result2; |
---|
261 | |
---|
262 | // Refresh aminoacid sequence terminals in Protein Viewer or protstruct |
---|
263 | if (ED4_ROOT->alignment_type == GB_AT_DNA) { |
---|
264 | PV_AA_SequenceUpdate_CB(GB_CB_CHANGED); |
---|
265 | } |
---|
266 | else if (ED4_ROOT->alignment_type == GB_AT_AA) { |
---|
267 | GB_ERROR err = ED4_pfold_set_SAI(&ED4_ROOT->protstruct, GLOBAL_gb_main, ED4_ROOT->alignment_name, &ED4_ROOT->protstruct_len); |
---|
268 | if (err) { aw_message(err); result = ED4_R_WARNING; } |
---|
269 | ED4_ROOT->refresh_all_windows(0); |
---|
270 | ED4_expose_all_windows(); |
---|
271 | } |
---|
272 | |
---|
273 | free(new_sequence); |
---|
274 | return result; |
---|
275 | } |
---|
276 | |
---|
277 | ED4_returncode ED4_manager::check_bases(const ED4_base *old_base, const ED4_base *new_base, int start_pos, int end_pos) { |
---|
278 | e4_assert(old_base); |
---|
279 | e4_assert(new_base); |
---|
280 | |
---|
281 | if (old_base->is_species_manager()) { |
---|
282 | e4_assert(new_base->is_species_manager()); |
---|
283 | ED4_species_manager *old_species_manager = old_base->to_species_manager(); |
---|
284 | ED4_species_manager *new_species_manager = new_base->to_species_manager(); |
---|
285 | ED4_terminal *old_sequence_terminal = old_species_manager->get_consensus_relevant_terminal(); |
---|
286 | ED4_terminal *new_sequence_terminal = new_species_manager->get_consensus_relevant_terminal(); |
---|
287 | |
---|
288 | int old_len; |
---|
289 | int new_len; |
---|
290 | char *old_seq = old_sequence_terminal->resolve_pointer_to_string_copy(&old_len); |
---|
291 | char *new_seq = new_sequence_terminal->resolve_pointer_to_string_copy(&new_len); |
---|
292 | |
---|
293 | ED4_returncode res = check_bases(old_seq, old_len, new_seq, new_len, start_pos, end_pos); |
---|
294 | free(new_seq); |
---|
295 | free(old_seq); |
---|
296 | return res; |
---|
297 | } |
---|
298 | |
---|
299 | if (old_base->is_group_manager()) { |
---|
300 | e4_assert(new_base->is_group_manager()); |
---|
301 | |
---|
302 | return check_bases(&old_base->to_group_manager()->table(), |
---|
303 | &new_base->to_group_manager()->table(), |
---|
304 | start_pos, end_pos); |
---|
305 | } |
---|
306 | |
---|
307 | return ED4_R_OK; |
---|
308 | } |
---|
309 | |
---|
310 | // WITH_ALL_ABOVE_GROUP_MANAGER_TABLES performs a command with all groupmanager-tables |
---|
311 | // starting at walk_up (normally the current) until top (or until one table has an ignore flag) |
---|
312 | |
---|
313 | #define WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, COMMAND) \ |
---|
314 | do { \ |
---|
315 | while (walk_up) { \ |
---|
316 | if (walk_up->is_group_manager()) { \ |
---|
317 | ED4_char_table& char_table = walk_up->to_group_manager()->table(); \ |
---|
318 | char_table.COMMAND; \ |
---|
319 | if (char_table.is_ignored()) break; \ |
---|
320 | } \ |
---|
321 | walk_up = walk_up->parent; \ |
---|
322 | } \ |
---|
323 | } while(0) |
---|
324 | |
---|
325 | ED4_returncode ED4_manager::check_bases(const char *old_sequence, int old_len, const char *new_sequence, int new_len, int start_pos, int end_pos) { |
---|
326 | ED4_manager *walk_up = this; |
---|
327 | |
---|
328 | #ifdef DEBUG |
---|
329 | if (end_pos==-1) { |
---|
330 | printf("check_bases does not know update range - maybe an error?\n"); |
---|
331 | } |
---|
332 | #endif |
---|
333 | |
---|
334 | if (old_sequence) { |
---|
335 | if (new_sequence) { |
---|
336 | if (end_pos==-1) { |
---|
337 | if (!ED4_char_table::changed_range(old_sequence, new_sequence, min(old_len, new_len), &start_pos, &end_pos)) { |
---|
338 | return ED4_R_OK; |
---|
339 | } |
---|
340 | } |
---|
341 | |
---|
342 | #if defined(DEBUG) && 0 |
---|
343 | printf("check_bases(..., %i, %i)\n", start_pos, end_pos); |
---|
344 | #endif |
---|
345 | |
---|
346 | WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, sub_and_add(old_sequence, new_sequence, start_pos, end_pos)); |
---|
347 | } else { |
---|
348 | e4_assert(start_pos==0 && end_pos==-1); |
---|
349 | WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, sub(old_sequence, old_len)); |
---|
350 | } |
---|
351 | } else { |
---|
352 | if (new_sequence) { |
---|
353 | e4_assert(start_pos==0 && end_pos==-1); |
---|
354 | WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, add(new_sequence, new_len)); |
---|
355 | } else { |
---|
356 | return ED4_R_OK; |
---|
357 | } |
---|
358 | } |
---|
359 | |
---|
360 | ED4_ROOT->root_group_man->remap()->mark_compile_needed(); |
---|
361 | return ED4_R_OK; |
---|
362 | } |
---|
363 | |
---|
364 | ED4_returncode ED4_manager::check_bases(const ED4_char_table *old_table, const ED4_char_table *new_table, int start_pos, int end_pos) { |
---|
365 | ED4_manager *walk_up = this; |
---|
366 | |
---|
367 | if (old_table) { |
---|
368 | if (new_table) { |
---|
369 | if (end_pos==-1) { |
---|
370 | if (!old_table->changed_range(*new_table, &start_pos, &end_pos)) { |
---|
371 | return ED4_R_OK; |
---|
372 | } |
---|
373 | } |
---|
374 | WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, sub_and_add(*old_table, *new_table, start_pos, end_pos)); |
---|
375 | } else { |
---|
376 | e4_assert(start_pos==0 && end_pos==-1); |
---|
377 | WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, sub(*old_table)); |
---|
378 | } |
---|
379 | } else { |
---|
380 | if (new_table) { |
---|
381 | e4_assert(start_pos==0 && end_pos==-1); |
---|
382 | WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, add(*new_table)); |
---|
383 | } else { |
---|
384 | return ED4_R_OK; |
---|
385 | } |
---|
386 | } |
---|
387 | |
---|
388 | ED4_ROOT->root_group_man->remap()->mark_compile_needed(); |
---|
389 | return ED4_R_OK; |
---|
390 | } |
---|
391 | |
---|
392 | #undef WITH_ALL_ABOVE_GROUP_MANAGER_TABLES |
---|
393 | |
---|
394 | ED4_returncode ED4_manager::remove_callbacks() { |
---|
395 | // removes callbacks |
---|
396 | int i; |
---|
397 | |
---|
398 | for (i=0; i < children->members(); i++) { |
---|
399 | if (children->member(i)->is_terminal()) { |
---|
400 | children->member(i)->to_terminal()->remove_callbacks(); |
---|
401 | } |
---|
402 | else { |
---|
403 | children->member(i)->to_manager()->remove_callbacks(); |
---|
404 | } |
---|
405 | } |
---|
406 | |
---|
407 | return ED4_R_OK; |
---|
408 | } |
---|
409 | |
---|
410 | ED4_returncode ED4_manager::update_consensus(ED4_manager *old_parent, ED4_manager *new_parent, ED4_base *sequence, int start_pos, int end_pos) { |
---|
411 | if (old_parent) old_parent->check_out_bases(sequence, start_pos, end_pos); |
---|
412 | if (new_parent) new_parent->check_in_bases(sequence, start_pos, end_pos); |
---|
413 | |
---|
414 | return ED4_R_OK; |
---|
415 | } |
---|
416 | |
---|
417 | ED4_terminal* ED4_manager::get_first_terminal(int start_index) const { |
---|
418 | ED4_terminal *terminal = 0; |
---|
419 | |
---|
420 | if (children) { |
---|
421 | int i; |
---|
422 | for (i=start_index; !terminal && i>=0 && i<children->members(); i++) { |
---|
423 | ED4_base *base = children->member(i); |
---|
424 | if (base->is_terminal()) { |
---|
425 | terminal = base->to_terminal(); |
---|
426 | } |
---|
427 | else { |
---|
428 | terminal = base->to_manager()->get_first_terminal(); |
---|
429 | } |
---|
430 | } |
---|
431 | } |
---|
432 | |
---|
433 | return terminal; |
---|
434 | } |
---|
435 | |
---|
436 | ED4_terminal* ED4_manager::get_last_terminal(int start_index) const { |
---|
437 | ED4_terminal *terminal = 0; |
---|
438 | |
---|
439 | if (children) { |
---|
440 | int i; |
---|
441 | if (start_index<0) start_index = children->members()-1; |
---|
442 | for (i=start_index; !terminal && i>=0 && i<children->members(); i--) { |
---|
443 | ED4_base *base = children->member(i); |
---|
444 | if (base->is_terminal()) { |
---|
445 | terminal = base->to_terminal(); |
---|
446 | } |
---|
447 | else { |
---|
448 | terminal = base->to_manager()->get_last_terminal(); |
---|
449 | } |
---|
450 | } |
---|
451 | } |
---|
452 | |
---|
453 | return terminal; |
---|
454 | } |
---|
455 | |
---|
456 | ED4_base* ED4_manager::get_competent_child(AW_pos x, AW_pos y, ED4_properties relevant_prop) { |
---|
457 | ED4_extension ext; |
---|
458 | ED4_index temp_index; |
---|
459 | ED4_base *child; |
---|
460 | |
---|
461 | ext.position[X_POS] = x; |
---|
462 | ext.position[Y_POS] = y; |
---|
463 | ED4_base::touch_world_cache(); |
---|
464 | |
---|
465 | temp_index = children->search_member(&ext, spec->static_prop); |
---|
466 | |
---|
467 | if ((temp_index < 0) || (temp_index >= children->members())) { // no child at given location |
---|
468 | return (NULL); |
---|
469 | } |
---|
470 | |
---|
471 | child = children->member(temp_index); |
---|
472 | |
---|
473 | return (child->spec->static_prop & relevant_prop) ? child : (ED4_base*)NULL; |
---|
474 | } |
---|
475 | |
---|
476 | ED4_base* ED4_manager::get_competent_clicked_child(AW_pos x, AW_pos y, ED4_properties relevant_prop) { |
---|
477 | ED4_extension ext; |
---|
478 | ED4_base *child; |
---|
479 | ED4_base *temp_parent = NULL; |
---|
480 | |
---|
481 | ext.position[X_POS] = x; |
---|
482 | ext.position[Y_POS] = y; |
---|
483 | ED4_base::touch_world_cache(); |
---|
484 | |
---|
485 | children->search_target_species(&ext, spec->static_prop, &temp_parent, ED4_L_MULTI_SPECIES); |
---|
486 | |
---|
487 | if (!temp_parent) { |
---|
488 | temp_parent = this; |
---|
489 | } |
---|
490 | |
---|
491 | child = temp_parent; |
---|
492 | if (child->spec->static_prop & relevant_prop) { |
---|
493 | return (child); |
---|
494 | } |
---|
495 | else { |
---|
496 | return (NULL); |
---|
497 | } |
---|
498 | } |
---|
499 | |
---|
500 | ED4_returncode ED4_manager::handle_move(ED4_move_info *mi) { |
---|
501 | // handles a move request with target world |
---|
502 | // coordinates within current object's borders |
---|
503 | AW_pos rel_x, rel_y, x_off, y_off; |
---|
504 | ED4_base *object; |
---|
505 | ED4_manager *old_parent; |
---|
506 | ED4_manager *manager; |
---|
507 | ED4_level mlevel; |
---|
508 | ED4_terminal *sel_object; |
---|
509 | ED4_selection_entry *sel_info; |
---|
510 | ED4_list_elem *list_elem; |
---|
511 | bool i_am_consensus = 0; |
---|
512 | ED4_AREA_LEVEL level; |
---|
513 | ED4_base *found_member = NULL; |
---|
514 | ED4_extension loc; |
---|
515 | |
---|
516 | #if defined(LIMIT_TOP_AREA_SPACE) |
---|
517 | int nr_of_visible_species = 0; |
---|
518 | int nr_of_children_in_group = 0; |
---|
519 | #endif |
---|
520 | |
---|
521 | if ((mi == NULL) || (mi->object->spec->level <= spec->level)) { |
---|
522 | return (ED4_R_IMPOSSIBLE); |
---|
523 | } |
---|
524 | |
---|
525 | rel_x = mi->end_x; // calculate target position relative to current object |
---|
526 | rel_y = mi->end_y; |
---|
527 | |
---|
528 | calc_rel_coords(&rel_x, &rel_y); |
---|
529 | |
---|
530 | if ((mi->preferred_parent & spec->level) || // desired parent or levels match = > can handle moving |
---|
531 | (mi->object->spec->level & spec->allowed_children)) // object(s) myself, take info from list of selected objects |
---|
532 | { |
---|
533 | |
---|
534 | if (mi->object->dynamic_prop & ED4_P_IS_HANDLE) { // object is a handle for an object up in the hierarchy = > search it |
---|
535 | mlevel = mi->object->spec->handled_level; |
---|
536 | object = mi->object; |
---|
537 | |
---|
538 | while ((object != NULL) && !(object->spec->level & mlevel)) object = object->parent; |
---|
539 | if (object == NULL) return (ED4_R_IMPOSSIBLE); // no target level found |
---|
540 | } |
---|
541 | else { |
---|
542 | object = mi->object; // selected object is no handle => take it directly |
---|
543 | |
---|
544 | if (object->flag.is_consensus) { |
---|
545 | if (this->is_child_of(object->parent)) return ED4_R_IMPOSSIBLE; // has to pass multi_species_manager |
---|
546 | i_am_consensus = 1; |
---|
547 | |
---|
548 | if (object->parent != this) { |
---|
549 | object = object->parent->parent; |
---|
550 | mi->object = object; |
---|
551 | } |
---|
552 | } |
---|
553 | } |
---|
554 | |
---|
555 | |
---|
556 | old_parent = object->parent; |
---|
557 | ED4_multi_species_manager *multi_species_manager = NULL; |
---|
558 | |
---|
559 | level = get_area_level(&multi_species_manager); |
---|
560 | |
---|
561 | #if defined(LIMIT_TOP_AREA_SPACE) |
---|
562 | if (old_parent->get_area_level() != level) { // when moving between two different areas we have to |
---|
563 | if (level == ED4_A_TOP_AREA || level == ED4_A_BOTTOM_AREA) { // check restrictions |
---|
564 | nr_of_visible_species = multi_species_manager->count_visible_children(); |
---|
565 | |
---|
566 | if (nr_of_visible_species >= MAX_TOP_AREA_SIZE) { |
---|
567 | return ED4_R_IMPOSSIBLE; |
---|
568 | } |
---|
569 | |
---|
570 | if (object->is_group_manager()) { |
---|
571 | ED4_group_manager *group_manager = object->to_group_manager(); |
---|
572 | |
---|
573 | if (object->dynamic_prop & ED4_P_IS_FOLDED) { |
---|
574 | nr_of_children_in_group = 1; |
---|
575 | } |
---|
576 | else { |
---|
577 | nr_of_children_in_group = group_manager->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager()->count_visible_children(); |
---|
578 | } |
---|
579 | |
---|
580 | if (nr_of_children_in_group + nr_of_visible_species > MAX_TOP_AREA_SIZE) { |
---|
581 | return ED4_R_IMPOSSIBLE; |
---|
582 | } |
---|
583 | } |
---|
584 | } |
---|
585 | } |
---|
586 | #endif // LIMIT_TOP_AREA_SPACE |
---|
587 | |
---|
588 | x_off = 0; |
---|
589 | y_off = 0; |
---|
590 | |
---|
591 | // now do move action => determine insertion offsets and insert object |
---|
592 | |
---|
593 | if (ED4_ROOT->selected_objects.no_of_entries()>1) { |
---|
594 | list_elem = ED4_ROOT->selected_objects.first(); |
---|
595 | while (list_elem != NULL) { |
---|
596 | sel_info = (ED4_selection_entry *) list_elem->elem(); |
---|
597 | sel_object = sel_info->object; |
---|
598 | |
---|
599 | if ((sel_object==mi->object)) break; |
---|
600 | if (spec->static_prop & ED4_P_HORIZONTAL) y_off += sel_info->actual_height; |
---|
601 | if (spec->static_prop & ED4_P_VERTICAL) x_off += sel_info->actual_width; |
---|
602 | |
---|
603 | list_elem = list_elem->next(); |
---|
604 | } |
---|
605 | } |
---|
606 | |
---|
607 | loc.position[Y_POS] = mi->end_y; |
---|
608 | loc.position[X_POS] = mi->end_x; |
---|
609 | ED4_base::touch_world_cache(); |
---|
610 | |
---|
611 | { |
---|
612 | ED4_manager *dummy_mark = ED4_ROOT->main_manager->search_spec_child_rek(ED4_L_DEVICE)->to_manager(); |
---|
613 | dummy_mark->children->search_target_species(&loc, ED4_P_HORIZONTAL, &found_member, ED4_L_NO_LEVEL); |
---|
614 | } |
---|
615 | |
---|
616 | if (found_member==object) { // if we are dropped on ourself => don't move |
---|
617 | return ED4_R_BREAK; |
---|
618 | } |
---|
619 | |
---|
620 | ED4_base *parent_man = object->get_parent(ED4_L_MULTI_SPECIES); |
---|
621 | object->parent->children->delete_member(object); |
---|
622 | parent_man->to_multi_species_manager()->invalidate_species_counters(); |
---|
623 | |
---|
624 | object->extension.position[X_POS] = rel_x + x_off; |
---|
625 | object->extension.position[Y_POS] = rel_y; // was: rel_y + y_off; |
---|
626 | ED4_base::touch_world_cache(); |
---|
627 | |
---|
628 | object->parent = this; |
---|
629 | |
---|
630 | if (old_parent != this) { // check whether consensus has to be calculated new or not |
---|
631 | GB_push_transaction(GLOBAL_gb_main); |
---|
632 | update_consensus(old_parent, this, object); |
---|
633 | rebuild_consensi(old_parent, ED4_U_UP); |
---|
634 | rebuild_consensi(this, ED4_U_UP); |
---|
635 | GB_pop_transaction(GLOBAL_gb_main); |
---|
636 | } |
---|
637 | |
---|
638 | if ((i_am_consensus && object->parent != old_parent) || !i_am_consensus) { |
---|
639 | object->set_width(); |
---|
640 | |
---|
641 | if (dynamic_prop & ED4_P_IS_FOLDED) { // add spacer and consensusheight |
---|
642 | object->extension.position[Y_POS] = children->member(0)->extension.size[HEIGHT] + children->member(1)->extension.size[HEIGHT]; |
---|
643 | object->flag.hidden = 1; |
---|
644 | ED4_base::touch_world_cache(); |
---|
645 | } |
---|
646 | } |
---|
647 | |
---|
648 | children->insert_member(object); |
---|
649 | if (is_multi_species_manager()) { |
---|
650 | to_multi_species_manager()->invalidate_species_counters(); |
---|
651 | } |
---|
652 | else { |
---|
653 | get_parent(ED4_L_MULTI_SPECIES)->to_multi_species_manager()->invalidate_species_counters(); |
---|
654 | } |
---|
655 | |
---|
656 | return (ED4_R_OK); |
---|
657 | } |
---|
658 | else { |
---|
659 | // levels do not match = > ask competent manager child to handle move request |
---|
660 | if ((manager = (ED4_manager *) get_competent_child(rel_x, rel_y, ED4_P_IS_MANAGER)) == NULL) { // no manager child covering target |
---|
661 | return (ED4_R_IMPOSSIBLE); // location = > move not possible |
---|
662 | } |
---|
663 | |
---|
664 | return (manager->move_requested_by_parent(mi)); // there is a manager child covering target location = > pass on move request |
---|
665 | } |
---|
666 | } |
---|
667 | |
---|
668 | |
---|
669 | ED4_returncode ED4_manager::move_requested_by_parent(ED4_move_info *mi) { |
---|
670 | // handles a move request with target world coordinates coming from parent |
---|
671 | if ((mi == NULL) || !(in_border(mi->end_x, mi->end_y, mi->mode))) |
---|
672 | return (ED4_R_IMPOSSIBLE); |
---|
673 | |
---|
674 | return (handle_move(mi)); |
---|
675 | } |
---|
676 | |
---|
677 | |
---|
678 | ED4_returncode ED4_manager::move_requested_by_child(ED4_move_info *mi) { |
---|
679 | // handles a move request coming from a child, |
---|
680 | // target location can be out of borders |
---|
681 | ED4_base *temp_parent = NULL; |
---|
682 | |
---|
683 | if (mi == NULL) |
---|
684 | return (ED4_R_IMPOSSIBLE); |
---|
685 | |
---|
686 | if (spec->level < mi->object->spec->restriction_level) return (ED4_R_IMPOSSIBLE); // check if there is a level restriction to the move request |
---|
687 | |
---|
688 | if (mi->object->dynamic_prop & ED4_P_IS_HANDLE) { // determine first if we could be the moving object |
---|
689 | if ((dynamic_prop & ED4_P_MOVABLE) && (spec->level & mi->object->spec->handled_level)) { // yes, we are meant to be the moving object |
---|
690 | mi->object = this; |
---|
691 | } |
---|
692 | |
---|
693 | if (parent == NULL) return (ED4_R_WARNING); |
---|
694 | |
---|
695 | return (parent->move_requested_by_child(mi)); |
---|
696 | } |
---|
697 | |
---|
698 | if (!(in_border(mi->end_x, mi->end_y, mi->mode))) { |
---|
699 | // determine if target location is within |
---|
700 | // the borders of current object, do boundary |
---|
701 | // adjustment of target coordinates if necessary |
---|
702 | // target location is not within borders => |
---|
703 | // ask parent, i.e. move recursively up |
---|
704 | if (parent == NULL) return (ED4_R_WARNING); |
---|
705 | return (parent->move_requested_by_child(mi)); |
---|
706 | } |
---|
707 | else { // target location within current borders = > handle move myself |
---|
708 | temp_parent = get_competent_clicked_child(mi->end_x, mi->end_y, ED4_P_IS_MANAGER); |
---|
709 | |
---|
710 | if (!temp_parent) { |
---|
711 | return (handle_move(mi)); |
---|
712 | } |
---|
713 | else { |
---|
714 | if ((temp_parent->is_group_manager()) || (temp_parent->is_area_manager())) { |
---|
715 | temp_parent = temp_parent->to_group_manager()->get_defined_level(ED4_L_MULTI_SPECIES); |
---|
716 | } |
---|
717 | else if (!(temp_parent->is_multi_species_manager())) { |
---|
718 | temp_parent = temp_parent->get_parent(ED4_L_MULTI_SPECIES); |
---|
719 | } |
---|
720 | if (!temp_parent) { |
---|
721 | return ED4_R_IMPOSSIBLE; |
---|
722 | } |
---|
723 | return (temp_parent->handle_move(mi)); |
---|
724 | } |
---|
725 | } |
---|
726 | } |
---|
727 | |
---|
728 | ED4_returncode ED4_manager::event_sent_by_parent(AW_event *event, AW_window *aww) { |
---|
729 | // handles an input event coming from parent |
---|
730 | ED4_extension ext; |
---|
731 | ED4_index temp_index; |
---|
732 | ED4_returncode returncode; |
---|
733 | |
---|
734 | if (flag.hidden) |
---|
735 | return ED4_R_BREAK; |
---|
736 | |
---|
737 | ext.position[X_POS] = event->x; |
---|
738 | ext.position[Y_POS] = event->y; |
---|
739 | |
---|
740 | calc_rel_coords(&ext.position[X_POS], &ext.position[Y_POS]); |
---|
741 | |
---|
742 | temp_index = children->search_member(&ext, spec->static_prop); // search child who is competent for the location of given event |
---|
743 | |
---|
744 | if ((temp_index >= children->members()) || (temp_index < 0)) { |
---|
745 | return (ED4_R_IMPOSSIBLE); // no suitable member found |
---|
746 | } |
---|
747 | |
---|
748 | returncode = children->member(temp_index)->event_sent_by_parent(event, aww); |
---|
749 | return (returncode); |
---|
750 | } |
---|
751 | |
---|
752 | ED4_returncode ED4_manager::calc_size_requested_by_parent(void) { |
---|
753 | if (calc_bounding_box()) { |
---|
754 | if (parent) { |
---|
755 | parent->resize_requested_by_child(); |
---|
756 | } |
---|
757 | } |
---|
758 | |
---|
759 | return (ED4_R_OK); |
---|
760 | } |
---|
761 | |
---|
762 | ED4_returncode ED4_manager::refresh_requested_by_child(void) { |
---|
763 | // handles a refresh-request from a child |
---|
764 | if (!update_info.refresh) { // determine if there were more refresh requests already => no need to tell parent about it |
---|
765 | update_info.set_refresh(1); // this is the first refresh request |
---|
766 | if (parent) parent->refresh_requested_by_child(); // if we have a parent, tell him about the refresh request |
---|
767 | } |
---|
768 | |
---|
769 | #ifdef TEST_REFRESH_FLAG |
---|
770 | e4_assert(refresh_flag_ok()); |
---|
771 | #endif |
---|
772 | return ED4_R_OK; |
---|
773 | } |
---|
774 | |
---|
775 | int ED4_manager::refresh_flag_ok() { |
---|
776 | ED4_index i; |
---|
777 | |
---|
778 | for (i=0; i<children->members(); i++) { |
---|
779 | ED4_base *child = children->member(i); |
---|
780 | |
---|
781 | if (child->is_manager()) { |
---|
782 | if (!child->to_manager()->refresh_flag_ok()) { |
---|
783 | return 0; |
---|
784 | } |
---|
785 | } |
---|
786 | |
---|
787 | if (child->update_info.refresh==1 && update_info.refresh==0) { |
---|
788 | printf("Forgotten refresh-flag in '%s' (son of '%s')\n", child->id, id); |
---|
789 | return 0; |
---|
790 | } |
---|
791 | } |
---|
792 | |
---|
793 | return 1; |
---|
794 | } |
---|
795 | |
---|
796 | short ED4_manager::calc_bounding_box(void) { |
---|
797 | //calculates the smallest rectangle containing the object and |
---|
798 | //gives information if something has changed |
---|
799 | AW_pos sum_width = 0; |
---|
800 | AW_pos sum_height = 0; |
---|
801 | AW_pos max_x = 0; |
---|
802 | AW_pos max_y = 0; |
---|
803 | AW_pos dummy = 0; |
---|
804 | ED4_index i = 0; |
---|
805 | short bb_changed = 0; |
---|
806 | ED4_list_elem *current_list_elem; |
---|
807 | ED4_base *child, *object; |
---|
808 | |
---|
809 | //initialize with first child |
---|
810 | while ((child = children->member(i++)) != NULL) { // check all children |
---|
811 | if (!child->flag.hidden) { |
---|
812 | sum_width += child->extension.size[WIDTH]; |
---|
813 | sum_height += child->extension.size[HEIGHT]; |
---|
814 | |
---|
815 | dummy = child->extension.position[X_POS] + child->extension.size[WIDTH]; |
---|
816 | if (dummy > max_x) { |
---|
817 | max_x = dummy; |
---|
818 | } |
---|
819 | |
---|
820 | dummy = child->extension.position[Y_POS] + child->extension.size[HEIGHT]; |
---|
821 | if (dummy > max_y) { |
---|
822 | max_y = dummy; |
---|
823 | } |
---|
824 | ED4_base::touch_world_cache(); |
---|
825 | } |
---|
826 | } |
---|
827 | |
---|
828 | |
---|
829 | if (spec->static_prop & ED4_P_HORIZONTAL) { |
---|
830 | if (int(extension.size[WIDTH]) != int(max_x)) { // because compares between floats fail sometimes (AW_pos==float) |
---|
831 | extension.size[WIDTH] = max_x; |
---|
832 | bb_changed = 1; |
---|
833 | } |
---|
834 | |
---|
835 | if (int(extension.size[HEIGHT]) != int(sum_height)) { |
---|
836 | extension.size[HEIGHT] = sum_height; |
---|
837 | bb_changed = 1; |
---|
838 | } |
---|
839 | } |
---|
840 | |
---|
841 | if (spec->static_prop & ED4_P_VERTICAL) { |
---|
842 | if (int(extension.size[WIDTH]) != int(sum_width)) { |
---|
843 | extension.size[WIDTH] = sum_width; |
---|
844 | bb_changed = 1; |
---|
845 | } |
---|
846 | if (int(extension.size[HEIGHT]) != int(max_y)) { |
---|
847 | extension.size[HEIGHT] = max_y; |
---|
848 | bb_changed = 1; |
---|
849 | } |
---|
850 | } |
---|
851 | |
---|
852 | if (bb_changed) { // tell linked objects about our change of bounding box |
---|
853 | |
---|
854 | current_list_elem = linked_objects.first(); |
---|
855 | while (current_list_elem) { |
---|
856 | object = (ED4_base *) current_list_elem->elem(); |
---|
857 | if (object) { |
---|
858 | object->link_changed(this); |
---|
859 | } |
---|
860 | |
---|
861 | current_list_elem = current_list_elem->next(); |
---|
862 | } |
---|
863 | } |
---|
864 | return (bb_changed); |
---|
865 | } |
---|
866 | |
---|
867 | ED4_returncode ED4_manager::distribute_children(void) { |
---|
868 | // distributes all children of current object according to current object's properties and |
---|
869 | // justification value; a recalculation of current object's extension will take place if necessary |
---|
870 | |
---|
871 | ED4_index current_index; |
---|
872 | ED4_index rel_pos = 0; |
---|
873 | ED4_index rel_size = 0; |
---|
874 | ED4_index other_pos = 0; |
---|
875 | ED4_index other_size = 0; |
---|
876 | AW_pos max_rel_size = 0; |
---|
877 | AW_pos max_other_size = 0; |
---|
878 | ED4_base *current_child; |
---|
879 | |
---|
880 | // printf("distribute_children this=%p\n", this); |
---|
881 | |
---|
882 | // set extension-indexes rel_pos and rel_size according to properties |
---|
883 | if (spec->static_prop & ED4_P_HORIZONTAL) { |
---|
884 | rel_pos = X_POS; |
---|
885 | other_pos = Y_POS; |
---|
886 | rel_size = WIDTH; |
---|
887 | other_size = HEIGHT; |
---|
888 | } |
---|
889 | if (spec->static_prop & ED4_P_VERTICAL) { |
---|
890 | rel_pos = Y_POS; |
---|
891 | other_pos = X_POS; |
---|
892 | rel_size = HEIGHT; |
---|
893 | other_size = WIDTH; |
---|
894 | } |
---|
895 | |
---|
896 | current_index = 0; // get maximal relevant and other size of children, set children's other position increasingly |
---|
897 | while ((current_child = children->member(current_index)) != NULL) { |
---|
898 | max_rel_size = max(int(max_rel_size), int(current_child->extension.size[rel_size])); |
---|
899 | if (current_child->extension.position[other_pos] != max_other_size) { |
---|
900 | current_child->extension.position[other_pos] = max_other_size; |
---|
901 | ED4_base::touch_world_cache(); |
---|
902 | } |
---|
903 | max_other_size += current_child->extension.size[other_size]; |
---|
904 | current_index++; |
---|
905 | } |
---|
906 | |
---|
907 | current_index = 0; // set children's relevant position according to justification value |
---|
908 | // (0.0 means top- or left-justified, 1.0 means bottom- or right-justified) |
---|
909 | while ((current_child = children->member(current_index++)) != NULL) { |
---|
910 | current_child->extension.position[rel_pos] = spec->justification * (max_rel_size - current_child->extension.size[rel_size]); |
---|
911 | ED4_base::touch_world_cache(); |
---|
912 | } |
---|
913 | |
---|
914 | refresh_requested_by_child(); |
---|
915 | return (ED4_R_OK); |
---|
916 | } |
---|
917 | |
---|
918 | ED4_returncode ED4_manager::resize_requested_by_parent(void) { |
---|
919 | if (update_info.resize) { // object wants to resize |
---|
920 | update_info.set_resize(0); // first clear the resize flag (remember it could be set again from somewhere below the hierarchy) |
---|
921 | |
---|
922 | ED4_index i = 0; |
---|
923 | while (1) { |
---|
924 | ED4_base *child = children->member(i++); |
---|
925 | |
---|
926 | if (!child) break; |
---|
927 | |
---|
928 | child->update_info.set_resize(1); |
---|
929 | child->resize_requested_by_parent(); |
---|
930 | } |
---|
931 | |
---|
932 | distribute_children(); |
---|
933 | if (calc_bounding_box()) { // recalculate current object's bounding_box |
---|
934 | resize_requested_by_child(); |
---|
935 | } |
---|
936 | } |
---|
937 | |
---|
938 | return ED4_R_OK; |
---|
939 | } |
---|
940 | ED4_returncode ED4_root_group_manager::resize_requested_by_parent(void) { |
---|
941 | ED4_returncode result = ED4_R_OK; |
---|
942 | |
---|
943 | if (update_info.resize) { |
---|
944 | update_remap(); |
---|
945 | result = ED4_manager::resize_requested_by_parent(); |
---|
946 | } |
---|
947 | |
---|
948 | return result; |
---|
949 | } |
---|
950 | |
---|
951 | ED4_returncode ED4_main_manager::resize_requested_by_parent() { |
---|
952 | ED4_returncode result = ED4_R_OK; |
---|
953 | |
---|
954 | if (update_info.resize) { |
---|
955 | result = ED4_manager::resize_requested_by_parent(); |
---|
956 | ED4_ROOT->get_ed4w()->update_scrolled_rectangle(); |
---|
957 | } |
---|
958 | return ED4_R_OK; |
---|
959 | } |
---|
960 | |
---|
961 | ED4_returncode ED4_manager::Resize() { |
---|
962 | if (!flag.hidden) { |
---|
963 | while (update_info.resize) { |
---|
964 | resize_requested_by_parent(); |
---|
965 | if (parent) break; |
---|
966 | } |
---|
967 | } |
---|
968 | |
---|
969 | return ED4_R_OK; |
---|
970 | } |
---|
971 | ED4_returncode ED4_terminal::Resize() { |
---|
972 | return ED4_R_OK; |
---|
973 | } |
---|
974 | |
---|
975 | ED4_returncode ED4_main_manager::Show(int refresh_all, int is_cleared) { |
---|
976 | #ifdef TEST_REFRESH_FLAG |
---|
977 | e4_assert(refresh_flag_ok()); |
---|
978 | #endif |
---|
979 | #if defined(DEBUG) && 0 |
---|
980 | printf("Show main_manager\n"); |
---|
981 | #endif |
---|
982 | |
---|
983 | AW_device *device = ED4_ROOT->get_device(); |
---|
984 | |
---|
985 | if (flag.hidden) { |
---|
986 | if (last_window_reached && update_info.refresh) { |
---|
987 | clear_refresh(); |
---|
988 | } |
---|
989 | } |
---|
990 | else if (refresh_all || update_info.refresh) { |
---|
991 | AW_rectangle area_rect; |
---|
992 | device->get_area_size(&area_rect); |
---|
993 | |
---|
994 | // if update all -> clear_background |
---|
995 | |
---|
996 | if (update_info.clear_at_refresh && !is_cleared) { |
---|
997 | device->push_clip_scale(); |
---|
998 | if (device->reduceClipBorders(area_rect.t, area_rect.b, area_rect.l, area_rect.r)) { |
---|
999 | clear_background(); |
---|
1000 | } |
---|
1001 | is_cleared = 1; |
---|
1002 | device->pop_clip_scale(); |
---|
1003 | } |
---|
1004 | |
---|
1005 | // loop through all rectangles between folding lines: |
---|
1006 | |
---|
1007 | int x1,y1,x2,y2; |
---|
1008 | ED4_folding_line *flv,*flh; |
---|
1009 | ED4_window& win = *ED4_ROOT->get_ed4w(); |
---|
1010 | int old_last_window_reached = last_window_reached; |
---|
1011 | |
---|
1012 | last_window_reached = 0; |
---|
1013 | x1 = area_rect.l; |
---|
1014 | for (flv = win.vertical_fl; ; flv = flv->next) { |
---|
1015 | int lastColumn = 0; |
---|
1016 | |
---|
1017 | if (flv) { |
---|
1018 | e4_assert(flv->length==INFINITE); |
---|
1019 | x2 = int(flv->window_pos[X_POS]); |
---|
1020 | if (!flv->next && x2==area_rect.r) { |
---|
1021 | lastColumn = 1; |
---|
1022 | } |
---|
1023 | } |
---|
1024 | else { |
---|
1025 | x2 = area_rect.r; |
---|
1026 | lastColumn = 1; |
---|
1027 | if (x1==x2) { |
---|
1028 | break; // do not draw last range, if it's only 1 pixel width |
---|
1029 | } |
---|
1030 | } |
---|
1031 | |
---|
1032 | y1 = area_rect.t; |
---|
1033 | for (flh = win.horizontal_fl; ; flh = flh->next) { |
---|
1034 | int lastRow = 0; |
---|
1035 | |
---|
1036 | if (flh) { |
---|
1037 | e4_assert(flh->length==INFINITE); |
---|
1038 | y2 = int(flh->window_pos[Y_POS]); |
---|
1039 | if (!flh->next && y2==area_rect.b) { |
---|
1040 | lastRow = 1; |
---|
1041 | } |
---|
1042 | } |
---|
1043 | else { |
---|
1044 | y2 = area_rect.b; |
---|
1045 | lastRow = 1; |
---|
1046 | if (y1==y2) { |
---|
1047 | break; // do not draw last range, if it's only 1 pixel high |
---|
1048 | } |
---|
1049 | } |
---|
1050 | |
---|
1051 | if (lastRow && lastColumn) { |
---|
1052 | last_window_reached = old_last_window_reached; |
---|
1053 | } |
---|
1054 | |
---|
1055 | device->push_clip_scale(); |
---|
1056 | if (device->reduceClipBorders(y1, y2-1, x1, x2-1)) { |
---|
1057 | ED4_manager::Show(refresh_all, is_cleared); |
---|
1058 | } |
---|
1059 | device->pop_clip_scale(); |
---|
1060 | |
---|
1061 | if (last_window_reached) { |
---|
1062 | update_info.set_refresh(0); |
---|
1063 | update_info.set_clear_at_refresh(0); |
---|
1064 | } |
---|
1065 | |
---|
1066 | if (!flh) break; // break out after drawing lowest range |
---|
1067 | y1 = y2; |
---|
1068 | } |
---|
1069 | if (!flv) break; // break out after drawing rightmost range |
---|
1070 | |
---|
1071 | x1 = x2; |
---|
1072 | } |
---|
1073 | } |
---|
1074 | |
---|
1075 | // to avoid text clipping problems between top and middle area we redraw the top-middle-spacer : |
---|
1076 | { |
---|
1077 | device->push_clip_scale(); |
---|
1078 | const AW_rectangle& clip_rect = device->clip_rect; |
---|
1079 | device->set_top_clip_border(clip_rect.t-TERMINALHEIGHT); |
---|
1080 | |
---|
1081 | int char_width = ED4_ROOT->font_group.get_max_width(); |
---|
1082 | device->set_left_clip_border(clip_rect.l-char_width); |
---|
1083 | device->set_right_clip_border(clip_rect.r+char_width); |
---|
1084 | |
---|
1085 | get_top_middle_spacer_terminal()->Show(true, false); |
---|
1086 | get_top_middle_line_terminal()->Show(true, false); |
---|
1087 | device->pop_clip_scale(); |
---|
1088 | } |
---|
1089 | |
---|
1090 | #ifdef TEST_REFRESH_FLAG |
---|
1091 | e4_assert(refresh_flag_ok()); |
---|
1092 | #endif |
---|
1093 | |
---|
1094 | return ED4_R_OK; |
---|
1095 | } |
---|
1096 | |
---|
1097 | |
---|
1098 | ED4_returncode ED4_root_group_manager::Show(int refresh_all, int is_cleared) { |
---|
1099 | if (update_remap()) { |
---|
1100 | #if defined(DEBUG) |
---|
1101 | printf("map updated\n"); |
---|
1102 | #endif // DEBUG |
---|
1103 | } |
---|
1104 | return ED4_manager::Show(refresh_all, is_cleared); |
---|
1105 | } |
---|
1106 | |
---|
1107 | ED4_returncode ED4_manager::Show(int refresh_all, int is_cleared) { |
---|
1108 | #ifdef TEST_REFRESH_FLAG |
---|
1109 | e4_assert(refresh_flag_ok()); |
---|
1110 | #endif |
---|
1111 | |
---|
1112 | if (flag.hidden) { |
---|
1113 | if (last_window_reached && update_info.refresh) { |
---|
1114 | clear_refresh(); |
---|
1115 | } |
---|
1116 | } |
---|
1117 | if (!flag.hidden && (refresh_all || update_info.refresh)) { |
---|
1118 | ED4_index i = 0; |
---|
1119 | const AW_rectangle &clip_rect = ED4_ROOT->get_device()->clip_rect; // clipped rectangle in win coordinates |
---|
1120 | AW_rectangle rect; // clipped rectangle in world coordinates |
---|
1121 | |
---|
1122 | if (update_info.clear_at_refresh && !is_cleared) { |
---|
1123 | clear_background(); |
---|
1124 | is_cleared = 1; |
---|
1125 | } |
---|
1126 | |
---|
1127 | { |
---|
1128 | double x, y; |
---|
1129 | x = clip_rect.l; |
---|
1130 | y = clip_rect.t; |
---|
1131 | |
---|
1132 | ED4_ROOT->win_to_world_coords(ED4_ROOT->get_aww(), &x, &y); |
---|
1133 | |
---|
1134 | rect.l = int(x); |
---|
1135 | rect.t = int(y); |
---|
1136 | rect.r = rect.l+(clip_rect.r-clip_rect.l); |
---|
1137 | rect.b = rect.t+(clip_rect.b-clip_rect.t); |
---|
1138 | } |
---|
1139 | |
---|
1140 | // draw_bb(ED4_G_STANDARD); // debugging only! |
---|
1141 | |
---|
1142 | // binary search to find first visible child |
---|
1143 | |
---|
1144 | int first_visible_child = 0; |
---|
1145 | |
---|
1146 | { |
---|
1147 | int l = 0; |
---|
1148 | int h = children->members()-1; |
---|
1149 | |
---|
1150 | while (l<h) { |
---|
1151 | |
---|
1152 | while (children->member(l)->flag.hidden && l<h) l++; |
---|
1153 | while (children->member(h)->flag.hidden && l<h) h--; |
---|
1154 | |
---|
1155 | int m = (l+h)/2; |
---|
1156 | int min_m = m; |
---|
1157 | int max_m = m+1; |
---|
1158 | |
---|
1159 | while (children->member(m)->flag.hidden) { |
---|
1160 | if (m==h) { |
---|
1161 | m = (l+h)/2-1; |
---|
1162 | while (children->member(m)->flag.hidden) { |
---|
1163 | if (m==l) { |
---|
1164 | // all childs between l..h are flag.hidden |
---|
1165 | goto no_visible_child_found; |
---|
1166 | } |
---|
1167 | m--; |
---|
1168 | } |
---|
1169 | min_m = m; |
---|
1170 | break; |
---|
1171 | } |
---|
1172 | m++; |
---|
1173 | max_m = m; |
---|
1174 | } |
---|
1175 | |
---|
1176 | ED4_base *child = children->member(m); |
---|
1177 | e4_assert(!child->flag.hidden); |
---|
1178 | |
---|
1179 | AW_pos x,y; |
---|
1180 | child->calc_world_coords(&x, &y); |
---|
1181 | |
---|
1182 | if (spec->static_prop & ED4_P_HORIZONTAL) { // horizontal manager |
---|
1183 | e4_assert((spec->static_prop&ED4_P_VERTICAL)==0); // otherwise this binary search will not work correctly |
---|
1184 | if ((x+child->extension.size[WIDTH])<=rect.l) { // left of clipping range |
---|
1185 | l = max_m; |
---|
1186 | } |
---|
1187 | else { |
---|
1188 | h = min_m; |
---|
1189 | } |
---|
1190 | } |
---|
1191 | else if (spec->static_prop & ED4_P_VERTICAL) { // vertical manager |
---|
1192 | if ((y+child->extension.size[HEIGHT])<=rect.t) { // above clipping range |
---|
1193 | l = max_m; |
---|
1194 | } |
---|
1195 | else { |
---|
1196 | h = min_m; |
---|
1197 | } |
---|
1198 | } |
---|
1199 | else { |
---|
1200 | e4_assert(0); |
---|
1201 | } |
---|
1202 | } |
---|
1203 | } |
---|
1204 | |
---|
1205 | no_visible_child_found: |
---|
1206 | |
---|
1207 | i = 0; |
---|
1208 | |
---|
1209 | while (1) { |
---|
1210 | ED4_base *child = children->member(i++); |
---|
1211 | if (!child) break; |
---|
1212 | |
---|
1213 | int flags_cleared = 0; |
---|
1214 | |
---|
1215 | if (!child->flag.hidden && (refresh_all || child->update_info.refresh) && i>=first_visible_child) { |
---|
1216 | AW_pos x,y; |
---|
1217 | child->calc_world_coords(&x, &y); |
---|
1218 | |
---|
1219 | AW_device *device = ED4_ROOT->get_device(); |
---|
1220 | |
---|
1221 | if (!(((y-rect.b)>0.5) || |
---|
1222 | ((rect.t-(y+child->extension.size[HEIGHT]-1))>0.5) || |
---|
1223 | ((x-rect.r)>0.5) || |
---|
1224 | ((rect.l-(x+child->extension.size[WIDTH]-1))>0.5) |
---|
1225 | )) |
---|
1226 | { |
---|
1227 | // they overlap -> show it |
---|
1228 | device->push_clip_scale(); |
---|
1229 | if (child->adjust_clipping_rectangle()) { |
---|
1230 | child->Show(refresh_all, is_cleared); |
---|
1231 | } |
---|
1232 | flags_cleared = 1; |
---|
1233 | device->pop_clip_scale(); |
---|
1234 | } |
---|
1235 | } |
---|
1236 | |
---|
1237 | if (last_window_reached) { |
---|
1238 | if (!flags_cleared && child->is_manager() && child->update_info.refresh) { // if we didn't show a manager we must clear its childs refresh flags |
---|
1239 | child->to_manager()->clear_refresh(); |
---|
1240 | } |
---|
1241 | else { |
---|
1242 | child->update_info.set_refresh(0); |
---|
1243 | child->update_info.set_clear_at_refresh(0); |
---|
1244 | } |
---|
1245 | } |
---|
1246 | } |
---|
1247 | } |
---|
1248 | |
---|
1249 | // if (last_window_reached) update_info.refresh = 0; |
---|
1250 | |
---|
1251 | #ifdef TEST_REFRESH_FLAG |
---|
1252 | e4_assert(refresh_flag_ok()); |
---|
1253 | #endif |
---|
1254 | |
---|
1255 | return ED4_R_OK; |
---|
1256 | } |
---|
1257 | |
---|
1258 | ED4_returncode ED4_manager::clear_refresh() { |
---|
1259 | e4_assert(update_info.refresh); |
---|
1260 | |
---|
1261 | int i; |
---|
1262 | |
---|
1263 | for (i=0; i<children->members(); i++) { |
---|
1264 | ED4_base *child = children->member(i); |
---|
1265 | |
---|
1266 | if (child->update_info.refresh) { |
---|
1267 | if (child->is_manager()) { |
---|
1268 | child->to_manager()->clear_refresh(); |
---|
1269 | } |
---|
1270 | else { |
---|
1271 | child->update_info.set_refresh(0); |
---|
1272 | child->update_info.set_clear_at_refresh(0); |
---|
1273 | } |
---|
1274 | } |
---|
1275 | } |
---|
1276 | |
---|
1277 | update_info.set_refresh(0); |
---|
1278 | |
---|
1279 | return ED4_R_OK; |
---|
1280 | } |
---|
1281 | |
---|
1282 | ED4_returncode ED4_manager::resize_requested_by_child(void) { |
---|
1283 | // handles a resize-request from a child |
---|
1284 | if (!update_info.resize) { // this is the first resize request |
---|
1285 | if (parent) { // if we have a parent, tell him about our resize |
---|
1286 | parent->resize_requested_by_child(); |
---|
1287 | } |
---|
1288 | update_info.set_resize(1); |
---|
1289 | } |
---|
1290 | return ED4_R_OK; |
---|
1291 | } |
---|
1292 | |
---|
1293 | ED4_returncode ED4_base::delete_requested_by_child() { |
---|
1294 | if (!update_info.delete_requested) { |
---|
1295 | if (parent) { |
---|
1296 | parent->delete_requested_by_child(); |
---|
1297 | } |
---|
1298 | update_info.delete_requested = 1; |
---|
1299 | } |
---|
1300 | return ED4_R_OK; |
---|
1301 | } |
---|
1302 | |
---|
1303 | ED4_returncode ED4_terminal::delete_requested_by_parent() { |
---|
1304 | flag.deleted = 1; |
---|
1305 | return ED4_R_OK; |
---|
1306 | } |
---|
1307 | ED4_returncode ED4_manager::delete_requested_by_parent() { |
---|
1308 | for (ED4_index i=0; children->member(i); i++) { |
---|
1309 | children->member(i)->delete_requested_by_parent(); |
---|
1310 | } |
---|
1311 | return ED4_R_OK; |
---|
1312 | } |
---|
1313 | |
---|
1314 | ED4_returncode ED4_terminal::delete_requested_childs() { |
---|
1315 | e4_assert(update_info.delete_requested); |
---|
1316 | e4_assert(flag.deleted); |
---|
1317 | |
---|
1318 | delete this; |
---|
1319 | return ED4_R_WARNING; // == remove all links to me |
---|
1320 | } |
---|
1321 | ED4_returncode ED4_manager::delete_requested_childs() { |
---|
1322 | e4_assert(update_info.delete_requested); |
---|
1323 | |
---|
1324 | int i; |
---|
1325 | ED4_base *child; |
---|
1326 | |
---|
1327 | for (i=0; (child=children->member(i))!=NULL; i++) { |
---|
1328 | if (child->update_info.delete_requested) { |
---|
1329 | ED4_returncode removed = child->delete_requested_childs(); |
---|
1330 | if (removed==ED4_R_WARNING) { |
---|
1331 | children->delete_member(child); |
---|
1332 | if (i) i--; |
---|
1333 | } |
---|
1334 | } |
---|
1335 | } |
---|
1336 | |
---|
1337 | update_info.delete_requested = 0; |
---|
1338 | if (children->members()) return ED4_R_OK; |
---|
1339 | |
---|
1340 | delete this; |
---|
1341 | return ED4_R_WARNING; |
---|
1342 | } |
---|
1343 | |
---|
1344 | |
---|
1345 | ED4_returncode ED4_manager::set_refresh(int clear) { |
---|
1346 | // sets refresh flag of current object and his children |
---|
1347 | ED4_index current_index; |
---|
1348 | ED4_base *current_child; |
---|
1349 | |
---|
1350 | update_info.set_refresh(1); |
---|
1351 | update_info.set_clear_at_refresh(clear); |
---|
1352 | |
---|
1353 | current_index = 0; |
---|
1354 | while ((current_child = children->member(current_index++)) != NULL) { |
---|
1355 | current_child->set_refresh(0); |
---|
1356 | } |
---|
1357 | |
---|
1358 | return (ED4_R_OK); |
---|
1359 | } |
---|
1360 | |
---|
1361 | |
---|
1362 | ED4_base* ED4_manager::search_ID(const char *temp_id) { |
---|
1363 | ED4_base *current_child, *object; |
---|
1364 | ED4_index current_index; |
---|
1365 | |
---|
1366 | if (strcmp(temp_id, id) == 0) { // this object is the sought one |
---|
1367 | return this; |
---|
1368 | } |
---|
1369 | else { |
---|
1370 | current_index = 0; |
---|
1371 | while ((current_child = children->member(current_index))) { // search whole memberlist recursively for object with the given id |
---|
1372 | if ((object = current_child->search_ID(temp_id)) != NULL) { |
---|
1373 | return (object); |
---|
1374 | } |
---|
1375 | current_index++; |
---|
1376 | } |
---|
1377 | } |
---|
1378 | |
---|
1379 | return NULL; // no object found |
---|
1380 | } |
---|
1381 | |
---|
1382 | |
---|
1383 | ED4_manager::ED4_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) : |
---|
1384 | ED4_base(temp_id, x, y, width, height, temp_parent) |
---|
1385 | { |
---|
1386 | children = new ED4_members(this); |
---|
1387 | is_group = temp_is_group; |
---|
1388 | } |
---|
1389 | |
---|
1390 | ED4_manager::~ED4_manager() { |
---|
1391 | ED4_base *current_child; |
---|
1392 | |
---|
1393 | while (children->members() > 0) { |
---|
1394 | current_child = children->member(0); |
---|
1395 | children->delete_member(current_child); |
---|
1396 | current_child->parent = NULL; |
---|
1397 | |
---|
1398 | if (current_child->is_terminal()) delete current_child->to_terminal(); |
---|
1399 | else if (current_child->is_manager()) delete current_child->to_manager(); |
---|
1400 | } |
---|
1401 | |
---|
1402 | delete children; |
---|
1403 | } |
---|
1404 | |
---|
1405 | |
---|
1406 | |
---|
1407 | |
---|
1408 | // -------------------------------------------------------------------------------- |
---|
1409 | // ED4_main_manager |
---|
1410 | // -------------------------------------------------------------------------------- |
---|
1411 | |
---|
1412 | ED4_main_manager::ED4_main_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) : |
---|
1413 | ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group) |
---|
1414 | { |
---|
1415 | spec = &(main_manager_spec); |
---|
1416 | } |
---|
1417 | |
---|
1418 | ED4_main_manager::~ED4_main_manager() |
---|
1419 | { |
---|
1420 | } |
---|
1421 | |
---|
1422 | // -------------------------------------------------------------------------------- |
---|
1423 | // ED4_device_manager |
---|
1424 | // -------------------------------------------------------------------------------- |
---|
1425 | |
---|
1426 | ED4_device_manager::ED4_device_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) : |
---|
1427 | ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group) |
---|
1428 | { |
---|
1429 | spec = &(device_manager_spec); |
---|
1430 | } |
---|
1431 | |
---|
1432 | ED4_device_manager::~ED4_device_manager() |
---|
1433 | { |
---|
1434 | } |
---|
1435 | |
---|
1436 | // -------------------------------------------------------------------------------- |
---|
1437 | // ED4_area_manager |
---|
1438 | // -------------------------------------------------------------------------------- |
---|
1439 | |
---|
1440 | ED4_area_manager::ED4_area_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) : |
---|
1441 | ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group) |
---|
1442 | { |
---|
1443 | spec = &(area_manager_spec); |
---|
1444 | } |
---|
1445 | |
---|
1446 | |
---|
1447 | ED4_area_manager::~ED4_area_manager() |
---|
1448 | { |
---|
1449 | } |
---|
1450 | |
---|
1451 | // -------------------------------------------------------------------------------- |
---|
1452 | // ED4_multi_species_manager |
---|
1453 | // -------------------------------------------------------------------------------- |
---|
1454 | |
---|
1455 | ED4_multi_species_manager::ED4_multi_species_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) : |
---|
1456 | ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group), |
---|
1457 | species(-1), |
---|
1458 | selected_species(-1) |
---|
1459 | { |
---|
1460 | spec = &(multi_species_manager_spec); |
---|
1461 | } |
---|
1462 | |
---|
1463 | ED4_multi_species_manager::~ED4_multi_species_manager() |
---|
1464 | { |
---|
1465 | } |
---|
1466 | |
---|
1467 | int ED4_multi_species_manager::get_no_of_species() { |
---|
1468 | if (!has_valid_counters()) { |
---|
1469 | update_species_counters(); |
---|
1470 | e4_assert(has_valid_counters()); |
---|
1471 | } |
---|
1472 | return species; |
---|
1473 | } |
---|
1474 | |
---|
1475 | int ED4_multi_species_manager::get_no_of_selected_species() { |
---|
1476 | if (!has_valid_counters()) { |
---|
1477 | update_species_counters(); |
---|
1478 | e4_assert(has_valid_counters()); |
---|
1479 | } |
---|
1480 | return selected_species; |
---|
1481 | } |
---|
1482 | |
---|
1483 | void ED4_multi_species_manager::invalidate_species_counters() { |
---|
1484 | if (has_valid_counters()) { |
---|
1485 | species = -1; |
---|
1486 | selected_species = -1; |
---|
1487 | |
---|
1488 | set_refresh(); |
---|
1489 | parent->refresh_requested_by_child(); |
---|
1490 | |
---|
1491 | if (parent->is_group_manager()) { |
---|
1492 | ED4_group_manager *group_man = parent->to_group_manager(); |
---|
1493 | ED4_base *base = group_man->get_defined_level(ED4_L_BRACKET); |
---|
1494 | |
---|
1495 | if (base && base->is_bracket_terminal()) { |
---|
1496 | ED4_bracket_terminal *bracket_term = base->to_bracket_terminal(); |
---|
1497 | |
---|
1498 | bracket_term->set_refresh(); |
---|
1499 | bracket_term->parent->refresh_requested_by_child(); |
---|
1500 | } |
---|
1501 | } |
---|
1502 | |
---|
1503 | ED4_base *pms = get_parent(ED4_L_MULTI_SPECIES); |
---|
1504 | if (pms) { |
---|
1505 | pms->to_multi_species_manager()->invalidate_species_counters(); |
---|
1506 | } |
---|
1507 | } |
---|
1508 | } |
---|
1509 | |
---|
1510 | void ED4_multi_species_manager::set_species_counters(int no_of_species, int no_of_selected) { |
---|
1511 | |
---|
1512 | #if defined(DEBUG) |
---|
1513 | int sp,sel; |
---|
1514 | |
---|
1515 | count_species(&sp, &sel); |
---|
1516 | e4_assert(no_of_species==sp); |
---|
1517 | e4_assert(no_of_selected==sel); |
---|
1518 | #endif |
---|
1519 | |
---|
1520 | e4_assert(no_of_species>=no_of_selected); |
---|
1521 | |
---|
1522 | if (species!=no_of_species || selected_species!=no_of_selected) { |
---|
1523 | int species_diff = no_of_species-species; |
---|
1524 | int selected_diff = no_of_selected-selected_species; |
---|
1525 | int quickSet = 1; |
---|
1526 | |
---|
1527 | if (species==-1 || selected_species==-1) { |
---|
1528 | quickSet = 0; |
---|
1529 | } |
---|
1530 | |
---|
1531 | species = no_of_species; |
---|
1532 | selected_species = no_of_selected; |
---|
1533 | |
---|
1534 | ED4_base *gm = get_parent(ED4_L_GROUP); |
---|
1535 | if (gm) { |
---|
1536 | ED4_bracket_terminal *bracket = gm->to_manager()->search_spec_child_rek(ED4_L_BRACKET)->to_bracket_terminal(); |
---|
1537 | bracket->set_refresh(); |
---|
1538 | bracket->parent->refresh_requested_by_child(); |
---|
1539 | } |
---|
1540 | |
---|
1541 | ED4_base *ms = get_parent(ED4_L_MULTI_SPECIES); |
---|
1542 | if (ms) { |
---|
1543 | ED4_multi_species_manager *parent_multi_species_man = ms->to_multi_species_manager(); |
---|
1544 | |
---|
1545 | if (!quickSet) { |
---|
1546 | parent_multi_species_man->invalidate_species_counters(); |
---|
1547 | } |
---|
1548 | |
---|
1549 | if (parent_multi_species_man->has_valid_counters()) { |
---|
1550 | parent_multi_species_man->set_species_counters(parent_multi_species_man->species+species_diff, |
---|
1551 | parent_multi_species_man->selected_species+selected_diff); |
---|
1552 | } |
---|
1553 | } |
---|
1554 | } |
---|
1555 | } |
---|
1556 | |
---|
1557 | #ifdef DEBUG |
---|
1558 | void ED4_multi_species_manager::count_species(int *speciesPtr, int *selectedPtr) const { |
---|
1559 | int m; |
---|
1560 | int sp = 0; |
---|
1561 | int sel = 0; |
---|
1562 | |
---|
1563 | for (m=0; m<children->members(); m++) { |
---|
1564 | ED4_base *member = children->member(m); |
---|
1565 | |
---|
1566 | if (member->is_group_manager()) { |
---|
1567 | ED4_multi_species_manager *multi_species_man = member->to_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager(); |
---|
1568 | |
---|
1569 | if (!multi_species_man->has_valid_counters()) { |
---|
1570 | int sp1, sel1; |
---|
1571 | |
---|
1572 | multi_species_man->count_species(&sp1, &sel1); |
---|
1573 | sel += sel1; |
---|
1574 | sp += sp1; |
---|
1575 | } |
---|
1576 | else { |
---|
1577 | sel += multi_species_man->get_no_of_selected_species(); |
---|
1578 | sp += multi_species_man->get_no_of_species(); |
---|
1579 | } |
---|
1580 | } |
---|
1581 | else if (member->is_species_manager()) { |
---|
1582 | ED4_species_manager *species_man = member->to_species_manager(); |
---|
1583 | |
---|
1584 | if (!species_man->flag.is_consensus) { |
---|
1585 | ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal(); |
---|
1586 | |
---|
1587 | sp++; |
---|
1588 | if (species_name->flag.selected) { |
---|
1589 | sel++; |
---|
1590 | } |
---|
1591 | } |
---|
1592 | } |
---|
1593 | } |
---|
1594 | |
---|
1595 | *speciesPtr = sp; |
---|
1596 | *selectedPtr = sel; |
---|
1597 | } |
---|
1598 | #endif |
---|
1599 | |
---|
1600 | void ED4_multi_species_manager::update_species_counters() { |
---|
1601 | int m; |
---|
1602 | int sp = 0; |
---|
1603 | int sel = 0; |
---|
1604 | |
---|
1605 | for (m=0; m<children->members(); m++) { |
---|
1606 | ED4_base *member = children->member(m); |
---|
1607 | |
---|
1608 | if (member->is_group_manager()) { |
---|
1609 | ED4_multi_species_manager *multi_species_man = member->to_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager(); |
---|
1610 | |
---|
1611 | if (!multi_species_man->has_valid_counters()) { |
---|
1612 | multi_species_man->update_species_counters(); |
---|
1613 | } |
---|
1614 | sel += multi_species_man->get_no_of_selected_species(); |
---|
1615 | sp += multi_species_man->get_no_of_species(); |
---|
1616 | } |
---|
1617 | else if (member->is_species_manager()) { |
---|
1618 | ED4_species_manager *species_man = member->to_species_manager(); |
---|
1619 | |
---|
1620 | if (!species_man->flag.is_consensus) { |
---|
1621 | ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal(); |
---|
1622 | |
---|
1623 | sp++; |
---|
1624 | if (species_name->flag.selected) { |
---|
1625 | sel++; |
---|
1626 | } |
---|
1627 | } |
---|
1628 | } |
---|
1629 | } |
---|
1630 | set_species_counters(sp, sel); |
---|
1631 | } |
---|
1632 | |
---|
1633 | void ED4_multi_species_manager::select_all_species() { |
---|
1634 | int m; |
---|
1635 | int sp = 0; |
---|
1636 | int sel = 0; |
---|
1637 | |
---|
1638 | for (m=0; m<children->members(); m++) { |
---|
1639 | ED4_base *member = children->member(m); |
---|
1640 | |
---|
1641 | if (member->is_group_manager()) { |
---|
1642 | ED4_multi_species_manager *multi_species_man = member->to_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager(); |
---|
1643 | multi_species_man->select_all_species(); |
---|
1644 | sp += multi_species_man->get_no_of_species(); |
---|
1645 | sel += multi_species_man->get_no_of_selected_species(); |
---|
1646 | } |
---|
1647 | else if (member->is_species_manager()) { |
---|
1648 | ED4_species_manager *species_man = member->to_species_manager(); |
---|
1649 | |
---|
1650 | if (!species_man->flag.is_consensus) { |
---|
1651 | sp++; |
---|
1652 | |
---|
1653 | if (!species_man->flag.is_SAI) { |
---|
1654 | ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal(); |
---|
1655 | |
---|
1656 | sel++; |
---|
1657 | if (!species_name->flag.selected) { |
---|
1658 | ED4_ROOT->add_to_selected(species_name); |
---|
1659 | } |
---|
1660 | } |
---|
1661 | } |
---|
1662 | } |
---|
1663 | } |
---|
1664 | set_species_counters(sp, sel); |
---|
1665 | } |
---|
1666 | void ED4_multi_species_manager::deselect_all_species() { |
---|
1667 | int m; |
---|
1668 | int sp = 0; |
---|
1669 | |
---|
1670 | for (m=0; m<children->members(); m++) { |
---|
1671 | ED4_base *member = children->member(m); |
---|
1672 | |
---|
1673 | if (member->is_group_manager()) { |
---|
1674 | ED4_multi_species_manager *multi_species_man = member->to_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager(); |
---|
1675 | multi_species_man->deselect_all_species(); |
---|
1676 | sp += multi_species_man->get_no_of_species(); |
---|
1677 | } |
---|
1678 | else if (member->is_species_manager()) { |
---|
1679 | ED4_species_manager *species_man = member->to_species_manager(); |
---|
1680 | |
---|
1681 | if (!species_man->flag.is_consensus) { |
---|
1682 | sp++; |
---|
1683 | ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal(); |
---|
1684 | |
---|
1685 | if (species_name->flag.selected) { |
---|
1686 | ED4_ROOT->remove_from_selected(species_name); |
---|
1687 | } |
---|
1688 | } |
---|
1689 | } |
---|
1690 | else { |
---|
1691 | e4_assert(!member->is_manager()); |
---|
1692 | } |
---|
1693 | } |
---|
1694 | set_species_counters(sp, 0); |
---|
1695 | } |
---|
1696 | void ED4_multi_species_manager::invert_selection_of_all_species() { |
---|
1697 | int m; |
---|
1698 | int sp = 0; |
---|
1699 | int sel = 0; |
---|
1700 | |
---|
1701 | for (m=0; m<children->members(); m++) { |
---|
1702 | ED4_base *member = children->member(m); |
---|
1703 | |
---|
1704 | if (member->is_group_manager()) { |
---|
1705 | ED4_multi_species_manager *multi_species_man = member->to_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager(); |
---|
1706 | multi_species_man->invert_selection_of_all_species(); |
---|
1707 | sp += multi_species_man->get_no_of_species(); |
---|
1708 | sel += multi_species_man->get_no_of_selected_species(); |
---|
1709 | } |
---|
1710 | else if (member->is_species_manager()) { |
---|
1711 | ED4_species_manager *species_man = member->to_species_manager(); |
---|
1712 | |
---|
1713 | if (!species_man->flag.is_consensus) { |
---|
1714 | sp++; |
---|
1715 | if (!species_man->flag.is_SAI) { |
---|
1716 | ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal(); |
---|
1717 | |
---|
1718 | if (species_name->flag.selected) { |
---|
1719 | ED4_ROOT->remove_from_selected(species_name); |
---|
1720 | } |
---|
1721 | else { |
---|
1722 | ED4_ROOT->add_to_selected(species_name); |
---|
1723 | sel++; |
---|
1724 | } |
---|
1725 | } |
---|
1726 | } |
---|
1727 | } |
---|
1728 | else { |
---|
1729 | e4_assert(!member->is_manager()); |
---|
1730 | } |
---|
1731 | } |
---|
1732 | |
---|
1733 | e4_assert(get_no_of_selected_species()==sel); |
---|
1734 | e4_assert(get_no_of_species()==sp); |
---|
1735 | } |
---|
1736 | void ED4_multi_species_manager::select_marked_species(int select) { |
---|
1737 | int m; |
---|
1738 | int sp = 0; |
---|
1739 | int sel = 0; |
---|
1740 | |
---|
1741 | for (m=0; m<children->members(); m++) { |
---|
1742 | ED4_base *member = children->member(m); |
---|
1743 | |
---|
1744 | if (member->is_group_manager()) { |
---|
1745 | ED4_multi_species_manager *multi_species_man = member->to_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager(); |
---|
1746 | multi_species_man->select_marked_species(select); |
---|
1747 | sp += multi_species_man->get_no_of_species(); |
---|
1748 | sel += multi_species_man->get_no_of_selected_species(); |
---|
1749 | } |
---|
1750 | else if (member->is_species_manager()) { |
---|
1751 | ED4_species_manager *species_man = member->to_species_manager(); |
---|
1752 | |
---|
1753 | if (!species_man->flag.is_consensus) { |
---|
1754 | sp++; |
---|
1755 | |
---|
1756 | GBDATA *gbd = species_man->get_species_pointer(); |
---|
1757 | e4_assert(gbd); |
---|
1758 | int is_marked = GB_read_flag(gbd); |
---|
1759 | |
---|
1760 | ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal(); |
---|
1761 | if (is_marked) { |
---|
1762 | if (select) { // select marked |
---|
1763 | if (!species_man->flag.is_SAI) { |
---|
1764 | if (!species_name->flag.selected) { |
---|
1765 | ED4_ROOT->add_to_selected(species_name); |
---|
1766 | } |
---|
1767 | sel++; |
---|
1768 | } |
---|
1769 | } |
---|
1770 | else { // de-select marked |
---|
1771 | if (species_name->flag.selected) { |
---|
1772 | ED4_ROOT->remove_from_selected(species_name); |
---|
1773 | } |
---|
1774 | } |
---|
1775 | } |
---|
1776 | else { |
---|
1777 | if (species_name->flag.selected) { |
---|
1778 | sel++; |
---|
1779 | } |
---|
1780 | } |
---|
1781 | } |
---|
1782 | } |
---|
1783 | else { |
---|
1784 | e4_assert(!member->is_manager()); |
---|
1785 | } |
---|
1786 | } |
---|
1787 | set_species_counters(sp, sel); |
---|
1788 | } |
---|
1789 | void ED4_multi_species_manager::mark_selected_species(int mark) { |
---|
1790 | int m; |
---|
1791 | int sp = 0; |
---|
1792 | int sel = 0; |
---|
1793 | |
---|
1794 | for (m=0; m<children->members(); m++) { |
---|
1795 | ED4_base *member = children->member(m); |
---|
1796 | |
---|
1797 | if (member->is_group_manager()) { |
---|
1798 | ED4_multi_species_manager *multi_species_man = member->to_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager(); |
---|
1799 | multi_species_man->mark_selected_species(mark); |
---|
1800 | sp += multi_species_man->get_no_of_species(); |
---|
1801 | sel += multi_species_man->get_no_of_selected_species(); |
---|
1802 | } |
---|
1803 | else if (member->is_species_manager()) { |
---|
1804 | ED4_species_manager *species_man = member->to_species_manager(); |
---|
1805 | |
---|
1806 | if (!species_man->flag.is_consensus) { |
---|
1807 | ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal(); |
---|
1808 | |
---|
1809 | sp++; |
---|
1810 | if (species_name->flag.selected) { |
---|
1811 | GBDATA *gbd = species_man->get_species_pointer(); |
---|
1812 | e4_assert(gbd); |
---|
1813 | |
---|
1814 | #if defined(ASSERTION_USED) |
---|
1815 | GB_ERROR error = |
---|
1816 | #endif // ASSERTION_USED |
---|
1817 | GB_write_flag(gbd, mark ? 1 : 0); |
---|
1818 | e4_assert(!error); |
---|
1819 | |
---|
1820 | sel++; |
---|
1821 | } |
---|
1822 | } |
---|
1823 | } |
---|
1824 | else { |
---|
1825 | e4_assert(!member->is_manager()); |
---|
1826 | } |
---|
1827 | } |
---|
1828 | set_species_counters(sp, sel); |
---|
1829 | } |
---|
1830 | |
---|
1831 | ED4_species_manager *ED4_multi_species_manager::get_consensus_manager() const { |
---|
1832 | ED4_species_manager *consensus_manager = 0; |
---|
1833 | |
---|
1834 | for (int i=0; i<children->members(); i++) { |
---|
1835 | ED4_base *member = children->member(i); |
---|
1836 | if (member->flag.is_consensus) { |
---|
1837 | consensus_manager = member->to_species_manager(); |
---|
1838 | break; |
---|
1839 | } |
---|
1840 | } |
---|
1841 | |
---|
1842 | return consensus_manager; |
---|
1843 | } |
---|
1844 | |
---|
1845 | ED4_terminal *ED4_multi_species_manager::get_consensus_terminal() { |
---|
1846 | // returns the consensus-name-terminal of a multi_species manager |
---|
1847 | ED4_species_manager *consensus_man = get_consensus_manager(); |
---|
1848 | return consensus_man ? consensus_man->children->member(0)->to_terminal() : 0; |
---|
1849 | } |
---|
1850 | |
---|
1851 | // -------------------------------------------------------------------------------- |
---|
1852 | // ED4_species_manager |
---|
1853 | // -------------------------------------------------------------------------------- |
---|
1854 | |
---|
1855 | ED4_species_manager::ED4_species_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) : |
---|
1856 | ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group) |
---|
1857 | { |
---|
1858 | spec = &(species_manager_spec); |
---|
1859 | } |
---|
1860 | |
---|
1861 | #if defined(DEBUG) |
---|
1862 | // #define DEBUG_SPMAN_CALLBACKS |
---|
1863 | #endif // DEBUG |
---|
1864 | |
---|
1865 | |
---|
1866 | ED4_species_manager::~ED4_species_manager() { |
---|
1867 | #if defined(DEBUG_SPMAN_CALLBACKS) |
---|
1868 | if (!callbacks.empty()) { |
---|
1869 | printf("this=%p - non-empty callbacks\n", (char*)this); |
---|
1870 | } |
---|
1871 | #endif // DEBUG |
---|
1872 | |
---|
1873 | e4_assert(callbacks.empty()); |
---|
1874 | // if assertion fails, callbacks are still bound to this manager. |
---|
1875 | // You need to remove all callbacks at two places: |
---|
1876 | // 1. ED4_species_manager::remove_all_callbacks |
---|
1877 | // 2. ED4_quit_editor() |
---|
1878 | } |
---|
1879 | |
---|
1880 | void ED4_species_manager::add_sequence_changed_cb(ED4_species_manager_cb cb, AW_CL cd) { |
---|
1881 | #if defined(DEBUG_SPMAN_CALLBACKS) |
---|
1882 | printf("this=%p - add_sequence_changed_cb\n", (char*)this); |
---|
1883 | #endif // DEBUG |
---|
1884 | callbacks.insert(ED4_species_manager_cb_data(cb, cd)); |
---|
1885 | } |
---|
1886 | |
---|
1887 | void ED4_species_manager::remove_sequence_changed_cb(ED4_species_manager_cb cb, AW_CL cd) { |
---|
1888 | e4_assert(this); |
---|
1889 | #if defined(DEBUG_SPMAN_CALLBACKS) |
---|
1890 | printf("this=%p - remove_sequence_changed_cb\n", (char*)this); |
---|
1891 | #endif // DEBUG |
---|
1892 | callbacks.erase(ED4_species_manager_cb_data(cb, cd)); |
---|
1893 | } |
---|
1894 | |
---|
1895 | void ED4_species_manager::do_callbacks() { |
---|
1896 | for (std::set<ED4_species_manager_cb_data>::iterator cb = callbacks.begin(); cb != callbacks.end(); ++cb) { |
---|
1897 | cb->call(this); |
---|
1898 | } |
---|
1899 | } |
---|
1900 | |
---|
1901 | void ED4_species_manager::remove_all_callbacks() { |
---|
1902 | if (!callbacks.empty()) { |
---|
1903 | for (ED4_window *ew = ED4_ROOT->first_window; ew; ew = ew->next) { |
---|
1904 | ED4_cursor& cursor = ew->cursor; |
---|
1905 | ED4_base *cursors_species_manager = cursor.owner_of_cursor->get_parent(ED4_L_SPECIES); |
---|
1906 | if (cursors_species_manager == this) { |
---|
1907 | cursor.invalidate_base_position(); // removes the callback |
---|
1908 | } |
---|
1909 | } |
---|
1910 | e4_assert(callbacks.empty()); |
---|
1911 | } |
---|
1912 | } |
---|
1913 | |
---|
1914 | |
---|
1915 | // -------------------------------------------------------------------------------- |
---|
1916 | // ED4_group_manager:: |
---|
1917 | // -------------------------------------------------------------------------------- |
---|
1918 | |
---|
1919 | ED4_group_manager::ED4_group_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) : |
---|
1920 | ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group), |
---|
1921 | my_table(0) |
---|
1922 | { |
---|
1923 | spec = &(group_manager_spec); |
---|
1924 | } |
---|
1925 | |
---|
1926 | ED4_group_manager::~ED4_group_manager() { |
---|
1927 | } |
---|
1928 | |
---|
1929 | // -------------------------------------------------------------------------------- |
---|
1930 | // ED4_remap:: |
---|
1931 | // -------------------------------------------------------------------------------- |
---|
1932 | |
---|
1933 | ED4_remap::ED4_remap() { |
---|
1934 | mode = ED4_RM_NONE; |
---|
1935 | show_above_percent = 0; |
---|
1936 | |
---|
1937 | sequence_table_len = 1; |
---|
1938 | screen_table_len = 1; |
---|
1939 | |
---|
1940 | screen_to_sequence_tab = new int[1]; screen_to_sequence_tab[0] = 0; |
---|
1941 | sequence_to_screen_tab = new int[1]; sequence_to_screen_tab[0] = 0; |
---|
1942 | |
---|
1943 | sequence_len = 0; |
---|
1944 | MAXSEQUENCECHARACTERLENGTH = screen_len = 0; |
---|
1945 | |
---|
1946 | changed = 0; |
---|
1947 | update_needed = 1; |
---|
1948 | |
---|
1949 | } |
---|
1950 | ED4_remap::~ED4_remap() { |
---|
1951 | delete [] screen_to_sequence_tab; |
---|
1952 | delete [] sequence_to_screen_tab; |
---|
1953 | } |
---|
1954 | int ED4_remap::screen_to_sequence(int screen_pos) const { |
---|
1955 | if (size_t(screen_pos)>=screen_len) { |
---|
1956 | return screen_to_sequence_tab[screen_len-1]; |
---|
1957 | } |
---|
1958 | e4_assert(screen_pos>=0 && size_t(screen_pos)<screen_len); |
---|
1959 | return screen_to_sequence_tab[screen_pos]; |
---|
1960 | } |
---|
1961 | int ED4_remap::sequence_to_screen(int sequence_pos) const { |
---|
1962 | e4_assert(sequence_pos>=0 && size_t(sequence_pos)<=sequence_len); |
---|
1963 | return sequence_to_screen_tab[sequence_pos]; |
---|
1964 | } |
---|
1965 | int ED4_remap::clipped_sequence_to_screen(int sequence_pos) const { |
---|
1966 | if (sequence_pos<0) { |
---|
1967 | sequence_pos = 0; |
---|
1968 | } |
---|
1969 | else if (size_t(sequence_pos)>sequence_len) { |
---|
1970 | sequence_pos = sequence_len; |
---|
1971 | } |
---|
1972 | |
---|
1973 | return sequence_to_screen_tab[sequence_pos]; |
---|
1974 | } |
---|
1975 | int ED4_remap::sequence_to_screen_clipped(int sequence_pos) const { |
---|
1976 | int scr_pos = sequence_to_screen(sequence_pos); |
---|
1977 | if (scr_pos<0) scr_pos = -scr_pos; |
---|
1978 | return scr_pos; |
---|
1979 | } |
---|
1980 | inline void ED4_remap::set_sequence_to_screen(int pos, int newVal) { |
---|
1981 | e4_assert(pos>=0 && size_t(pos)<sequence_table_len); |
---|
1982 | if (sequence_to_screen_tab[pos]!=newVal) { |
---|
1983 | sequence_to_screen_tab[pos] = newVal; |
---|
1984 | changed = 1; |
---|
1985 | } |
---|
1986 | } |
---|
1987 | void ED4_remap::mark_compile_needed() { |
---|
1988 | if (mode!=ED4_RM_NONE && !update_needed) { |
---|
1989 | update_needed = 1; |
---|
1990 | if (ED4_ROOT && ED4_ROOT->root_group_man) { // test if root_group_man already exists |
---|
1991 | ED4_ROOT->root_group_man->resize_requested_by_child(); // remapping is recompiled while re-displaying the root_group_manager |
---|
1992 | } |
---|
1993 | } |
---|
1994 | } |
---|
1995 | void ED4_remap::mark_compile_needed_force() { |
---|
1996 | if (!update_needed) { |
---|
1997 | update_needed = 1; |
---|
1998 | if (ED4_ROOT && ED4_ROOT->root_group_man) { // test if root_group_man already exists |
---|
1999 | ED4_ROOT->root_group_man->resize_requested_by_child(); // remapping is recompiled while re-displaying the root_group_manager |
---|
2000 | } |
---|
2001 | } |
---|
2002 | } |
---|
2003 | GB_ERROR ED4_remap::compile(ED4_root_group_manager *gm) |
---|
2004 | { |
---|
2005 | e4_assert(update_needed); |
---|
2006 | |
---|
2007 | const ED4_char_table& table = gm->table(); |
---|
2008 | size_t i,j; |
---|
2009 | |
---|
2010 | changed = 0; // is changed by set_sequence_to_screen |
---|
2011 | update_needed = 0; |
---|
2012 | |
---|
2013 | sequence_len = table.table('A').size(); // take size of any table |
---|
2014 | if ((sequence_len+1) > sequence_table_len) { |
---|
2015 | delete [] sequence_to_screen_tab; |
---|
2016 | sequence_to_screen_tab = new int[sequence_table_len = sequence_len+1]; |
---|
2017 | memset(sequence_to_screen_tab, 0, sequence_table_len*sizeof(int)); |
---|
2018 | changed = 1; |
---|
2019 | } |
---|
2020 | |
---|
2021 | int above_percent; |
---|
2022 | switch (gm->remap()->get_mode()) { |
---|
2023 | default: e4_assert(0); |
---|
2024 | case ED4_RM_NONE: { |
---|
2025 | dont_map: |
---|
2026 | for (i=0; i<sequence_table_len; i++) { |
---|
2027 | set_sequence_to_screen(i,i); |
---|
2028 | } |
---|
2029 | screen_len = sequence_len; |
---|
2030 | break; |
---|
2031 | } |
---|
2032 | // case ED4_RM_SHOW_ABOVE_30: { |
---|
2033 | // above_percent = 30; |
---|
2034 | // goto calc_percent; |
---|
2035 | // } |
---|
2036 | case ED4_RM_SHOW_ABOVE: { |
---|
2037 | above_percent = show_above_percent; |
---|
2038 | goto calc_percent; |
---|
2039 | } |
---|
2040 | case ED4_RM_MAX_ALIGN: |
---|
2041 | case ED4_RM_MAX_EDIT: { |
---|
2042 | above_percent = 0; |
---|
2043 | calc_percent: |
---|
2044 | for (i=0,j=0; i<(sequence_table_len-1); i++) { |
---|
2045 | int bases; |
---|
2046 | int gaps; |
---|
2047 | |
---|
2048 | table.bases_and_gaps_at(i, &bases, &gaps); |
---|
2049 | |
---|
2050 | if (bases==0 && gaps==0) { // special case (should occur only after inserting columns) |
---|
2051 | set_sequence_to_screen(i, -j); // hide |
---|
2052 | } |
---|
2053 | else { |
---|
2054 | int percent = (int)((bases*100L)/table.added_sequences()); |
---|
2055 | |
---|
2056 | e4_assert(percent==((bases*100)/(bases+gaps))); |
---|
2057 | |
---|
2058 | if (bases && percent>=above_percent) { |
---|
2059 | set_sequence_to_screen(i,j++); |
---|
2060 | }else{ |
---|
2061 | set_sequence_to_screen(i, -j); |
---|
2062 | } |
---|
2063 | } |
---|
2064 | } |
---|
2065 | for (;i<sequence_table_len;i++) { // fill rest of table |
---|
2066 | set_sequence_to_screen(i,j++); |
---|
2067 | } |
---|
2068 | screen_len = j; |
---|
2069 | break; |
---|
2070 | } |
---|
2071 | case ED4_RM_DYNAMIC_GAPS: { |
---|
2072 | for (i=0,j=0; i<(sequence_table_len-1); i++) { |
---|
2073 | int bases; |
---|
2074 | |
---|
2075 | table.bases_and_gaps_at(i, &bases, 0); |
---|
2076 | if (bases) { |
---|
2077 | set_sequence_to_screen(i,j++); |
---|
2078 | } |
---|
2079 | else { |
---|
2080 | size_t k = i+1; |
---|
2081 | |
---|
2082 | while (k<(sequence_table_len-1)) { |
---|
2083 | int bases2; |
---|
2084 | |
---|
2085 | table.bases_and_gaps_at(k, &bases2, 0); |
---|
2086 | if (bases2) { |
---|
2087 | break; |
---|
2088 | } |
---|
2089 | k++; |
---|
2090 | } |
---|
2091 | |
---|
2092 | int gaps = k-i; |
---|
2093 | int shown_gapsize; |
---|
2094 | |
---|
2095 | if (gaps<100) { |
---|
2096 | shown_gapsize = gaps/10 + 1; |
---|
2097 | } |
---|
2098 | else if (gaps<1000) { |
---|
2099 | shown_gapsize = gaps/100 + 10; |
---|
2100 | } |
---|
2101 | else { |
---|
2102 | shown_gapsize = gaps/1000 + 19; |
---|
2103 | } |
---|
2104 | |
---|
2105 | for (; i<k && shown_gapsize; i++,shown_gapsize--) { |
---|
2106 | set_sequence_to_screen(i,j++); |
---|
2107 | } |
---|
2108 | for (; i<k; i++) { |
---|
2109 | set_sequence_to_screen(i,-j); |
---|
2110 | } |
---|
2111 | i--; |
---|
2112 | } |
---|
2113 | } |
---|
2114 | for (;i<sequence_table_len;i++) { |
---|
2115 | set_sequence_to_screen(i,j++); // fill rest of table |
---|
2116 | } |
---|
2117 | screen_len = j; |
---|
2118 | break; |
---|
2119 | } |
---|
2120 | } |
---|
2121 | |
---|
2122 | if (sequence_table_len) { |
---|
2123 | if (!screen_len && sequence_len) { |
---|
2124 | goto dont_map; |
---|
2125 | } |
---|
2126 | if ((screen_len+1) > screen_table_len) { |
---|
2127 | delete [] screen_to_sequence_tab; |
---|
2128 | screen_to_sequence_tab = new int[screen_table_len = screen_len+1]; |
---|
2129 | } |
---|
2130 | memset(screen_to_sequence_tab, 0, sizeof(int)*screen_table_len); |
---|
2131 | for (i=0; i<sequence_table_len; i++) { |
---|
2132 | int screen_pos = sequence_to_screen_tab[i]; |
---|
2133 | if (screen_pos>=0) { |
---|
2134 | screen_to_sequence_tab[screen_pos] = i; |
---|
2135 | } |
---|
2136 | } |
---|
2137 | } |
---|
2138 | |
---|
2139 | if (sequence_len>1) { |
---|
2140 | MAXSEQUENCECHARACTERLENGTH = sequence_len; |
---|
2141 | } |
---|
2142 | |
---|
2143 | return NULL; |
---|
2144 | } |
---|
2145 | |
---|
2146 | // -------------------------------------------------------------------------------- |
---|
2147 | // ED4_root_group_manager:: |
---|
2148 | // -------------------------------------------------------------------------------- |
---|
2149 | |
---|
2150 | ED4_root_group_manager::ED4_root_group_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) |
---|
2151 | : ED4_group_manager(temp_id,x,y,width,height,temp_parent), |
---|
2152 | my_remap() |
---|
2153 | { |
---|
2154 | spec = &(root_group_manager_spec); |
---|
2155 | |
---|
2156 | AW_root *awr = ED4_ROOT->aw_root; |
---|
2157 | my_remap.set_mode((ED4_remap_mode)awr->awar(ED4_AWAR_COMPRESS_SEQUENCE_TYPE)->read_int(), |
---|
2158 | awr->awar(ED4_AWAR_COMPRESS_SEQUENCE_PERCENT)->read_int()); |
---|
2159 | my_remap.mark_compile_needed_force(); |
---|
2160 | } |
---|
2161 | |
---|
2162 | ED4_root_group_manager::~ED4_root_group_manager() { |
---|
2163 | } |
---|
2164 | |
---|
2165 | int ED4_root_group_manager::update_remap() |
---|
2166 | { |
---|
2167 | int remapped = 0; |
---|
2168 | |
---|
2169 | if (my_remap.compile_needed()) { |
---|
2170 | my_remap.compile(this); |
---|
2171 | if (my_remap.was_changed()) { |
---|
2172 | ED4_ROOT->main_manager->set_refresh(); |
---|
2173 | ED4_ROOT->main_manager->refresh_requested_by_child(); |
---|
2174 | remapped = 1; |
---|
2175 | } |
---|
2176 | } |
---|
2177 | |
---|
2178 | return remapped; |
---|
2179 | } |
---|
2180 | |
---|
2181 | // -------------------------------------------------------------------------------- |
---|
2182 | // ED4_multi_species_manager:: |
---|
2183 | // -------------------------------------------------------------------------------- |
---|
2184 | |
---|
2185 | ED4_multi_sequence_manager::ED4_multi_sequence_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) |
---|
2186 | : ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group) |
---|
2187 | { |
---|
2188 | spec = &(multi_sequence_manager_spec); |
---|
2189 | } |
---|
2190 | |
---|
2191 | ED4_multi_sequence_manager::~ED4_multi_sequence_manager() |
---|
2192 | { |
---|
2193 | } |
---|
2194 | |
---|
2195 | ED4_sequence_manager::ED4_sequence_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) |
---|
2196 | : ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group) |
---|
2197 | { |
---|
2198 | spec = &(sequence_manager_spec); |
---|
2199 | } |
---|
2200 | |
---|
2201 | ED4_sequence_manager::~ED4_sequence_manager() { |
---|
2202 | } |
---|
2203 | |
---|
2204 | |
---|
2205 | ED4_multi_name_manager::ED4_multi_name_manager(const char *temp_id,AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) |
---|
2206 | : ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group) |
---|
2207 | { |
---|
2208 | spec = &(multi_name_manager_spec); |
---|
2209 | } |
---|
2210 | |
---|
2211 | ED4_multi_name_manager::~ED4_multi_name_manager() |
---|
2212 | { |
---|
2213 | } |
---|
2214 | |
---|
2215 | ED4_name_manager::ED4_name_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool temp_is_group) |
---|
2216 | : ED4_manager(temp_id, x, y, width, height, temp_parent, temp_is_group) |
---|
2217 | { |
---|
2218 | spec = &(name_manager_spec); |
---|
2219 | } |
---|
2220 | |
---|
2221 | ED4_name_manager::~ED4_name_manager() { |
---|
2222 | } |
---|
2223 | |
---|