@@ -130,7 +130,7 @@ def relationship_views(self) -> Iterable[RelationshipView]:
130130 """Return the relationship views contained by this view."""
131131 return set (self ._relationship_views )
132132
133- def _add_element (self , element : Element , add_relationships : bool ) -> None :
133+ def _add_element (self , element : Element , add_relationships : bool ) -> ElementView :
134134 """
135135 Add the given element to this view.
136136
@@ -145,10 +145,13 @@ def _add_element(self, element: Element, add_relationships: bool) -> None:
145145 f"The element { element } does not exist in the model associated with "
146146 f"this view."
147147 )
148- if element not in [view .element for view in self .element_views ]:
149- self .element_views .add (ElementView (element = element ))
148+ view = self .find_element_view (element = element )
149+ if view is None :
150+ view = ElementView (element = element )
151+ self .element_views .add (view )
150152 if add_relationships :
151153 self ._add_relationships (element )
154+ return view
152155
153156 def _remove_element (self , element : Element ) -> None :
154157 """
@@ -192,15 +195,8 @@ def _add_relationship(
192195 if self .is_element_in_view (relationship .source ) and self .is_element_in_view (
193196 relationship .destination
194197 ):
195- view = next (
196- (
197- rv
198- for rv in self ._relationship_views
199- if rv .relationship is relationship
200- and rv .description == description
201- and rv .response == response
202- ),
203- None ,
198+ view = self .find_relationship_view (
199+ relationship = relationship , description = description , response = response
204200 )
205201 if not view :
206202 view = RelationshipView (
@@ -211,7 +207,6 @@ def _add_relationship(
211207 )
212208 self ._relationship_views .add (view )
213209 return view
214- return None
215210
216211 def _add_relationships (self , element : Element ) -> None :
217212 """
@@ -241,15 +236,17 @@ def copy_layout_information_from(self, source: "View") -> None:
241236 self .paper_size = source .paper_size
242237
243238 for source_element_view in source .element_views :
244- destination_element_view = self .find_element_view (source_element_view )
239+ destination_element_view = self .find_element_view (
240+ element = source_element_view .element
241+ )
245242 if destination_element_view :
246243 destination_element_view .copy_layout_information_from (
247244 source_element_view
248245 )
249246
250247 for source_relationship_view in source .relationship_views :
251248 destintion_relationship_view = self .find_relationship_view (
252- source_relationship_view
249+ relationship = source_relationship_view . relationship
253250 )
254251 if destintion_relationship_view :
255252 destintion_relationship_view .copy_layout_information_from (
@@ -258,28 +255,47 @@ def copy_layout_information_from(self, source: "View") -> None:
258255
259256 def is_element_in_view (self , element : Element ) -> bool :
260257 """Return True if the given element is in this view."""
261- return any ([ e . element . id == element . id for e in self . element_views ])
258+ return self . find_element_view ( element = element ) is not None
262259
263260 def find_element_view (
264- self , source_element_view : ElementView
261+ self ,
262+ * ,
263+ element : Optional [Element ] = None ,
265264 ) -> Optional [ElementView ]:
266- """Find a child element view corresponding to the given source view."""
267- for element_view in self .element_views :
268- if element_view .element .id == source_element_view .element .id :
269- return element_view
270- return None
265+ """Find a child element view matching a given element."""
266+ return next (
267+ (view for view in self .element_views if view .element .id == element .id ), None
268+ )
271269
272270 def find_relationship_view (
273- self , source_relationship_view : RelationshipView
271+ self ,
272+ * ,
273+ relationship : Optional [Relationship ] = None ,
274+ description : Optional [str ] = None ,
275+ response : Optional [bool ] = None ,
274276 ) -> Optional [RelationshipView ]:
275- """Find a child element view corresponding to the given relationship view."""
276- for relationship_view in self ._relationship_views :
277+ """
278+ Find a child relationship view matching the supplied non-None arguments.
279+
280+ Args:
281+ relationship: find a child view with matching relationship ID
282+ description: find a child view with matching view description. Note that
283+ the view description is not always the same as that of the
284+ relationship
285+ response: find a child view with matching response indicator.
286+ """
287+ for view in self ._relationship_views :
288+ rel = view .relationship
277289 if (
278- relationship_view .relationship .id
279- == source_relationship_view .relationship .id
290+ (relationship is None or rel .id == relationship .id )
291+ and (
292+ description is None
293+ or view .description == description
294+ or (view .description is None and rel .description == description )
295+ )
296+ and (response is None or view .response == response )
280297 ):
281- return relationship_view
282- return None
298+ return view
283299
284300 def check_parent_and_children_not_in_view (self , element : Element ) -> None :
285301 """Ensure that an element can't be added if parent or children are in view."""
0 commit comments