diff --git a/app/solaar_cli.py b/app/solaar_cli.py index b2dd1cba..10355a01 100644 --- a/app/solaar_cli.py +++ b/app/solaar_cli.py @@ -303,21 +303,16 @@ def config_device(receiver, args): if old_value is None: _fail("could not read current value of '%s'" % setting.name) - old_index = setting.choices.index(old_value) if value == 'lower': - if old_index == 0: - sys.stderr.write("'%s' already at the lowest value") - return - value = setting.choices[old_index - 1:old_index][0] + lower_values = setting.choices[:old_value] + value = lower_values[-1] if lower_values else setting.choices[:][0] elif value == 'higher': - if old_index == len(setting.choices) - 1: - sys.stderr.write("'%s' already at the highest value") - return - value = setting.choices[old_index + 1:old_index + 2][0] + higher_values = setting.choices[old_value + 1:] + value = higher_values[0] if higher_values else setting.choices[:][-1] elif value in ('highest', 'max'): - value = setting.choices[-1:][0] + value = setting.choices[:][-1] elif value in ('lowest', 'min'): - value = setting.choices[:1][0] + value = setting.choices[:][0] elif value not in setting.choices: _fail("possible values for '%s' are: [%s]" % (setting.name, ', '.join(str(v) for v in setting.choices))) value = setting.choices[value] diff --git a/lib/logitech/unifying_receiver/common.py b/lib/logitech/unifying_receiver/common.py index 7afa06bb..7346f75f 100644 --- a/lib/logitech/unifying_receiver/common.py +++ b/lib/logitech/unifying_receiver/common.py @@ -45,9 +45,17 @@ class NamedInt(int): class NamedInts(object): - """A collection of NamedInt values. + """An ordered set of NamedInt values. - Behaves partially like a sorted list (by int value), partially like a dict. + Indexing can be made by int or string, and will return the corresponding + NamedInt if it exists in this set, or `None`. + + Extracting slices will return all present NamedInts in the given interval + (extended slices are not supported). + + Assigning a string to an indexed int will create a new NamedInt in this set; + if the value already exists in the set (int or string), ValueError will be + raised. """ __slots__ = ['__dict__', '_values', '_indexed', '_fallback'] @@ -75,10 +83,10 @@ class NamedInts(object): if unknown_bits: yield 'unknown:%06X' % unknown_bits - def index(self, value): - if value in self._values: - return self._values.index(value) - raise IndexError('%s not found' % value) + # def index(self, value): + # if value in self._values: + # return self._values.index(value) + # raise IndexError('%s not found' % value) def __getitem__(self, index): if isinstance(index, int): @@ -90,13 +98,36 @@ class NamedInts(object): self._values = sorted(self._values + [value]) return value - elif isinstance(index, slice): - return self._values[index] - elif isinstance(index, basestring): if index in self.__dict__: return self.__dict__[index] + elif isinstance(index, slice): + if index.start is None and index.stop is None: + return self._values[:] + + v_start = int(self._values[0]) if index.start is None else int(index.start) + v_stop = (self._values[-1] + 1) if index.stop is None else int(index.stop) + + if v_start > v_stop or v_start > self._values[-1] or v_stop <= self._values[0]: + return [] + + if v_start <= self._values[0] and v_stop > self._values[-1]: + return self._values[:] + + start_index = 0 + stop_index = len(self._values) + for i, value in enumerate(self._values): + if value < v_start: + start_index = i + 1 + elif index.stop is None: + break + if value >= v_stop: + stop_index = i + break + + return self._values[start_index:stop_index] + def __setitem__(self, index, name): assert isinstance(index, int) if isinstance(name, NamedInt):