Coverage for src/robotide/controller/settingcontrollers.py: 89%
461 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:40 +0100
« prev ^ index » next coverage.py v7.8.0, created at 2025-05-06 10:40 +0100
1# Copyright 2008-2015 Nokia Networks
2# Copyright 2016- Robot Framework Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
16import re 1ab
17from itertools import chain 1ab
19from .. import robotapi, utils 1ab
20from ..robotapi import ALIAS_MARKER 1ab
21from ..publish.messages import (RideImportSettingChanged, RideImportSettingRemoved, RideVariableUpdated, 1ab
22 RideItemSettingsChanged, RideImportSettingAdded)
23from ..utils import variablematcher, unescape_newlines_and_whitespaces 1ab
24from .basecontroller import ControllerWithParent 1ab
25from .tags import Tag, ForcedTag, DefaultTag, TestTag 1ab
28class _SettingController(ControllerWithParent): 1ab
29 def __init__(self, parent_controller, data): 1ab
30 self._parent = parent_controller 2a # BbZb2 9b!b#b$bj k l w dc%becwb+ C Q R zb4 xbE P 'b$ (bucncfcvc' gchcycwc)bCbzcAcBcCcicocpcDb^bqcDc5 Y B x T y 0b*b+b( ,b-b.b/b:b;bc m _bd S 1b2bjcEcN kcObPbQb, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 K o M L G p n q s t r g X Z 0 1 H u I h i e f Fcsctcvbv z GcHcA O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7bGbHbIbJbKbLbMb) * `b{b=b|bxc
31 self._data = data 2a # BbZb2 9b!b#b$bj k l w dc%becwb+ C Q R zb4 xbE P 'b$ (bucncfcvc' gchcycwc)bCbzcAcBcCcicocpcDb^bqcDc5 Y B x T y 0b*b+b( ,b-b.b/b:b;bc m _bd S 1b2bjcEcN kcObPbQb, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 K o M L G p n q s t r g X Z 0 1 H u I h i e f Fcsctcvbv z GcHcA O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7bGbHbIbJbKbLbMb) * `b{b=b|bxc
32 self.label = self._label(self._data) 2a # BbZb2 9b!b#b$bj k l w dc%becwb+ C Q R zb4 xbE P 'b$ (bucncfcvc' gchcycwc)bCbzcAcBcCcicocpcDb^bqcDc5 Y B x T y 0b*b+b( ,b-b.b/b:b;bc m _bd S 1b2bjcEcN kcObPbQb, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 K o M L G p n q s t r g X Z 0 1 H u I h i e f Fcsctcvbv z GcHcA O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7bGbHbIbJbKbLbMb) * `b{b=b|bxc
33 self._init(self._data) 2a # BbZb2 9b!b#b$bj k l w dc%becwb+ C Q R zb4 xbE P 'b$ (bucncfcvc' gchcycwc)bCbzcAcBcCcicocpcDb^bqcDc5 Y B x T y 0b*b+b( ,b-b.b/b:b;bc m _bd S 1b2bjcEcN kcObPbQb, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 K o M L G p n q s t r g X Z 0 1 H u I h i e f Fcsctcvbv z GcHcA O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7bGbHbIbJbKbLbMb) * `b{b=b|bxc
35 def _init(self, data): 1ab
36 raise NotImplementedError
38 def _label(self, data): 1ab
39 label = data.setting_name 2a Bbj k l w dc%becucncfcvc' gcDb^bqc*b+b( ,b-b.b/b:b;bc m _bd S 1b2bEckc, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 K o M L G p n q s t r g X Z 0 1 H u I h i e f vbv z A O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7bGbHbIbJbKbLbMb
40 if label.startswith('['): 2a Bbj k l w dc%becucncfcvc' gcDb^bqc*b+b( ,b-b.b/b:b;bc m _bd S 1b2bEckc, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 K o M L G p n q s t r g X Z 0 1 H u I h i e f vbv z A O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7bGbHbIbJbKbLbMb
41 return label[1:-1] 2a Bbj k l w dcDb*b+b( ,b-b.b/b:b;bc m _bd S 1b2b, - . / : ; = ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbub3 K o M L G p n q s t r g X Z 0 1 H u I h i e f vbv z A O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7bGbHbIbJbKbLbMb
42 return label 2a j k l w %becucncfcvc' gc^bqcc m Eckc, - . / : ; yb= ? @ D U F V [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 n q s t r g X Z 0 1 H u I e f vbv z A O J
44 @property 1ab
45 def _value(self): 1ab
46 return [v.replace('|', '\\|') for v in self.as_list()[1:]] 2dcRcecYbScgc*b+b( ,b-b.b/b:bc d D U F V W h i e f
48 @property 1ab
49 def value(self): 1ab
50 value = self._value 2*b+b( ,b-b.b/b:bc d D U F V W h i e f
51 if self._data.comment: 2*b+b( ,b-b.b/b:bc d D U F V W h i e f
52 value.pop() 1cd
53 return ' | '.join(value) 2*b+b( ,b-b.b/b:bc d D U F V W h i e f
55 @property 1ab
56 def display_value(self): 1ab
57 return ' | ' .join(self._value) 2dcRcecYbScgc
59 def as_list(self): 1ab
60 # print(f"\nDEBUG: _SettingController enter as_list")
61 return self._data.as_list() 2dc%bRcecYbScgc*b+b( ,b-b.b/b:b;bc d , - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 h i e f vb
63 @property 1ab
64 def comment(self): 1ab
65 return self._data.comment 2j k l w Mcc m d S h i e f
67 @property 1ab
68 def keyword_name(self): 1ab
69 return ''
71 def contains_keyword(self, name): 1ab
72 istring = isinstance(name, str) 2%b, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 vb
73 # print(f"DEBUG: settingcontrollers.py _SettingController contains_keyword: item={self} search="
74 # f"{name}")
75 matcher = name.match if not istring else lambda i: utils.eq(i, name) 2%b, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 vb
76 return self._contains_keyword(matcher) 2%b, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 vb
78 def _contains_keyword(self, matcher_function): 1ab
79 return any(matcher_function(item or '') for item in self.as_list()) 2%b, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 vb
81 def contains_variable(self, name): 1ab
82 return variablematcher.value_contains_variable(self.value, name) 1DUFVW
84 @property 1ab
85 def is_set(self): 1ab
86 return self._data.is_set() 2j k l w RcScc m d S h i e f
88 def set_from(self, other): 1ab
89 if other.is_set: 1jklwcmdShief
90 self.set_value(other.value) 1cdhief
91 self.set_comment(other.comment) 1jklwcmdShief
93 def set_value(self, value): 1ab
94 if self._changed(value): 2BbYc?b8bNcOcPcQc}b~bacbcccYb% TcIcJcKcLc@b[b]bDb( c d K o M L G p n q s t r g u h i e f v z GbHbIbJbKbLbMb
95 self._set(value) 2Bb?b8bNcOcPc}b~bacbcccYb% IcJcKc@b[b]bDb( c d K o M L G p n q s t r g u h i e f v z GbHbIbJbKbLbMb
96 self.mark_dirty() 2Bb?b8bNcOcPc}b~bacbcccYb% IcJcKc@b[b]bDb( c d K o M L G p n q s t r g u h i e f v z GbHbIbJbKbLbMb
97 RideItemSettingsChanged(item=self._parent).publish() 2Bb?b8bNcOcPc}b~bacbcccYb% IcJcKc@b[b]bDb( c d K o M L G p n q s t r g u h i e f v z GbHbIbJbKbLbMb
99 def set_comment(self, comment): 1ab
100 if comment != self.comment: 100 ↛ exitline 100 didn't return from function 'set_comment' because the condition on line 100 was always true2j k l w Mcc m d S h i e f
101 if not isinstance(comment, robotapi.Comment): 2j k l w Mcc m d S h i e f
102 comment = robotapi.Comment(comment) 2Mcc d
103 self._data.comment = comment 2j k l w Mcc m d S h i e f
104 self.mark_dirty() 2j k l w Mcc m d S h i e f
106 def notify_value_changed(self, old_name=None, new_name=None): 1ab
107 self._parent.notify_settings_changed(old_name) 16789!3nqstrguvz
109 def clear(self): 1ab
110 self._data.reset() 2UcVcA
111 self.mark_dirty() 2UcVcA
112 RideItemSettingsChanged(item=self._parent).publish() 2UcVcA
114 def _changed(self, value): 1ab
115 return value != self._data.value 2Yc?b8bNcOcPcc d h i e f
117 def _set(self, value): 1ab
118 self._data.value = value 2?b8bNcOcPcc d h i e f
120 @staticmethod 1ab
121 def _split_from_separators(value): 1ab
122 return utils.split_value(value) 2BbQc}b~bacbcccYb% TcIcJcKcDb( c d K o M L G p n q s t r g u h i e f v z GbHbIbJbKbLbMb
125class DocumentationController(_SettingController): 1ab
126 _regexps = (re.compile(r'(\\+)r\\n'), 1ab
127 re.compile(r'(\\+)n'),
128 re.compile(r'(\\+)r'),
129 re.compile(r'(\\+) '))
131 def _init(self, doc): 1ab
132 self._doc = doc 2a j k l w dc^bqcc m _bd S 1b2bkc, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 h i e f vbRbSbTbEbUbVbFbWbXbAb
134 @property 1ab
135 def value(self): 1ab
136 return self._doc.value 2Zc0c?b8bc d kcD U F V W h i e f RbSbTbEbUbVbFbWbXbAb
138 def contains_keyword(self, name): 1ab
139 return False 2, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbob3bpbqbrbsbtbub3 vb
141 def _get_editable_value(self): 1ab
142 return unescape_newlines_and_whitespaces(self.value) 2Zc?b8b
144 def _set_editable_value(self, value): 1ab
145 self.set_value(self._escape_newlines_and_leading_hash(value)) 2?b8b
147 editable_value = property(_get_editable_value, _set_editable_value) 1ab
149 @property 1ab
150 def visible_value(self): 1ab
151 return utils.html_format(utils.unescape(self.value)) 20c
153 @staticmethod 1ab
154 def _escape_newlines_and_leading_hash(item): 1ab
155 for newline in ('\r\n', '\n', '\r'): 2?b8b
156 item = item.replace(newline, '\\n') 2?b8b
157 if item.strip().startswith('#'): 2?b8b
158 item = '\\' + item 28b
159 return item 2?b8b
162class FixtureController(_SettingController): 1ab
164 def _init(self, fixture): 1ab
165 self._fixture = fixture 2a j k l w %bec^bqcc m _bd S 1b2bkc, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbub3 h i e f vb
167 @property 1ab
168 def keyword_name(self): 1ab
169 return self._fixture.name
171 def replace_keyword(self, new_name, old_value=None): 1ab
172 # print(f"DEBUG: settingcontrollers.py replace_keyword new_name={new_name} existing name={self._fixture.name}"
173 # f"\nold_value={old_value}")
174 if self._fixture.name == old_value: 16793
175 self._fixture.name = new_name 1679
176 else:
177 for idx, argument in enumerate(self._fixture.args): 13
178 if argument == old_value: 13
179 self._fixture.args[idx] = new_name 13
180 self.mark_dirty() 16793
182 def _changed(self, value): 1ab
183 name, args = self._parse(value) 2Qc}b~bacbcccYbc d e f
184 return self._fixture.name != name or self._fixture.args != args 2Qc}b~bacbcccYbc d e f
186 def _set(self, value): 1ab
187 name, args = self._parse(value) 2}b~bacbcccYbc d e f
188 self._fixture.name = name 2}b~bacbcccYbc d e f
189 self._fixture.args = args 2}b~bacbcccYbc d e f
191 def _parse(self, value): 1ab
192 value = self._split_from_separators(value) 2Qc}b~bacbcccYbc d e f
193 return (value[0], value[1:]) if value else ('', []) 2Qc}b~bacbcccYbc d e f
196class TagsController(_SettingController): 1ab
198 def _init(self, tags): 1ab
199 self.tags = tags 2a j k l w ' ^bqc;bc m _bd S 1b2bkc, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbub3 n q s t r g X Z 0 1 H u I h i e f vbv z A O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7b
201 def empty_tag(self): 1ab
202 return Tag(None, controller=self) 1nq
204 def _changed(self, value): 1ab
205 return self.tags.value != self._split_from_separators(value) 2% TcIcJcKcc d n q s t r g u e f v z
207 def set_from(self, other): 1ab
208 if other.is_set and other.tags.value is not None: 1jklwcmdShief
209 self.set_value(other.value) 1cdef
210 self.set_comment(other.comment) 1jklwcmdShief
212 def _set(self, value): 1ab
213 self.tags.value = self._split_from_separators(value) 2% IcJcKcc d n q s t r g u e f v z
215 def add(self, tag): 1ab
216 if self.tags.value is None: 2w Wc;bn q s t r g X Z 0 1 H u I A J
217 self.tags.value = [] 2w ;bn q s t r g X Z 0 1 H u I A J
218 tag.set_index(len(self.tags.value)) 2w Wc;bn q s t r g X Z 0 1 H u I A J
219 self.tags.value.append(tag.name) 2w Wc;bn q s t r g X Z 0 1 H u I A J
221 def remove(self, tag): 1ab
222 if tag in self.tags.value:
223 self.tags.value.remove(tag)
225 def __iter__(self): 1ab
226 forced = self._parent.force_tags 2j k l w Nb% ' c m d S n q s t r g X Z 0 1 H u I h i e f v z A O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7b
227 test_tags = self._parent.test_tags 2j k l w Nb% ' c m d S n q s t r g X Z 0 1 H u I h i e f v z A O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7b
228 if self.tags.value is None: 2j k l w Nb% ' c m d S n q s t r g X Z 0 1 H u I h i e f v z A O J Rb4bSbTb5bEbUbVbFbWb6bXbAb7b
229 return chain(forced, self._parent.default_tags, test_tags).__iter__() 1jklw'cmdSnXZ01hivzAO
230 if len(self.tags.value) == 0: 2Nb% c d n q s t r g H u I e f v z A J Rb4bSbTb5bEbUbVbFbWb6bXbAb7b
231 return chain(forced, test_tags, [Tag('', controller=self)]) 2n r RbSbTbUbVbWbXbAb
232 own_tags = (Tag(t, index, self) 2Nb% c d q s t r g H u I e f v z A J 4b5bEbFb6bAb7b
233 for index, t in enumerate(self.tags.value))
234 return chain(forced, test_tags, own_tags).__iter__() 2Nb% c d q s t r g H u I e f v z A J 4b5bEbFb6bAb7b
236 @property 1ab
237 def is_set(self): 1ab
238 return any(self) 2j k l w Nbc m d S h i e f
240 @property 1ab
241 def display_value(self): 1ab
242 return ' | ' .join(tag.name.replace('|', '\\|') for tag in self) 2Nb% '
245class DefaultTagsController(TagsController): 1ab
247 def empty_tag(self): 1ab
248 return DefaultTag(None, controller=self)
250 def __iter__(self): 1ab
251 if self.tags.value is None: 2j k l w Nb% ' c m n X v z A O
252 return [].__iter__() 2j k l Nb% ' c m v z A O
253 return (DefaultTag(t, index, self) 1wnXv
254 for index, t in enumerate(self.tags.value)).__iter__()
257class ForceTagsController(TagsController): 1ab
259 def empty_tag(self): 1ab
260 return ForcedTag(None, controller=self)
262 def __iter__(self): 1ab
263 return self._recursive_gather_from(self.parent, []).__iter__() 2j k l w Nb% ' c m n q s t r g X Z 0 1 H u I e f v z A O J
265 def __eq__(self, other): 1ab
266 if self is other: 266 ↛ 267line 266 didn't jump to line 267 because the condition on line 266 was never true1g
267 return True
268 if other is None: 268 ↛ 269line 268 didn't jump to line 269 because the condition on line 268 was never true1g
269 return False
270 if not isinstance(other, self.__class__): 270 ↛ 272line 270 didn't jump to line 272 because the condition on line 270 was always true1g
271 return False 1g
272 return self.tags == other.tags
274 def _recursive_gather_from(self, obj, result): 1ab
275 if obj is None: 2j k l w Nb% ' c m n q s t r g X Z 0 1 H u I e f v z A O J
276 return result 1jklwcmnqstrgXZ01HuIefvzAOJ
277 try: 2j k l w Nb% ' c m n q s t r g X Z 0 1 H u I e f v z A O J
278 force_tags = obj.setting_table.force_tags 2j k l w Nb% ' c m n q s t r g X Z 0 1 H u I e f v z A O J
279 except AttributeError: # In the case of a .resource file, there is no Forced Tags fields 2Nb% '
280 return result 2Nb% '
281 # print(f"DEBUG: SettingsController _recursive_gather_from force_tags={force_tags}, obj.parent={obj.parent}")
282 return self._recursive_gather_from( 1jklwcmnqstrgXZ01HuIefvzAOJ
283 obj.parent,
284 self._gather_from_data(force_tags, obj.force_tags) + result)
286 @staticmethod 1ab
287 def _gather_from_data(tags, parent): 1ab
288 if tags.value is None: 1jklwcmnqstrgXZ01HuIefvzAOJ
289 return [] 1jklwcmnqstrgXZ01HuIvzAOJ
290 return [ForcedTag(t, index, parent) 1gZ01ef
291 for index, t in enumerate(tags.value)]
294class TestTagsController(TagsController): 1ab
296 def empty_tag(self): 1ab
297 return TestTag(None, controller=self)
299 def __iter__(self): 1ab
300 return self._recursive_gather_from(self.parent, []).__iter__() 1jklcmnqstrgHuIvzAOJ
302 def __eq__(self, other): 1ab
303 if self is other:
304 return True
305 if other is None:
306 return False
307 if not isinstance(other, self.__class__):
308 return False
309 return self.tags == other.tags
311 def _recursive_gather_from(self, obj, result): 1ab
312 if obj is None: 1jklcmnqstrgHuIvzAOJ
313 return result 1jklcmnqstrgHuIvzAOJ
314 try: 1jklcmnqstrgHuIvzAOJ
315 test_tags = obj.setting_table.test_tags 1jklcmnqstrgHuIvzAOJ
316 except AttributeError: # In the case of a .resource file, there is no Test Tags fields
317 return result
318 # print(f"DEBUG: SettingsController _recursive_gather_from force_tags={force_tags}, obj.parent={obj.parent}")
319 return self._recursive_gather_from( 1jklcmnqstrgHuIvzAOJ
320 obj.parent,
321 self._gather_from_data(test_tags, obj.test_tags) + result)
323 @staticmethod 1ab
324 def _gather_from_data(tags, parent): 1ab
325 if tags.value is None: 325 ↛ 327line 325 didn't jump to line 327 because the condition on line 325 was always true1jklcmnqstrgHuIvzAOJ
326 return [] 1jklcmnqstrgHuIvzAOJ
327 return [TestTag(t, index, parent)
328 for index, t in enumerate(tags.value)]
331class TimeoutController(_SettingController): 1ab
333 def _init(self, timeout): 1ab
334 self._timeout = timeout 2a j k l w gc^bc m _bd S 1b2b, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbub3 h i e f vb
336 def _changed(self, value): 1ab
337 val, msg = self._parse(value) 2Lc@b[b]bc d
338 return self._timeout.value != val or self._timeout.message != msg 2Lc@b[b]bc d
340 def _set(self, value): 1ab
341 value, message = self._parse(value) 2@b[b]bc d
342 self._timeout.value = value 2@b[b]bc d
343 self._timeout.message = message 2@b[b]bc d
345 @staticmethod 1ab
346 def _parse(value): 1ab
347 parts = value.split('|', 1) 2Lc@b[b]bc d
348 val = parts[0].strip() if parts else '' 2Lc@b[b]bc d
349 msg = parts[1].strip() if len(parts) == 2 else '' 2Lc@b[b]bc d
350 return val, msg 2Lc@b[b]bc d
353class TemplateController(_SettingController): 1ab
355 def _init(self, template): 1ab
356 self._template = template 2j k l w ^bc m _b, - . / : ; yb= ? @ D U F V W [ ] ^ _ ` 6 7 8 9 ! { | } ~ abbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbub3 e f vb
358 def _set(self, value): 1ab
359 _SettingController._set(self, value) 1c
360 self._parent.notify_steps_changed() 1c
362 def clear(self): 1ab
363 _SettingController.clear(self)
364 self._parent.notify_steps_changed()
366 @property 1ab
367 def keyword_name(self): 1ab
368 return self._template.value
370 def replace_keyword(self, new_name, old_name=None): 1ab
371 _ = old_name 18!
372 self._template.value = new_name 18!
373 self.mark_dirty() 18!
376class ArgumentsController(_SettingController): 1ab
378 def _init(self, args): 1ab
379 self._args = args 2BbDb*b+b( ,b-b.b/b:bd S 1b2bD U F V W K o M L G p h i GbHbIbJbKbLbMb
381 def _changed(self, value): 1ab
382 return self._args.value != self._split_from_separators(value) 2BbDb( d K o M L G p h i GbHbIbJbKbLbMb
384 def _set(self, value): 1ab
385 self._args.value = self._split_from_separators(value) 2BbDb( d K o M L G p h i GbHbIbJbKbLbMb
386 self._parent.notify_settings_changed() 2BbDb( d K o M L G p h i GbHbIbJbKbLbMb
388 def clear(self): 1ab
389 _SettingController.clear(self)
390 self._parent.notify_settings_changed()
393class ReturnValueController(_SettingController): 1ab
395 def _init(self, return_): 1ab
396 self._return = return_ 2a d S 1b2bD U F V W h i
398 def _label(self, data): 1ab
399 return 'Return Value' 2a d S 1b2bD U F V W h i
401 def _changed(self, value): 1ab
402 return self._return.value != self._split_from_separators(value) 1dhi
404 def _set(self, value): 1ab
405 self._return.value = self._split_from_separators(value) 1dhi
408class MetadataController(_SettingController): 1ab
410 def _init(self, meta): 1ab
411 self._meta = meta 2ucncfcvc
413 @property 1ab
414 def name(self): 1ab
415 return self._meta.name 2nc
417 @property 1ab
418 def value(self): 1ab
419 return self._meta.value 2nc
421 def set_value(self, name=None, value=None): 1ab
422 self._meta.name = name 2fc
423 self._meta.value = value 2fc
424 self._parent.mark_dirty() 2fc
427class VariableController(_SettingController): 1ab
429 def _init(self, var): 1ab
430 self.var = var 2a hcycwc)bCbzcAcBcCcicocpcDcObPbQbFcsctcGcHc`b{b=b|bxc
432 def _label(self, data): 1ab
433 return '' 2a hcycwc)bCbzcAcBcCcicocpcDcObPbQbFcsctcGcHc`b{b=b|bxc
435 def __ne__(self, other): 1ab
436 return not (self == other) # This cannot be compared with != 2ic`b{b=b|b
438 @property 1ab
439 def name(self): 1ab
440 return self.var.name 2hcycwc)bCbzcAcBcCcicocpcDcObPbQb`b{b=b|bxc
442 @property 1ab
443 def value(self): 1ab
444 return self.var.value 2)bocpcObPbQb
446 @property 1ab
447 def comment(self): 1ab
448 return self.var.comment 2ocpcObPbQb
450 @property 1ab
451 def data(self): 1ab
452 return self._data 2a wcObPbQbGcHc
454 @property 1ab
455 def index(self): 1ab
456 return self.parent.index(self) 2hcCbocpcObPbQb`b{b=b|bxc
458 @staticmethod 1ab
459 def get_local_variables(): 1ab
460 return {}
462 def set_value(self, name=None, value=None): 1ab
463 if isinstance(value, str): 2)bCb
464 value = [value] 2)bCb
465 self.var.name = name 2)bCb
466 self.var.value = value 2)bCb
467 self._parent.mark_dirty() 2)bCb
469 def has_data(self): 1ab
470 return self._data.has_data() 2a Fc
472 def delete(self): 1ab
473 self._parent.remove_var(self) 2ObPbQb
475 def notify_value_changed(self): 1ab
476 RideVariableUpdated(item=self).publish()
478 def notify_variable_added(self): 1ab
479 self.parent.notify_variable_added(self)
481 def validate_name(self, new_name): 1ab
482 if variablematcher.is_scalar_variable(self.name):
483 return self.parent.validate_scalar_variable_name(new_name, self)
484 if variablematcher.is_dict_variable(self.name):
485 return self.parent.validate_dict_variable_name(new_name, self)
486 return self.parent.validate_list_variable_name(new_name, self)
488 def move_up(self): 1ab
489 return self._parent.move_up(self.index)
491 def move_down(self): 1ab
492 return self._parent.move_down(self.index)
494 def __eq__(self, other): 1ab
495 if self is other: 2hcCbicObPbQbsc1cXctc`b{b=b|b
496 return True 21c
497 if other.__class__ != self.__class__: 2hcCbicObPbQbscXctc`b{b=b|b
498 return False 2icXc`b{b=b|b
499 return self.var == other.var 2hcCbObPbQbsctc=b
501 def __hash__(self): 1ab
502 return hash(self.var) + 1
505def import_controller(parent, import_): 1ab
506 if import_.type == 'Resource': 2a # Zb2 9b!b#b$bwb+ C Q R zb4 xbE P 'b$ (b5 Y B x T y 0bN D K o M L G p ) *
507 return ResourceImportController(parent, import_) 2a # $bwb+ C Q R zb4 xbE P $ 5 Y B x T y N D K o M L G p ) *
508 elif import_.type == 'Library': 2a # Zb2 9b!b#bwb+ C Q R zb4 xbE P 'b(b0bD
509 return LibraryImportController(parent, import_) 2a # Zb2 9b!b#bwb+ C Q R zb4 xbE P 'b0b
510 return VariablesImportController(parent, import_) 2a xb(bD
513class _ImportController(_SettingController): 1ab
515 def __init__(self, parent_controller, data): 1ab
516 super().__init__(parent_controller, data) 2a # Zb2 9b!b#b$bwb+ C Q R zb4 xbE P 'b$ (b5 Y B x T y 0bjcN D K o M L G p ) *
517 self.is_resource = None 2a # Zb2 9b!b#b$bwb+ C Q R zb4 xbE P 'b$ (b5 Y B x T y 0bjcN D K o M L G p ) *
519 def _init(self, import_): 1ab
520 self._import = import_ 2a # Zb2 9b!b#b$bwb+ C Q R zb4 xbE P 'b$ (b5 Y B x T y 0bjcN D K o M L G p ) *
521 self.type = self._import.type 2a # Zb2 9b!b#b$bwb+ C Q R zb4 xbE P 'b$ (b5 Y B x T y 0bjcN D K o M L G p ) *
523 def _label(self, data): 1ab
524 return data.type 2a # Zb2 9b!b#b$bwb+ C Q R zb4 xbE P 'b$ (b5 Y B x T y 0bjcN D K o M L G p ) *
526 @property 1ab
527 def name(self): 1ab
528 return self._import.name 2a wbC Q R zb4 xbE P 5 Y B x T y 2c3c4clc5crc6c0b7cmc8cN #c$c) 9c
530 @property 1ab
531 def alias(self): 1ab
532 return self._import.alias or '' 2wb+ C Q R
534 @property 1ab
535 def args(self): 1ab
536 return self._import.args or [] 2wb+ C Q R
538 @property 1ab
539 def display_value(self): 1ab
540 value = self.args + ([ALIAS_MARKER, self.alias] if self.alias else []) 1+
541 return ' | '.join(value) 1+
543 @property 1ab
544 def dirty(self): 1ab
545 return self._parent.dirty
547 def has_error(self): 1ab
548 return False
550 def get_imported_controller(self): 1ab
551 return None 1a#F
553 def set_value(self, name, args=None, alias=''): 1ab
554 self._import.name = name 12CQREBxy
555 self._import.args = utils.split_value(args or []) 12CQREBxy
556 self._import.alias = alias 12CQREBxy
557 self._parent.mark_dirty() 12CQREBxy
558 self.publish_edited() 12CQREBxy
559 self.import_loaded_or_modified() 12CQREBxy
560 return self 12CQREBxy
562 def import_loaded_or_modified(self): 1ab
563 self._parent.notify_imports_modified() 12CQREBxy
564 if not self.is_resource: 564 ↛ 566line 564 didn't jump to line 566 because the condition on line 564 was always true12CQREBxy
565 return 12CQREBxy
566 self._parent.resource_import_modified(self.name)
568 def remove(self): 1ab
569 self.parent.remove_import_data(self._import) 1No
571 def publish_added(self): 1ab
572 RideImportSettingAdded( 2a Zb2 9b!b#bzb4 xb'b$ (bK o M L G p *
573 datafile=self.datafile_controller,
574 import_controller=self, type=self.type.lower()).publish()
576 def publish_edited(self): 1ab
577 RideImportSettingChanged( 12CQREBxy
578 datafile=self.datafile_controller,
579 import_controller=self, type=self.type.lower()).publish()
581 def publish_removed(self): 1ab
582 RideImportSettingRemoved(datafile=self.datafile_controller, 2Zb2 P N o p
583 import_controller=self,
584 type=self.type.lower()).publish()
587class ResourceImportController(_ImportController): 1ab
588 is_resource = True 1ab
589 _resolved_import = False 1ab
590 _previous_imported_controller = None 1ab
592 def __init__(self, parent_controller, data): 1ab
593 super().__init__(parent_controller, data) 2a # $bwb+ C Q R zb4 xbE P $ 5 Y B x T y jcN D K o M L G p ) *
594 self._imported_resource_controller = None 2a # $bwb+ C Q R zb4 xbE P $ 5 Y B x T y jcN D K o M L G p ) *
596 def set_value(self, name, args=None, alias=''): 1ab
597 self._previous_imported_controller = self.get_imported_controller() 1CEBxy
598 self.unresolve() 1CEBxy
599 _ImportController.set_value(self, name, args, alias) 1CEBxy
601 def get_imported_controller(self): 1ab
602 if not self._resolved_import: 2a # C 4 E P $ 5 Y B x T y lcrcmcN F K o M L G p ) * !c
603 self._imported_resource_controller = self.parent.resource_file_controller_factory.find_with_import( 2a # C 4 E P $ 5 Y B x T y lcrcmcN F K o M L G p ) *
604 self._import)
605 if self._imported_resource_controller: 2a # C 4 E P $ 5 Y B x T y lcrcmcN F K o M L G p ) *
606 self._imported_resource_controller.add_known_import(self) 2a # $ 5 Y B x T y lcmcN F K o L G p )
607 self._resolved_import = True 2a # C 4 E P $ 5 Y B x T y lcrcmcN F K o M L G p ) *
608 return self._imported_resource_controller 2a # C 4 E P $ 5 Y B x T y lcrcmcN F K o M L G p ) * !c
610 def has_error(self): 1ab
611 # un-resolve before checking import errors
612 self.unresolve() 2lcrcmc
613 return self.get_imported_controller() is None 2lcrcmc
615 def publish_added(self): 1ab
616 # Resolve the import <-> ResourceFileController link
617 self.get_imported_controller() 14$KoMLGp*
618 _ImportController.publish_added(self) 14$KoMLGp*
620 def publish_removed(self): 1ab
621 self._previous_imported_controller = self.get_imported_controller() 1PNop
622 # Unresolve the import <-> ResourceFileController link
623 self.unresolve() 1PNop
624 self._prevent_resolve() 1PNop
625 _ImportController.publish_removed(self) 1PNop
627 def _prevent_resolve(self): 1ab
628 self._resolved_import = True 1PNop
629 self._imported_resource_controller = None 1PNop
631 def get_previous_imported_controller(self): 1ab
632 return self._previous_imported_controller 1Gp
634 def unresolve(self): 1ab
635 if self._resolved_import and self._imported_resource_controller: 2C E P 5 Y B x T y lcrcmcN o p
636 self._imported_resource_controller.remove_known_import(self) 15YBxTyNop
637 self._resolved_import = False 2C E P 5 Y B x T y lcrcmcN o p
639 def contains_filename(self, filename): 1ab
640 return self.name.endswith(filename) 2Y B ) 9c
642 def change_name(self, old_name, new_name): 1ab
643 # print(f"DEBUG: settingcontrollers.py ResourceImportController change_name ENTER\n"
644 # f"old_name={old_name} new_name={new_name}")
645 if self.contains_filename(old_name): 1YB
646 self.set_value(self.name[:-len(old_name)] + new_name) 1B
647 else:
648 # If original result has changed and this import relies on
649 # variables, can't know if import is still resolved
650 self.unresolve() 1Y
652 def change_format(self, cformat): 1ab
653 if self._has_format(): 1xTy
654 self.set_value(utils.replace_extension(self.name, cformat)) 1xy
655 else:
656 self.unresolve() 1T
658 def _has_format(self): 1ab
659 parts = self.name.rsplit('.', 1) 1xTy
660 if len(parts) == 1: 1xTy
661 return False 1T
662 return parts[-1].lower() in ['txt', 'tsv', 'robot', 'resource'] 1xy
665class LibraryImportController(_ImportController): 1ab
666 is_resource = False 1ab
668 def has_error(self): 1ab
669 return not self.parent.parent.is_library_import_ok(self._data) 22c3c4c5c0b7c
672class VariablesImportController(_ImportController): 1ab
673 is_resource = False 1ab
675 def has_error(self): 1ab
676 return not self.parent.parent.is_variables_import_ok(self._data) 26c8c