src/eric7/Graphics/GraphicsUtilities.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9653
e67609152c5e
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
10 10
11 class RecursionError(OverflowError, ValueError): 11 class RecursionError(OverflowError, ValueError):
12 """ 12 """
13 Unable to calculate result because of recursive structure. 13 Unable to calculate result because of recursive structure.
14 """ 14 """
15
15 pass 16 pass
16 17
17 18
18 def sort(nodes, routes, noRecursion=False): 19 def sort(nodes, routes, noRecursion=False):
19 """ 20 """
20 Function to sort widgets topographically. 21 Function to sort widgets topographically.
21 22
22 Passed a list of nodes and a list of source, dest routes, it attempts 23 Passed a list of nodes and a list of source, dest routes, it attempts
23 to create a list of stages, where each sub list is one stage in a process. 24 to create a list of stages, where each sub list is one stage in a process.
24 25
25 The algorithm was taken from Boa Constructor. 26 The algorithm was taken from Boa Constructor.
26 27
27 @param nodes list of nodes to be sorted 28 @param nodes list of nodes to be sorted
28 @type str 29 @type str
29 @param routes list of routes between the nodes 30 @param routes list of routes between the nodes
30 @type list of tuple of (str, str) 31 @type list of tuple of (str, str)
31 @param noRecursion flag indicating, if recursion errors should be raised 32 @param noRecursion flag indicating, if recursion errors should be raised
33 @return list of stages 34 @return list of stages
34 @rtype list of lists of str 35 @rtype list of lists of str
35 @exception RecursionError a recursion error was detected 36 @exception RecursionError a recursion error was detected
36 """ 37 """
37 children, parents = _buildChildrenLists(routes) 38 children, parents = _buildChildrenLists(routes)
38 39
39 # first stage is those nodes having no incoming routes... 40 # first stage is those nodes having no incoming routes...
40 stage = [] 41 stage = []
41 stages = [stage] 42 stages = [stage]
42 taken = [] 43 taken = []
43 for node in nodes: 44 for node in nodes:
44 if not parents.get(node): 45 if not parents.get(node):
45 stage.append(node) 46 stage.append(node)
46 47
47 if nodes and not stage: 48 if nodes and not stage:
48 # there is no element, which does not depend on some other element! 49 # there is no element, which does not depend on some other element!
49 stage.append(nodes[0]) 50 stage.append(nodes[0])
50 51
51 taken.extend(stage) 52 taken.extend(stage)
52 nodes = list(filter(lambda x, li=stage: x not in li, nodes)) 53 nodes = list(filter(lambda x, li=stage: x not in li, nodes))
53 while nodes: 54 while nodes:
54 previousStageChildren = [] 55 previousStageChildren = []
55 nodelen = len(nodes) 56 nodelen = len(nodes)
56 57
57 # second stage are those nodes, which are direct children of the 58 # second stage are those nodes, which are direct children of the
58 # first stage 59 # first stage
59 for node in stage: 60 for node in stage:
60 for child in children.get(node, []): 61 for child in children.get(node, []):
61 if child not in previousStageChildren and child not in taken: 62 if child not in previousStageChildren and child not in taken:
62 previousStageChildren.append(child) 63 previousStageChildren.append(child)
63 elif child in taken and noRecursion: 64 elif child in taken and noRecursion:
64 raise RecursionError((child, node)) 65 raise RecursionError((child, node))
65 66
66 # unless they are children of other direct children... 67 # unless they are children of other direct children...
67 stage = previousStageChildren 68 stage = previousStageChildren
68 removes = [] 69 removes = []
69 for current in stage: 70 for current in stage:
70 currentParents = parents.get(current, []) 71 currentParents = parents.get(current, [])
71 for parent in currentParents: 72 for parent in currentParents:
72 if ( 73 if (
73 parent in stage and 74 parent in stage
74 parent != current and 75 and parent != current
75 current not in parents.get(parent, []) 76 and current not in parents.get(parent, [])
76 ): 77 ):
77 # is not mutually dependant 78 # is not mutually dependant
78 removes.append(current) 79 removes.append(current)
79 80
80 for remove in removes: 81 for remove in removes:
81 while remove in stage: 82 while remove in stage:
82 stage.remove(remove) 83 stage.remove(remove)
83 84
84 stages.append(stage) 85 stages.append(stage)
85 taken.extend(stage) 86 taken.extend(stage)
86 nodes = list(filter(lambda x, li=stage: x not in li, nodes)) 87 nodes = list(filter(lambda x, li=stage: x not in li, nodes))
87 if nodelen == len(nodes): 88 if nodelen == len(nodes):
88 if noRecursion: 89 if noRecursion:
89 raise RecursionError(nodes) 90 raise RecursionError(nodes)
90 else: 91 else:
91 stages.append(nodes[:]) 92 stages.append(nodes[:])
92 nodes = [] 93 nodes = []
93 94
94 return stages 95 return stages
95 96
96 97
97 def _buildChildrenLists(routes): 98 def _buildChildrenLists(routes):
98 """ 99 """
99 Function to build up parent - child relationships. 100 Function to build up parent - child relationships.
100 101
101 Taken from Boa Constructor. 102 Taken from Boa Constructor.
102 103
103 @param routes list of routes between nodes 104 @param routes list of routes between nodes
104 @type list of tuple of (str, str) 105 @type list of tuple of (str, str)
105 @return dictionary of child and dictionary of parent relationships 106 @return dictionary of child and dictionary of parent relationships
106 @rtype tuple of (dict, dict) 107 @rtype tuple of (dict, dict)
107 """ 108 """

eric ide

mercurial