Changeset 1112
- Timestamp:
- 12/18/06 13:35:32 (2 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
gaphor/branches/new-canvas/gaphor/adapters/connectors.py
r1111 r1112 409 409 return connected_items 410 410 411 def connect_subject(self ):411 def connect_subject(self, handle): 412 412 """ 413 413 Establish the relationship at model level. … … 435 435 opposite = self.line.opposite(handle) 436 436 if opposite.connected_to: 437 self.connect_subject( )437 self.connect_subject(handle) 438 438 line = self.line 439 439 if line.subject: … … 491 491 return super(DependencyConnect, self).glue(handle, x, y) 492 492 493 def connect_subject(self ):493 def connect_subject(self, handle): 494 494 """ 495 495 TODO: cleck for existing relationships (use self.relation()) … … 549 549 return super(ImplementationConnect, self).glue(handle, x, y) 550 550 551 def connect_subject(self ):551 def connect_subject(self, handle): 552 552 relation = self.relationship_or_new(UML.Implementation, 553 553 ('contract', None), … … 587 587 return super(GeneralizationConnect, self).glue(handle, x, y) 588 588 589 def connect_subject(self ):589 def connect_subject(self, handle): 590 590 relation = self.relationship_or_new(UML.Generalization, 591 591 ('general', None), … … 627 627 return super(IncludeConnect, self).glue(handle, x, y) 628 628 629 def connect_subject(self ):629 def connect_subject(self, handle): 630 630 relation = self.relationship_or_new(UML.Include, 631 631 ('addition', None), … … 667 667 return super(ExtendConnect, self).glue(handle, x, y) 668 668 669 def connect_subject(self ):669 def connect_subject(self, handle): 670 670 relation = self.relationship_or_new(UML.Extend, 671 671 ('extendedCase', None), … … 714 714 return super(ExtensionConnect, self).glue(handle, x, y) 715 715 716 def connect_subject(self ):716 def connect_subject(self, handle): 717 717 element = self.element 718 718 line = self.line … … 811 811 return super(AssociationConnect, self).glue(handle, x, y) 812 812 813 def connect_subject(self ):813 def connect_subject(self, handle): 814 814 element = self.element 815 815 line = self.line … … 931 931 return super(FlowConnect, self).glue(handle, x, y) 932 932 933 def connect_subject(self ):933 def connect_subject(self, handle): 934 934 line = self.line 935 935 element = self.element … … 947 947 if not relation.guard: 948 948 relation.guard = UML.create(UML.LiteralSpecification) 949 self.line.subject = relation 949 line.subject = relation 950 opposite = line.opposite(handle) 951 if opposite and isinstance(opposite.connected_to, (items.ForkNodeItem, items.DecisionNodeItem)): 952 adapter = component.queryMultiAdapter((opposite.connected_to, line), IConnect) 953 adapter.combine_nodes() 954 955 def disconnect_subject(self, handle): 956 super(FlowConnect, self).disconnect_subject(handle) 957 line = self.line 958 opposite = line.opposite(handle) 959 if opposite and isinstance(opposite.connected_to, (items.ForkNodeItem, items.DecisionNodeItem)): 960 adapter = component.queryMultiAdapter((opposite.connected_to, line), IConnect) 961 adapter.decombine_nodes() 950 962 951 963 component.provideAdapter(factory=FlowConnect, … … 1003 1015 line = self.line 1004 1016 element = self.element 1005 join_node = element.subject1006 if element.combined:1007 return1008 1009 # determine flow class:1010 if [ f for f in join_node.incoming if isinstance(f, UML.ObjectFlow) ]:1011 flow_class = UML.ObjectFlow1012 else:1013 flow_class = UML.ControlFlow1014 1015 UML.swap_element(join_node, join_node_class)1016 fork_node = UML.create(UML.ForkNode)1017 for flow in join_node.outgoing:1018 flow.source = fork_node1019 flow = UML.create(flow_class)1020 flow.source = join_node1021 flow.target = fork_node1022 1023 element.combined = fork_node1024 1025 def decombine_nodes(self, fork_node_class, join_node_class):1026 """1027 Decombine join/fork or decision/merge nodes.1028 """1029 line = self.line1030 element = self.element1031 if element.combined:1032 join_node = element.subject1033 flow = subject.outgoing[0]1034 fork_node = flow.target1035 assert fork_node is element.combined1036 assert isinstance(join_node, join_node_class)1037 assert isinstance(fork_node, fork_node_class)1038 1039 if len(join_node.incoming) < 2 or len(fork_node.outgoing) < 2:1040 # Move all outgoing edges to the first node (the join node):1041 for flow in fork_node.outgoing:1042 flow.source = join_node1043 flow.unlink()1044 fork_node.unlink()1045 1046 # swap subject to fork node if outgoing > 11047 if len(subject.outgoing) > 1:1048 assert len(subject.incoming) < 21049 UML.swap_element(subject, fork_node_class)1050 else:1051 # Illegal state!1052 pass1053 element.combined = None1054 1055 def connect_subject(self, fork_node_class, join_node_class):1056 """1057 In addition to a subject connect, the subject of the element may1058 be changed.1059 For readability, parameters are named afther the classes used by1060 Join/Fork nodes.1061 """1062 super(FlowForkDecisionNodeConnect, self).connect_subject()1063 1064 # Switch class for self.element Join/Fork depending on the number1065 # of incoming/outgoing edges.1066 element = self.element1067 1017 subject = element.subject 1068 1018 if len(subject.incoming) > 1 and len(subject.outgoing) < 2: … … 1072 1022 UML.swap_element(subject, fork_node_class) 1073 1023 element.request_update() 1074 elif len(subject.incoming) > 1 and len(subject.outgoing) > 1: 1075 self.combine_nodes(fork_node_class, join_node_class) 1076 1077 def disconnect_subject(self, fork_node_class=None, join_node_class=None): 1024 elif not element.combined and len(subject.incoming) > 1 and len(subject.outgoing) > 1: 1025 join_node = subject 1026 1027 # determine flow class: 1028 if [ f for f in join_node.incoming if isinstance(f, UML.ObjectFlow) ]: 1029 flow_class = UML.ObjectFlow 1030 else: 1031 flow_class = UML.ControlFlow 1032 1033 UML.swap_element(join_node, join_node_class) 1034 fork_node = UML.create(fork_node_class) 1035 for flow in list(join_node.outgoing): 1036 flow.source = fork_node 1037 flow = UML.create(flow_class) 1038 flow.source = join_node 1039 flow.target = fork_node 1040 1041 element.combined = fork_node 1042 1043 def decombine_nodes(self, fork_node_class, join_node_class): 1044 """ 1045 Decombine join/fork or decision/merge nodes. 1046 """ 1047 line = self.line 1048 element = self.element 1049 if element.combined: 1050 join_node = element.subject 1051 flow = join_node.outgoing[0] 1052 fork_node = flow.target 1053 assert fork_node is element.combined 1054 assert isinstance(join_node, join_node_class) 1055 assert isinstance(fork_node, fork_node_class) 1056 1057 if len(join_node.incoming) < 2 or len(fork_node.outgoing) < 2: 1058 # Move all outgoing edges to the first node (the join node): 1059 for flow in list(fork_node.outgoing): 1060 flow.source = join_node 1061 flow.unlink() 1062 fork_node.unlink() 1063 1064 # swap subject to fork node if outgoing > 1 1065 if len(join_node.outgoing) > 1: 1066 assert len(join_node.incoming) < 2 1067 UML.swap_element(join_node, fork_node_class) 1068 element.combined = None 1069 1070 def connect_subject(self, handle): 1071 """ 1072 In addition to a subject connect, the subject of the element may 1073 be changed. 1074 For readability, parameters are named afther the classes used by 1075 Join/Fork nodes. 1076 """ 1077 super(FlowForkDecisionNodeConnect, self).connect_subject(handle) 1078 1079 # Switch class for self.element Join/Fork depending on the number 1080 # of incoming/outgoing edges. 1081 self.combine_nodes() 1082 1083 def disconnect_subject(self): 1078 1084 super(FlowForkDecisionNodeConnect, self).disconnect_subject() 1079 1085 if self.element.combined: 1080 self.decombine_nodes(fork_node_class, join_node_class) 1081 # TODO: if combined node: un-combine if only one incoming or outgoing 1082 # egde on one side. 1086 self.decombine_nodes() 1083 1087 1084 1088 … … 1089 1093 component.adapts(items.ForkNodeItem, items.FlowItem) 1090 1094 1091 def connect_subject(self): 1092 super(FlowForkNodeConnect, self).connect_subject(join_node_class=UML.JoinNode, fork_node_class=UML.ForkNode) 1095 def combine_nodes(self, fork_node_class=UML.ForkNode, 1096 join_node_class=UML.JoinNode): 1097 super(FlowForkNodeConnect, self).combine_nodes(fork_node_class=fork_node_class, join_node_class=join_node_class) 1098 1099 def decombine_nodes(self, fork_node_class=UML.ForkNode, 1100 join_node_class=UML.JoinNode): 1101 super(FlowForkNodeConnect, self).decombine_nodes(fork_node_class=fork_node_class, join_node_class=join_node_class) 1093 1102 1094 1103 component.provideAdapter(FlowForkNodeConnect) … … 1101 1110 component.adapts(items.DecisionNodeItem, items.FlowItem) 1102 1111 1103 def connect_subject(self): 1104 super(FlowDecisionNodeConnect, self).connect_subject(join_node_class=UML.MergeNode, fork_node_class=UML.DecisionNode) 1112 def combine_nodes(self, fork_node_class=UML.DecisionNode, 1113 join_node_class=UML.MergeNode): 1114 super(FlowDecisionNodeConnect, self).combine_nodes(fork_node_class=fork_node_class, join_node_class=join_node_class) 1115 1116 def decombine_nodes(self, fork_node_class=UML.DecisionNode, 1117 join_node_class=UML.MergeNode): 1118 super(FlowDecisionNodeConnect, self).decombine_nodes(fork_node_class=fork_node_class, join_node_class=join_node_class) 1105 1119 1106 1120 component.provideAdapter(FlowDecisionNodeConnect) gaphor/branches/new-canvas/gaphor/adapters/tests/test_connector.py
r1109 r1112 611 611 a2 = diagram.create(items.ActionItem, subject=UML.create(UML.Action)) 612 612 a3 = diagram.create(items.ActionItem, subject=UML.create(UML.Action)) 613 a4 = diagram.create(items.ActionItem, subject=UML.create(UML.Action)) 613 614 f1 = diagram.create(itemClass, subject=UML.create(joinNodeClass)) 614 615 … … 617 618 # Connect between two actions (ControlFlow) 618 619 # Connecting line this: 619 # |--flow2-->[ a2 ]620 # head tail|--flow2-->[ a2 ] 620 621 # [ a1 ] --flow1-->| 621 622 # |--flow3-->[ a3 ] … … 653 654 assert flow2.subject in f1.subject.outgoing 654 655 assert type(f1.subject) is joinNodeClass 656 assert flow2.canvas 655 657 656 658 adapter = component.queryMultiAdapter((f1, flow3), IConnect) … … 660 662 assert flow3.subject.source is f1.subject 661 663 assert flow3.subject in f1.subject.outgoing 664 assert len(f1.subject.outgoing) == 2 662 665 663 666 assert type(f1.subject) is forkNodeClass, f1.subject 664 667 665 # flow4 can't be an incoming flow:668 # flow4 will force the forknode to become a combined node: 666 669 667 670 adapter = component.queryMultiAdapter((f1, flow4), IConnect) 668 671 assert adapter 669 672 adapter.connect(flow4.tail, flow4.tail.x, flow4.tail.y) 670 assert flow4.tail.connected_to is None 673 assert type(f1.subject) is forkNodeClass 674 675 adapter = component.queryMultiAdapter((a4, flow4), IConnect) 676 adapter.connect(flow4.head, flow4.head.x, flow4.head.y) 677 assert type(f1.subject) is joinNodeClass 678 assert f1.combined 679 assert flow4.tail.connected_to is f1 680 assert flow4.subject.target is f1.subject 681 assert type(f1.combined) is forkNodeClass, f1.combined 682 assert flow1.subject in f1.subject.incoming 683 assert flow4.subject in f1.subject.incoming 684 assert flow2.subject in f1.combined.outgoing, f1.combined.outgoing 685 assert flow3.subject in f1.combined.outgoing, f1.combined.outgoing 686 assert len(f1.subject.outgoing) == 1 687 assert len(f1.combined.incoming) == 1 688 assert f1.subject.outgoing[0] is f1.combined.incoming[0] 671 689 672 690 # flow4 can be connected as outgoing flow though: 673 674 adapter = component.queryMultiAdapter((f1, flow4), IConnect) 675 assert adapter 676 adapter.connect(flow4.head, flow4.head.x, flow4.head.y) 677 assert flow4.head.connected_to is f1 691 #adapter = component.queryMultiAdapter((f1, flow4), IConnect) 692 #assert adapter 693 #adapter.connect(flow4.head, flow4.head.x, flow4.head.y) 694 #assert flow4.head.connected_to is f1 678 695 679 696 adapter.disconnect(flow4.head) 680 697 assert flow4.head.connected_to is None 698 adapter = component.queryMultiAdapter((f1, flow4), IConnect) 699 adapter.disconnect(flow4.tail) 700 assert not f1.combined 701 702 assert flow2.canvas 703 assert flow2.canvas.solver 681 704 682 705 # Now change the ForkNode back into a JoinNode by moving flow2 … … 711 734 712 735 # And of course I can't add another outgoing edge: 713 adapter = component.queryMultiAdapter((f1, flow4), IConnect)714 assert adapter715 adapter.connect(flow4.head, flow4.head.x, flow4.head.y)716 assert flow4.head.connected_to is None736 #adapter = component.queryMultiAdapter((f1, flow4), IConnect) 737 #assert adapter 738 #adapter.connect(flow4.head, flow4.head.x, flow4.head.y) 739 #assert flow4.head.connected_to is None 717 740 718 741 gaphor/branches/new-canvas/gaphor/diagram/activitynodes.py
r1111 r1112 133 133 134 134 def _set_combined(self, value): 135 self.preserve_property('combined')135 #self.preserve_property('combined') 136 136 self._combined = value 137 137
