/[eiffelstudio]/branches/Eiffel_57_docking/Src/Eiffel/interface/new_graphical/case_tool/eiffel_studio/class_graph.e
ViewVC logotype

Contents of /branches/Eiffel_57_docking/Src/Eiffel/interface/new_graphical/case_tool/eiffel_studio/class_graph.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62171 - (show annotations)
Tue Aug 1 01:27:17 2006 UTC (13 years, 4 months ago) by larryl
File size: 21013 byte(s)
First commit docking tabbed Eiffel Studio.
1 indexing
2 description: "Objects that is a graph of classes"
3 legal: "See notice at end of class."
4 status: "See notice at end of class."
5 author: ""
6 date: "$Date$"
7 revision: "$Revision$"
8
9 class
10 ES_CLASS_GRAPH
11
12 inherit
13 ES_GRAPH
14 redefine
15 synchronize
16 end
17
18 create
19 make
20
21 feature {NONE} -- Initialization
22
23 make (a_tool: like context_editor) is
24 -- Create a CLASS_GRAPH in `a_tool'.
25 require
26 a_tool_not_void: a_tool /= Void
27 do
28 default_create
29 context_editor := a_tool
30 ancestor_depth := 1
31 descendant_depth := 1
32 client_depth := 0
33 supplier_depth := 0
34
35 include_all_classes_of_cluster := False
36 include_only_classes_of_cluster := False
37 ensure
38 set: context_editor = a_tool
39 end
40
41 feature -- Access
42
43 center_class: ES_CLASS
44 -- Center class of this graph.
45
46 ancestor_depth: INTEGER
47 -- Depth of ancestor links.
48
49 descendant_depth: INTEGER
50 -- Depth of descendant links.
51
52 client_depth: INTEGER
53 -- Depth of client links.
54
55 supplier_depth: INTEGER
56 -- Depth of supplier links.
57
58 feature -- Status report.
59
60 include_all_classes_of_cluster: BOOLEAN
61 -- Do all the classes in same cluster as `center_class' have to be in `Current?
62
63 include_only_classes_of_cluster: BOOLEAN
64 -- Do all the classes in `Current' have to be in same cluster as `center_class'?
65
66 feature -- Status settings.
67
68 set_include_all_classes_of_cluster (b: BOOLEAN) is
69 -- Set `include_all_classes_of_cluster' to `b'.
70 do
71 include_all_classes_of_cluster := b
72 ensure
73 set: include_all_classes_of_cluster = b
74 end
75
76 set_include_only_classes_of_cluster (b: BOOLEAN) is
77 -- Set `include_only_classes_in_cluster' to `b'.
78 do
79 include_only_classes_of_cluster := b
80 ensure
81 set: include_only_classes_of_cluster = b
82 end
83
84 feature -- Element change
85
86 set_ancestor_depth (i: INTEGER) is
87 -- Set `ancestor_depth' to `i'.
88 require
89 positive_depth: i >= 0
90 do
91 ancestor_depth := i
92 ensure
93 assigned: ancestor_depth = i
94 end
95
96 set_descendant_depth (i: INTEGER) is
97 -- Set `descendant_depth' to `i'.
98 require
99 positive_depth: i >= 0
100 do
101 descendant_depth := i
102 ensure
103 assigned: descendant_depth = i
104 end
105
106 set_client_depth (i: INTEGER) is
107 -- Set `client_depth' to `i'.
108 require
109 positive_depth: i >= 0
110 do
111 client_depth := i
112 ensure
113 assigned: client_depth = i
114 end
115
116 set_supplier_depth (i: INTEGER) is
117 -- Set `supplier_depth' to `i'.
118 require
119 positive_depth: i >= 0
120 do
121 supplier_depth := i
122 ensure
123 assigned: supplier_depth = i
124 end
125
126 set_center_class (a_center_class: like center_class) is
127 -- Set `center_class' to `a_center_class'.
128 require
129 a_center_class_not_void: a_center_class /= Void
130 do
131 center_class := a_center_class
132 ensure
133 center_class_set: center_class = a_center_class
134 end
135
136 explore_center_class is
137 -- Explore relations according to `center_class'.
138 require
139 center_class_not_void: center_class /= Void
140 do
141 wipe_out
142 add_node (center_class)
143 if include_all_classes_of_cluster then
144 include_all_classes (center_class.class_i.group)
145 end
146 explore_relations
147 add_node_relations (center_class)
148 remove_unneeded_items
149 end
150
151 set_new_center_class (a_center_class: like center_class) is
152 -- Set `center_class' to `a_center_class' add not
153 -- relations not yet there, remove relations too
154 -- far away.
155 require
156 a_center_class_not_void: a_center_class /= Void
157 center_class_not_void: center_class /= Void
158 do
159 create last_created_classes.make (10)
160 if not has_node (a_center_class) then
161 add_node (a_center_class)
162 end
163 disable_reachable_classes (center_class)
164 center_class.disable_needed_on_diagram
165 disable_all_links (center_class.internal_links)
166 center_class := a_center_class
167 center_class.enable_needed_on_diagram
168 add_node_relations (center_class)
169
170 explore_ancestors (center_class.class_i, ancestor_depth, False)
171 explore_descendants (center_class.class_i, descendant_depth, False)
172 explore_clients (center_class, client_depth, False)
173 explore_suppliers (center_class, supplier_depth, False)
174 end
175
176 feature {EB_CONTEXT_EDITOR} -- Synchronization
177
178 synchronize is
179 -- Contexts need to be updated because of recompilation
180 -- or similar action that needs resynchronization.
181 do
182 Precursor {ES_GRAPH}
183 if center_class /= Void and then not has_node (center_class) then
184 if not center_class.is_needed_on_diagram then
185 -- Fake the class is still there but don't show it
186 add_node (center_class)
187 add_node_relations (center_class)
188 disable_all_links (center_class.links)
189 -- else
190 -- The class must have been deleted/or renamed and can't be found anymore
191 -- The stone will be set to Void and the diagram is erased.
192 end
193 end
194 end
195
196 feature {EB_CONTEXT_DIAGRAM_COMMAND} -- Implementation
197
198 explore_relations is
199 -- Explore relations of `center_class'.
200 local
201 nb_of_items: INTEGER
202 l_status_bar: EB_DEVELOPMENT_WINDOW_STATUS_BAR
203 do
204 nb_of_items := number_of_ancestors (center_class.class_i, ancestor_depth) +
205 number_of_descendants (center_class.class_i, descendant_depth) +
206 number_of_clients (center_class.class_i, client_depth) +
207 number_of_suppliers (center_class.class_i, supplier_depth)
208
209 l_status_bar := context_editor.develop_window.status_bar
210 l_status_bar.reset_progress_bar_with_range (0 |..| nb_of_items)
211
212 l_status_bar.display_message ("Exploring ancestors of " + center_class.name)
213 explore_ancestors (center_class.class_i, ancestor_depth, True)
214
215 l_status_bar.display_message ("Exploring descendants of " + center_class.name)
216 explore_descendants (center_class.class_i, descendant_depth, True)
217
218 l_status_bar.display_message ("Exploring clients of " + center_class.name)
219 explore_clients (center_class, client_depth, True)
220
221 l_status_bar.display_message ("Exploring suppliers of " + center_class.name)
222 explore_suppliers (center_class, supplier_depth, True)
223 end
224
225 number_of_ancestors (a_class: CLASS_I; depth: INTEGER): INTEGER is
226 -- Calculate number of ancestors of `a_class' until `depth' is reached.
227 require
228 a_class_not_void: a_class /= Void
229 local
230 l: FIXED_LIST [CL_TYPE_A]
231 ci: CLASS_I
232 do
233 if depth > 0 and then a_class.compiled then
234 l := a_class.compiled_class.parents
235 if l /= Void then
236 from
237 l.start
238 until
239 l.after
240 loop
241 ci := l.item.associated_class.lace_class
242 Result := Result + number_of_ancestors (ci, depth - 1) + 1
243 l.forth
244 end
245 end
246 end
247 end
248
249 explore_ancestors (a_class: CLASS_I; depth: INTEGER; progress_bar: BOOLEAN) is
250 -- Add ancestors of `a_class' until `depth' is reached.
251 require
252 a_class_not_void: a_class /= Void
253 local
254 l: FIXED_LIST [CL_TYPE_A]
255 ci: CLASS_I
256 l_status_bar: EB_DEVELOPMENT_WINDOW_STATUS_BAR
257 do
258 if depth > 0 and then a_class.compiled then
259 l := a_class.compiled_class.parents
260 if l /= Void then
261 from
262 if progress_bar then
263 l_status_bar := context_editor.develop_window.status_bar
264 end
265 l.start
266 until
267 l.after
268 loop
269 ci := l.item.associated_class.lace_class
270 add_class (ci)
271 explore_ancestors (ci, depth - 1, progress_bar)
272 if progress_bar then
273 l_status_bar.display_progress_value (
274 l_status_bar.current_progress_value + 1
275 )
276 end
277 l.forth
278 end
279 end
280 end
281 end
282
283 number_of_descendants (a_class: CLASS_I; depth: INTEGER): INTEGER is
284 -- Add descendants of `a_class' until `depth' is reached.
285 require
286 a_class_not_void: a_class /= Void
287 local
288 l: LINEAR [CLASS_C]
289 ci: CLASS_I
290 do
291 if depth > 0 and then a_class.compiled then
292 l := a_class.compiled_class.descendants
293 from
294 l.start
295 until
296 l.after
297 loop
298 ci := l.item.lace_class
299 Result := Result + number_of_descendants (ci, depth - 1) + 1
300 l.forth
301 end
302 end
303 end
304
305 explore_descendants (a_class: CLASS_I; depth: INTEGER; progress_bar: BOOLEAN) is
306 -- Add descendants of `a_class' until `depth' is reached.
307 require
308 a_class_not_void: a_class /= Void
309 local
310 l: ARRAYED_LIST [CLASS_C]
311 ci: CLASS_I
312 i, nb: INTEGER
313 l_status_bar: EB_DEVELOPMENT_WINDOW_STATUS_BAR
314 do
315 if depth > 0 and then a_class.compiled then
316 l := a_class.compiled_class.descendants
317 from
318 i := 1
319 nb := l.count
320 if progress_bar then
321 l_status_bar := context_editor.develop_window.status_bar
322 end
323 until
324 i > nb
325 loop
326 ci := l.i_th (i).lace_class
327 add_class (ci)
328 explore_descendants (ci, depth - 1, progress_bar)
329 if progress_bar then
330 l_status_bar.display_progress_value (
331 l_status_bar.current_progress_value + 1
332 )
333 end
334 i := i + 1
335 end
336 end
337 end
338
339 number_of_clients (a_class: CLASS_I; depth: INTEGER): INTEGER is
340 -- Add clients of `a_class' until `depth' is reached.
341 require
342 a_class_not_void: a_class /= Void
343 local
344 l: ARRAYED_LIST [CLASS_C]
345 ci: CLASS_I
346 i, nb: INTEGER
347 do
348 if depth > 0 and then a_class.is_compiled then
349 l := a_class.compiled_class.syntactical_clients
350 from
351 i := 1
352 nb := l.count
353 until
354 i > nb
355 loop
356 ci := l.i_th (i).lace_class
357 Result := Result + number_of_clients (ci, depth - 1) + 1
358 i := i + 1
359 end
360 end
361 end
362
363 explore_clients (a_class: ES_CLASS; depth: INTEGER; progress_bar: BOOLEAN) is
364 -- Add clients of `a_class' until `depth' is reached.
365 require
366 a_class_not_void: a_class /= Void
367 local
368 l: ARRAYED_LIST [CLASS_C]
369 ci: CLASS_I
370 i, nb, c: INTEGER
371 added_class: ES_CLASS
372 l_status_bar: EB_DEVELOPMENT_WINDOW_STATUS_BAR
373 l_classes: ARRAYED_LIST [ES_CLASS]
374 do
375 if depth > 0 and then a_class.class_i.is_compiled then
376 l := a_class.class_i.compiled_class.syntactical_clients
377 from
378 i := 1
379 nb := l.count
380 if progress_bar then
381 l_status_bar := context_editor.develop_window.status_bar
382 end
383 until
384 i > nb
385 loop
386 ci := l.i_th (i).lace_class
387 if ci = a_class.class_i then
388 added_class := a_class
389 else
390 add_class (ci)
391 l_classes := class_from_interface (ci)
392 if not l_classes.is_empty then
393 added_class := l_classes.first
394 end
395 end
396 if added_class /= Void then
397 if not added_class.has_supplier (a_class) then
398 if last_added_class /= Void then
399 disable_class (added_class)
400 end
401 if progress_bar then
402 c := number_of_clients (ci, depth - 1) + 1
403 end
404 else
405 explore_clients (added_class, depth - 1, progress_bar)
406 c := 1
407 end
408 else
409 if progress_bar then
410 c := number_of_clients (ci, depth - 1) + 1
411 end
412 end
413 if progress_bar then
414 l_status_bar.display_progress_value (
415 l_status_bar.current_progress_value + c
416 )
417 end
418 i := i + 1
419 end
420 end
421 end
422
423
424 number_of_suppliers (a_class: CLASS_I; depth: INTEGER): INTEGER is
425 -- Add suppliers of `a_class' until `depth' is reached.
426 require
427 a_class_not_void: a_class /= Void
428 local
429 l: ARRAYED_LIST [CLASS_C]
430 ci: CLASS_I
431 i, nb: INTEGER
432 do
433 if depth > 0 and then a_class.compiled then
434 l := a_class.compiled_class.syntactical_suppliers
435 from
436 i := 1
437 nb := l.count
438 until
439 i > nb
440 loop
441 ci := l.i_th (i).lace_class
442 Result := Result + number_of_suppliers (ci, depth - 1) + 1
443 i := i + 1
444 end
445 end
446 end
447
448 explore_suppliers (a_class: ES_CLASS; depth: INTEGER; progress_bar: BOOLEAN) is
449 -- Add suppliers of `a_class' until `depth' is reached.
450 require
451 a_class_not_void: a_class /= Void
452 local
453 l: ARRAYED_LIST [CLASS_C]
454 ci: CLASS_I
455 i, nb, c: INTEGER
456 added_class: ES_CLASS
457 l_status_bar: EB_DEVELOPMENT_WINDOW_STATUS_BAR
458 l_classes : ARRAYED_LIST [ES_CLASS]
459 do
460 if depth > 0 and then a_class.class_i.compiled then
461 l := a_class.class_i.compiled_class.syntactical_suppliers
462 from
463 i := 1
464 nb := l.count
465 if progress_bar then
466 l_status_bar := context_editor.develop_window.status_bar
467 end
468 until
469 i > nb
470 loop
471 ci := l.i_th (i).lace_class
472 if ci = a_class.class_i then
473 added_class := a_class
474 else
475 add_class (ci)
476 l_classes := class_from_interface (ci)
477 if not l_classes.is_empty then
478 added_class := l_classes.first
479 end
480 end
481 if added_class /= Void then
482 if not a_class.has_supplier (added_class) then
483 -- added_class was not a syntactical_supplier in a query
484 if last_added_class /= Void then
485 -- added_class was not added before
486 disable_class (added_class)
487 end
488 if progress_bar then
489 c := number_of_suppliers (ci, depth - 1) + 1
490 end
491 else
492 explore_suppliers (added_class, depth - 1, progress_bar)
493 c := 1
494 end
495 else
496 -- Was an excluded class
497 if progress_bar then
498 c := number_of_suppliers (ci, depth - 1) + 1
499 end
500 end
501 if progress_bar then
502 l_status_bar.display_progress_value (
503 l_status_bar.current_progress_value + c
504 )
505 end
506 i := i + 1
507 end
508 end
509 end
510
511 include_all_classes (cluster_i: CONF_GROUP) is
512 -- Include all classes in `cluster_i'.
513 require
514 cluster_i_not_void: cluster_i /= Void
515 local
516 l_classes: HASH_TABLE [CONF_CLASS, STRING]
517 l_class: CLASS_I
518 do
519 l_classes := cluster_i.classes
520 from
521 l_classes.start
522 until
523 l_classes.after
524 loop
525 l_class ?= l_classes.item_for_iteration
526 check
527 l_class_not_void: l_class /= Void
528 end
529 add_class (l_class)
530 l_classes.forth
531 end
532 end
533
534 feature {NONE} -- Disable relations
535
536 disable_reachable_classes (a_center: ES_CLASS) is
537 -- Disable needed on diagram for all classes reachable from `a_center'.
538 require
539 a_center_not_void: a_center /= Void
540 do
541 disable_reachable_clients (a_center, client_depth)
542 disable_reachable_suppliers (a_center, supplier_depth)
543 disable_reachable_ancestors (a_center, ancestor_depth)
544 disable_reachable_descendants (a_center, descendant_depth)
545 end
546
547 disable_reachable_clients (a_class: ES_CLASS; a_depth: INTEGER) is
548 -- Disable needed on diagram for all reachable clients from `a_class'.
549 require
550 a_class_not_Void: a_class /= Void
551 a_depth_not_negative: a_depth >= 0
552 local
553 l_links: LIST [EG_LINK]
554 cs_link: ES_CLIENT_SUPPLIER_LINK
555 do
556 if a_depth > 0 then
557 from
558 l_links := a_class.links
559 l_links.start
560 until
561 l_links.after
562 loop
563 check
564 is_a_class_link: l_links.item.source = a_class or else l_links.item.target = a_class
565 end
566 cs_link ?= l_links.item
567 if cs_link /= Void and then cs_link.supplier = a_class then
568 disable_reachable_clients (cs_link.client, a_depth - 1)
569
570 if cs_link.client.is_needed_on_diagram then
571 cs_link.client.disable_needed_on_diagram
572 disable_all_links (cs_link.client.internal_links)
573 end
574 end
575 l_links.forth
576 end
577 end
578 end
579
580 disable_reachable_suppliers (a_class: ES_CLASS; a_depth: INTEGER) is
581 -- Disable needed on diagram for all reachable suppliers from `a_class'.
582 require
583 a_class_not_Void: a_class /= Void
584 a_depth_not_negative: a_depth >= 0
585 local
586 l_links: LIST [EG_LINK]
587 cs_link: ES_CLIENT_SUPPLIER_LINK
588 do
589 if a_depth > 0 then
590 from
591 l_links := a_class.links
592 l_links.start
593 until
594 l_links.after
595 loop
596 cs_link ?= l_links.item
597 if cs_link /= Void and then cs_link.client = a_class then
598 disable_reachable_suppliers (cs_link.supplier, a_depth - 1)
599 if cs_link.supplier.is_needed_on_diagram then
600 cs_link.supplier.disable_needed_on_diagram
601 disable_all_links (cs_link.supplier.internal_links)
602 end
603 end
604 l_links.forth
605 end
606 end
607
608 end
609
610 disable_reachable_ancestors (a_class: ES_CLASS; a_depth: INTEGER) is
611 -- Disable needed on diagram for all reachable ancestors from `a_class'.
612 require
613 a_class_not_Void: a_class /= Void
614 a_depth_not_negative: a_depth >= 0
615 local
616 l_links: LIST [EG_LINK]
617 i_link: ES_INHERITANCE_LINK
618 do
619 if a_depth > 0 then
620 from
621 l_links := a_class.links
622 l_links.start
623 until
624 l_links.after
625 loop
626 i_link ?= l_links.item
627 if i_link /= Void and then i_link.descendant = a_class then
628 disable_reachable_suppliers (i_link.ancestor, a_depth - 1)
629 if i_link.ancestor.is_needed_on_diagram then
630 i_link.ancestor.disable_needed_on_diagram
631 disable_all_links (i_link.ancestor.internal_links)
632 end
633 end
634 l_links.forth
635 end
636 end
637 end
638
639 disable_reachable_descendants (a_class: ES_CLASS; a_depth: INTEGER) is
640 -- Disable needed on diagram for all reachable descendants from `a_class'.
641 require
642 a_class_not_Void: a_class /= Void
643 a_depth_not_negative: a_depth >= 0
644 local
645 l_links: LIST [EG_LINK]
646 i_link: ES_INHERITANCE_LINK
647 do
648 if a_depth > 0 then
649 from
650 l_links := a_class.links
651 l_links.start
652 until
653 l_links.after
654 loop
655 i_link ?= l_links.item
656 if i_link /= Void and then i_link.ancestor = a_class then
657 disable_reachable_descendants (i_link.descendant, a_depth - 1)
658 if i_link.descendant.is_needed_on_diagram then
659 i_link.descendant.disable_needed_on_diagram
660 disable_all_links (i_link.descendant.internal_links)
661 end
662 end
663 l_links.forth
664 end
665 end
666 end
667
668 disable_class (a_class: ES_CLASS) is
669 -- Remove `a_class' and its links
670 do
671 a_class.disable_needed_on_diagram
672 disable_all_links (a_class.internal_links)
673 end
674
675 disable_all_links (a_links: LIST [EG_LINK]) is
676 -- Disable `is_needed_on_diagram' for all links in `a_links'
677 require
678 a_links_not_void: a_links /= Void
679 local
680 l_item: ES_ITEM
681 do
682 from
683 a_links.start
684 until
685 a_links.after
686 loop
687 l_item ?= a_links.item
688 if l_item /= Void then
689 l_item.disable_needed_on_diagram
690 end
691 a_links.forth
692 end
693 end
694
695 add_class (a_class: CLASS_I) is
696 -- Include `a_class' in the diagram.
697 -- Add any relations `a_class' may have with
698 -- all items in `class_figures'.
699 require
700 a_class_not_void: a_class /= Void
701 local
702 es_class: ES_CLASS
703 es_classes: ARRAYED_LIST [ES_CLASS]
704 do
705 last_added_class := Void
706 if not context_editor.is_excluded_in_preferences (a_class.name_in_upper) then
707 if not include_only_classes_of_cluster or else a_class.group = center_class.class_i.group then
708 es_classes := class_from_interface (a_class)
709 if not es_classes.is_empty then
710 es_class := es_classes.first
711 end
712 if es_class = Void then
713 create es_class.make (a_class)
714 add_node (es_class)
715 add_node_relations (es_class)
716 last_added_class := es_class
717 if last_created_classes /= Void then
718 last_created_classes.extend (es_class)
719 end
720 elseif not es_class.is_needed_on_diagram then
721 es_class.enable_needed_on_diagram
722 add_node_relations (es_class)
723 last_added_class := es_class
724 if last_created_classes /= Void then
725 last_created_classes.extend (es_class)
726 end
727 end
728 end
729 end
730 end
731
732 last_added_class: ES_CLASS
733
734 feature {EIFFEL_CLASS_FIGURE}
735
736 last_created_classes: ARRAYED_LIST [ES_CLASS]
737 -- Last created classes by `add_class' if not Void.
738
739 reset_last_created_classes is
740 -- Set `last_created_classes' to Void.
741 do
742 last_created_classes := Void
743 end
744
745 invariant
746 ancestor_depth_positive: ancestor_depth >= 0
747 descendant_depth_positive: descendant_depth >= 0
748 client_depth_positive: client_depth >= 0
749 supplier_depth_positive: supplier_depth >= 0
750 center_class_Void_implies_empty: center_class = Void implies is_empty
751
752 indexing
753 copyright: "Copyright (c) 1984-2006, Eiffel Software"
754 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
755 licensing_options: "http://www.eiffel.com/licensing"
756 copying: "[
757 This file is part of Eiffel Software's Eiffel Development Environment.
758
759 Eiffel Software's Eiffel Development Environment is free
760 software; you can redistribute it and/or modify it under
761 the terms of the GNU General Public License as published
762 by the Free Software Foundation, version 2 of the License
763 (available at the URL listed under "license" above).
764
765 Eiffel Software's Eiffel Development Environment is
766 distributed in the hope that it will be useful, but
767 WITHOUT ANY WARRANTY; without even the implied warranty
768 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
769 See the GNU General Public License for more details.
770
771 You should have received a copy of the GNU General Public
772 License along with Eiffel Software's Eiffel Development
773 Environment; if not, write to the Free Software Foundation,
774 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
775 ]"
776 source: "[
777 Eiffel Software
778 356 Storke Road, Goleta, CA 93117 USA
779 Telephone 805-685-1006, Fax 805-685-6869
780 Website http://www.eiffel.com
781 Customer support http://support.eiffel.com
782 ]"
783
784 end -- class ES_CLASS_GRAPH

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.23