rules: add rule condition for checking device settings
This commit is contained in:
parent
eedf4bfffb
commit
00176a1df8
|
@ -412,6 +412,43 @@ class Report(Condition):
|
|||
return {'Report': self.report}
|
||||
|
||||
|
||||
# Setting(device, setting, [key], value...)
|
||||
class Setting(Condition):
|
||||
def __init__(self, args):
|
||||
if not (isinstance(args, list) and len(args) > 2):
|
||||
_log.warn('rule Setting argument not list with minimum length 3: %s', args)
|
||||
self.args = []
|
||||
else:
|
||||
self.args = args
|
||||
|
||||
def __str__(self):
|
||||
return 'Setting: ' + ' '.join([str(a) for a in self.args])
|
||||
|
||||
def evaluate(self, report, notification, device, status, last_result):
|
||||
import solaar.ui.window as _window
|
||||
if len(self.args) < 3:
|
||||
return None
|
||||
dev = _window.find_device(self.args[0]) if self.args[0] is not None else device
|
||||
if dev is None:
|
||||
_log.warn('Setting condition: device %s is not known', self.args[0])
|
||||
return False
|
||||
setting = next((s for s in dev.settings if s.name == self.args[1]), None)
|
||||
if setting is None:
|
||||
_log.warn('Setting condition: setting %s is not the name of a setting for %s', self.args[1], dev.name)
|
||||
return None
|
||||
# should the value argument be checked to be sure it is acceptable?? needs to be careful about boolean toggle
|
||||
# TODO add compare methods for more validators
|
||||
try:
|
||||
result = setting.compare(self.args[2:], setting.read())
|
||||
except Exception as e:
|
||||
_log.warn('Setting condition: error when checking setting %s: %s', self.args, e)
|
||||
result = False
|
||||
return result
|
||||
|
||||
def data(self):
|
||||
return {'Setting': self.args[:]}
|
||||
|
||||
|
||||
MODIFIERS = {
|
||||
'Shift': int(Gdk.ModifierType.SHIFT_MASK),
|
||||
'Control': int(Gdk.ModifierType.CONTROL_MASK),
|
||||
|
@ -635,7 +672,7 @@ class KeyPress(Action):
|
|||
def evaluate(self, feature, notification, device, status, last_result):
|
||||
current = gkeymap.get_modifier_state()
|
||||
if _log.isEnabledFor(_INFO):
|
||||
_log.info('KeyPress action: %s, modifiers %s %s', self.key_symbols, current, [hex(k) for k in self.keys])
|
||||
_log.info('KeyPress action: %s, modifiers %s %s', self.key_symbols, current, [hex(k) for k in self.key_symbols])
|
||||
self.keyDown(self.key_symbols, current)
|
||||
self.keyUp(reversed(self.key_symbols), current)
|
||||
if x11:
|
||||
|
@ -819,6 +856,7 @@ COMPONENTS = {
|
|||
'MouseProcess': MouseProcess,
|
||||
'Feature': Feature,
|
||||
'Report': Report,
|
||||
'Setting': Setting,
|
||||
'Modifiers': Modifiers,
|
||||
'Key': Key,
|
||||
'Test': Test,
|
||||
|
|
|
@ -67,6 +67,11 @@ class Validator:
|
|||
def to_string(cls, value):
|
||||
return (str(value))
|
||||
|
||||
def compare(self, args, current):
|
||||
if len(args) != 1:
|
||||
return False
|
||||
return args[0] == current
|
||||
|
||||
|
||||
class BooleanValidator(Validator):
|
||||
__slots__ = ('true_value', 'false_value', 'read_skip_byte_count', 'write_prefix_bytes', 'mask', 'needs_current_value')
|
||||
|
@ -316,6 +321,9 @@ class Setting:
|
|||
def acceptable(self, args, current):
|
||||
return self._validator.acceptable(args, current) if self._validator else None
|
||||
|
||||
def compare(self, args, current):
|
||||
return self._validator.compare(args, current) if self._validator else None
|
||||
|
||||
def apply(self):
|
||||
assert hasattr(self, '_value')
|
||||
assert hasattr(self, '_device')
|
||||
|
@ -789,6 +797,14 @@ class BitFieldValidator(Validator):
|
|||
val = bool_or_toggle(current[str(int(key))], args[1])
|
||||
return None if val is None else [str(int(key)), val]
|
||||
|
||||
def compare(self, args, current):
|
||||
if len(args) != 2:
|
||||
return False
|
||||
key = next((key for key in self.options if key == args[0]), None)
|
||||
if key is None:
|
||||
return False
|
||||
return args[1] == current[str(int(key))]
|
||||
|
||||
|
||||
class BitFieldWithOffsetAndMaskValidator(Validator):
|
||||
__slots__ = ('byte_count', 'options', '_option_from_key', '_mask_from_offset', '_option_from_offset_mask')
|
||||
|
@ -878,7 +894,15 @@ class BitFieldWithOffsetAndMaskValidator(Validator):
|
|||
if key is None:
|
||||
return None
|
||||
val = bool_or_toggle(current[str(int(key))], args[1])
|
||||
return None if val is None else [str(key), val]
|
||||
return None if val is None else [str(int(key)), val]
|
||||
|
||||
def compare(self, args, current):
|
||||
if len(args) != 2:
|
||||
return False
|
||||
key = next((option.id for option in self.options if option.as_int() == args[0]), None)
|
||||
if key is None:
|
||||
return False
|
||||
return args[1] == current[str(int(key))]
|
||||
|
||||
|
||||
class ChoicesValidator(Validator):
|
||||
|
@ -1026,6 +1050,14 @@ class ChoicesMapValidator(ChoicesValidator):
|
|||
choice = next((item for item in choices if item == args[1]), None)
|
||||
return [str(int(key)), int(choice)] if choice is not None else None
|
||||
|
||||
def compare(self, args, current):
|
||||
if len(args) != 2:
|
||||
return False
|
||||
key = next((key for key in self.choices if key == int(args[0])), None)
|
||||
if key is None:
|
||||
return False
|
||||
return args[1] == current[str(int(key))]
|
||||
|
||||
|
||||
class RangeValidator(Validator):
|
||||
kind = KIND.range
|
||||
|
@ -1071,6 +1103,14 @@ class RangeValidator(Validator):
|
|||
# None if len(args) != 1 or type(arg) != int or arg < self.min_value or arg > self.max_value else args)
|
||||
return None if len(args) != 1 or type(arg) != int or arg < self.min_value or arg > self.max_value else args
|
||||
|
||||
def compare(self, args, current):
|
||||
if len(args) == 1:
|
||||
return args[0] == current
|
||||
elif len(args) == 2:
|
||||
return args[0] <= current and current <= args[1]
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class MultipleRangeValidator(Validator):
|
||||
|
||||
|
@ -1157,6 +1197,10 @@ class MultipleRangeValidator(Validator):
|
|||
return None
|
||||
return [str(int(item)), {**args[1]}]
|
||||
|
||||
def commpare(self, args, current):
|
||||
_log.warn('compare not implemented for multiple range settings')
|
||||
return False
|
||||
|
||||
|
||||
class ActionSettingRW:
|
||||
"""Special RW class for settings that turn on and off special processing when a key or button is depressed"""
|
||||
|
|
Loading…
Reference in New Issue