class Embedded(Widget): enabled = xom.Boolean(default=True) # font height = xom.Integer(default=200) group_name = xom.String(default="") macros = Macros() file = xom.String(default="") resize = xom.Enum(["none", "content", "widget"]) tooltip = xom.String(default="") visible = xom.Boolean(default=True) width = xom.Integer(default=300) def setParentMacros(self, macros): """ Invoke base class function and also update opi_path field. """ super(Embedded, self).setParentMacros(macros) m = {} if self.macros.include_parent_macros: m = dict(macros) # Same macros defined in widget overwrite parent macros for k, v in self.macros.items(): m[k] = Macros.replace(v, m) if m and self.file: # Turn into a query string self.file += "?" escape = tornado.escape.url_escape self.file += "&".join("{0}={1}".format(escape(k), escape(v)) for k, v in m.iteritems())
class LinkingContainer(Widget): background_color = Color() border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) enabled = xom.Boolean(default=True) # font foreground_color = Color() group_name = xom.String(default="") macros = Macros() opi_file = xom.String(default="") resize_behaviour = xom.Enum(["resize", "fit", "crop", "scroll"]) tooltip = xom.String(default="") visible = xom.Boolean(default=True) def setParentMacros(self, macros): """ Invoke base class function and also update opi_path field. """ super(LinkingContainer, self).setParentMacros(macros) m = {} if self.macros.include_parent_macros: m = dict(macros) # Same macros defined in widget overwrite parent macros for k, v in self.macros.items(): m[k] = Macros.replace(v, m) if m and self.opi_file: # Turn into a query string self.opi_file += "?" escape = tornado.escape.url_escape self.opi_file += "&".join("{0}={1}".format(escape(k), escape(v)) for k, v in m.iteritems())
class TextEntry(Widget): alarm_border = xom.Boolean(default=True) background_color = Color(default={"red": 128, "green": 255, "blue": 255}) height = xom.Integer(default=20) # font foreground_color = Color(default={"red": 0, "green": 0, "blue": 0}) format_type = xom.Enum(FORMAT_TYPES, tagname="format") multi_line = xom.Boolean(default=False) precision = xom.Integer(default=-1) pv_name = xom.String(default="") pv_value = xom.String(default="") show_units = xom.Boolean(default=True) tooltip = xom.String(default="") visible = xom.Boolean(default=True) width = xom.Integer(default=100) wrap_words = xom.Boolean(default=False) def parse(self, node): done = super(TextEntry, self).parse(node) if self.precision == -1: fmt = "%s" else: fmt = self.format_type.get() precision = self.precision if self.format_type.index == 5: precision = 8 fmt = fmt.format(precision) self.setField("value_format", fmt) return done
class TextUpdate(Widget): alarm_border = xom.Boolean(default=True) background_color = Color(default={"red": 240, "green": 240, "blue": 240}) # font foreground_color = Color(default={"red": 0, "green": 0, "blue": 0}) format_type = xom.Enum(FORMAT_TYPES, tagname="format") height = xom.Integer(default=20) horizontal_alignment = xom.Enum(HORIZONTAL_ALIGN) precision = xom.Integer(default=-1) pv_name = xom.String(default="") pv_value = xom.String(default="") rotation = xom.Enum(["0deg", "90deg", "180deg", "270deg"]) show_units = xom.Boolean(default=True) tooltip = xom.String(default="") transparent = xom.Boolean(default=False) vertical_alignment = xom.Enum(VERTICAL_ALIGN) visible = xom.Boolean(default=True) width = xom.Integer(default=100) wrap_words = xom.Boolean(default=True) def parse(self, node): done = super(TextUpdate, self).parse(node) if self.precision == -1: fmt = "%s" else: fmt = self.format_type.get() precision = self.precision if self.format_type.index == 5: precision = 8 fmt = fmt.format(precision) self.setField("value_format", fmt) return done
class BoolButton(Widget): background_color = Color() bit = xom.Integer(default=0) border_alarm_sensitive = xom.Boolean(default=False) border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) confirm_message = xom.String(default="") data_type = xom.Enum(["bit", "enum"]) enabled = xom.Boolean(default=True) # font foreground_color = Color() labels_from_pv = xom.Boolean(default=False) off_color = Color() off_label = xom.String(default="") off_state = xom.String(default="") on_color = Color() on_label = xom.String(default="") on_state = xom.String(default="") password = xom.String(default="") push_action_index = xom.Integer(default=0) pv_name = xom.String(default="") pv_value = xom.String(default="") released_action_index = xom.Integer(default=0) show_boolean_label = xom.Boolean(default=True) show_confirm_dialog = xom.Enum(["no", "both", "push", "release"]) show_led = xom.Boolean(default=True) square_button = xom.Boolean(default=False) toggle_button = xom.Boolean(default=True) tooltip = xom.String(default="") visible = xom.Boolean(default=True)
class MultiStateLED(Widget): alarm_border = xom.Boolean(default=False) #font foreground_color = Color(default={"red": 0, "green": 0, "blue": 0}) height = xom.Integer(default=20) pv_name = xom.String(default="") pv_value = xom.String(default="") square = xom.Boolean(default=False) states = MultiStateLEDList() tooltip = xom.String(default="") visible = xom.Boolean(default=True) width = xom.Integer(default=20)
class CheckBox(Widget): alarm_border = xom.Boolean(default=True) bit = xom.Integer(default=0) enabled = xom.Boolean(default=True) # font height = xom.Integer(default=20) label = xom.String(default="") pv_name = xom.String(default="") pv_value = xom.String(default="") tooltip = xom.String(default="") visible = xom.Boolean(default=True) width = xom.Integer(default=100)
class Widget(xom.Model): """ Base Widget model with common fields. """ widget_type = xom.String() name = xom.String(default="") x = xom.Integer(default=0) y = xom.Integer(default=0) width = xom.Integer(default=100) height = xom.Integer(default=40) actions = ActionList() def __init__(self, typeId=None, **kwds): self._typeId = (self.__class__.__name__ if typeId is None else typeId) super(Widget, self).__init__(**kwds) @staticmethod def parseType(node): # Remap some container names to match code widgetMap = { "checkbox": "CheckBox", "groupingContainer": "GroupingContainer", "linkingContainer": "LinkingContainer", } for key, value in node.attributes.items(): if key == "typeId": if value.startswith("org.csstudio.opibuilder."): widgetType = value.split(".")[-1] return widgetMap.get(widgetType, widgetType) raise ValueError("<{0}> Invalid attribute typeId {1}".format( node.nodeName, value)) else: raise ValueError("<{0}> Missing attribute typeId".format( node.nodeName)) def getType(self): return self._typeId def parse(self, node): """ Overloaded function makes sure we're parsing <widget> node. """ typeId = Widget.parseType(node) if self._typeId != typeId and self._typeId != "Widget": raise ValueError("<{0}> Attribute typeId mismatch {1}!={2}".format( node.nodeName, typeId, self._typeId)) return super(Widget, self).parse(node) def setParentMacros(self, macros): """ Called from converter to recognize additional macros provided by parent. """ for action in self.actions: action.addMacros(macros)
class ActionButton(Widget): background_color = Color(default={"red": 210, "green": 210, "blue": 210}) enabled = xom.Boolean(default=True) # font foreground_color = Color(default={"red": 0, "green": 0, "blue": 0}) height = xom.Integer(default=30) horizontal_alignment = xom.Enum(HORIZONTAL_ALIGN, default=0) pv_name = xom.String(default="") pv_value = xom.String(default="") rotation = xom.Enum(["0deg", "90deg", "180deg", "270deg"]) text = xom.String(default="$(actions)") tooltip = xom.String(default="") visible = xom.Boolean(default=True) width = xom.Integer(default=100)
class Label(Widget): background_color = Color(default={"red": 255, "green": 255, "blue": 255}) # font foreground_color = Color(default={"red": 0, "green": 0, "blue": 0}) height = xom.Integer(default=20) horizontal_alignment = xom.Enum(HORIZONTAL_ALIGN, default=0) rotation = xom.Enum(["0deg", "90deg", "180deg", "270deg"]) text = xom.String(default="") tooltip = xom.String(default="") transparent = xom.Boolean(default=False) vertical_alignment = xom.Enum(VERTICAL_ALIGN, default=0) visible = xom.Boolean(default=True) wrap_words = xom.Boolean(default=True) width = xom.Integer(default=100)
class CheckBox(Widget): background_color = Color() bit = xom.Integer(default=0) border_alarm_sensitive = xom.Boolean(default=False) border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) enabled = xom.Boolean(default=True) # font foreground_color = Color() label = xom.String(default="") pv_name = xom.String(default="") pv_value = xom.String(default="") tooltip = xom.String(default="") visible = xom.Boolean(default=True)
class LEDState(xom.Model): value = xom.Number() label = xom.String(default="") color = Color() def parse(self, node): pass
class Label(Widget): """ Label widget handler. """ background_color = Color() border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) enabled = xom.Boolean(default=True) # font foreground_color = Color() horizontal_alignment = xom.Enum(HORIZONTAL_ALIGN, default=0) text = xom.String(default="") tooltip = xom.String(default="") transparent = xom.Boolean(default=False) vertical_alignment = xom.Enum(VERTICAL_ALIGN, default=0) visible = xom.Boolean(default=True) wrap_words = xom.Boolean(default=True)
class Widget(xom.Model): """ Base Widget model with common fields. """ actions = ActionList() name = xom.String(default="") x = xom.Integer(default=0) y = xom.Integer(default=0) height = xom.Integer(default=-1) width = xom.Integer(default=-1) def __init__(self, typeId=None, **kwds): self._typeId = (self.__class__.__name__ if typeId is None else typeId) super(Widget, self).__init__(**kwds) self.setField("widget_type", self._typeId) @staticmethod def parseType(node): # Remap some container names to match code widgetMap = { "action_button": "ActionButton", "bool_button": "BoolButton", "checkbox": "CheckBox", "embedded": "Embedded", "group": "Group", "label": "Label", "led": "LED", "multi_state_led": "MultiStateLED", "textentry": "TextEntry", "textupdate": "TextUpdate", } for key, value in node.attributes.items(): if key == "type": return widgetMap.get(value, value) else: raise ValueError("<{0}> Missing attribute type".format( node.nodeName)) def getType(self): return self._typeId def parse(self, node): """ Overloaded function makes sure we're parsing <widget> node. """ typeId = Widget.parseType(node) if self._typeId != typeId: if self._typeId != "Widget": raise ValueError( "<{0}> Attribute type mismatch {1}!={2}".format( node.nodeName, typeId, self._typeId)) self._typeId = typeId self.setField("widget_type", self._typeId) return super(Widget, self).parse(node) def setParentMacros(self, macros): """ Called from converter to recognize additional macros provided by parent. """ pass
class TextInput(Widget): background_color = Color() border_alarm_sensitive = xom.Boolean(default=False) border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) enabled = xom.Boolean(default=True) #font foreground_color = Color() format_type = xom.Integer(default=0) horizontal_alignment = xom.Enum(HORIZONTAL_ALIGN) limits_from_pv = xom.Boolean(default=False) maximum = xom.Number(default=100) minimum = xom.Number(default=0) multiline_input = xom.Boolean(default=False) precision = xom.Integer(default=0) precision_from_pv = xom.Boolean(default=True) pv_name = xom.String(default="") pv_value = xom.String(default="") selector_type = xom.Enum(["none", "file", "datetime"]) show_units = xom.Boolean(default=True) text = xom.String(default="") tooltip = xom.String(default="") transparent = xom.Boolean(default=False) visible = xom.Boolean(default=True) def parse(self, node): super(TextInput, self).parse(node) if self.precision_from_pv: fmt = None else: try: fmt = FORMAT_TYPES[self.format_type] except: fmt = FORMAT_TYPES[0] precision = self.precision if self.format_type == 5: precision = 8 fmt = fmt.format(precision) self.setField("value_format", fmt) return True
class ActionButton(Widget): background_color = Color() border_alarm_sensitive = xom.Boolean(default=False) border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) enabled = xom.Boolean(default=True) # font foreground_color = Color() horizontal_alignment = xom.Enum(HORIZONTAL_ALIGN, default=0) push_action_index = xom.Integer(default=0) pv_name = xom.String(default="") pv_value = xom.String(default="") style = xom.Integer(default=0) text = xom.String(default="") toggle_button = xom.Boolean(default=False) tooltip = xom.String(default="") visible = xom.Boolean(default=True)
class LED(Widget): alarm_border = xom.Boolean(default=False) bit = xom.Integer(default=0) enabled = xom.Boolean(default=True) #font foreground_color = Color(default={"red": 0, "green": 0, "blue": 0}) height = xom.Integer(default=20) labels_from_pv = xom.Boolean(default=False) off_label = xom.String(default="") off_color = Color(default={"red": 60, "green": 100, "blue": 60}) on_label = xom.String(default="") on_color = Color(default={"red": 60, "green": 255, "blue": 60}) pv_name = xom.String(default="") pv_value = xom.String(default="") square = xom.Boolean(default=False) tooltip = xom.String(default="") visible = xom.Boolean(default=True) width = xom.Integer(default=20)
class OpenPathAction(Action): path = xom.String() def parse(self, node): """ Overloaded method does all from base class plus escapes path parameter. """ super(OpenPathAction, self).parse(node) self.path = tornado.escape.url_escape(self.path, False) return True
class Action(xom.Model): """ Model for a single action. """ type = xom.String(tagname="__self__", attrname="type") description = xom.String(default="") def __init__(self, **kwds): kwds["tagname"] = "action" super(Action, self).__init__(**kwds) def addMacros(self, macros): """ Add all available macros to actions that need pass macros along. This is a hook for actions that open new display and need to pass macros to it. Derived classes should not use this hook for replace existing macros, that is done by Converter. Default is no action. """ pass
class TextUpdate(Widget): """ TextUpdate widget handler. """ background_color = Color() border_alarm_sensitive = xom.Boolean(default=False) border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) foreground_color = Color() format_type = xom.Integer(default=0) horizontal_alignment = xom.Enum(HORIZONTAL_ALIGN) precision = xom.Integer(default=0) precision_from_pv = xom.Boolean(default=True) pv_name = xom.String(default="") pv_value = xom.String(default="") show_units = xom.Boolean(default=True) text = xom.String(default="") tooltip = xom.String(default="") transparent = xom.Boolean(default=False) vertical_alignment = xom.Enum(VERTICAL_ALIGN) visible = xom.Boolean(default=True) wrap_words = xom.Boolean(default=True) def parse(self, node): done = super(TextUpdate, self).parse(node) if self.precision_from_pv: fmt = None else: try: fmt = FORMAT_TYPES[self.format_type] except: fmt = FORMAT_TYPES[0] precision = self.precision if self.format_type == 5: precision = 8 fmt = fmt.format(precision) self.setField("value_format", fmt) return done
class Group(Widget): background_color = Color(default={"red": 255, "green": 255, "blue": 255}) enabled = xom.Boolean(default=True) # font foreground_color = Color(default={"red": 0, "green": 0, "blue": 0}) height = xom.Integer(default=200) macros = Macros() style = xom.Enum(["group", "title", "border", "none"]) tooltip = xom.String(default="") visible = xom.Boolean(default=True) widgets = WidgetList(tagname="widget", default=[]) width = xom.Integer(default=300)
class GroupingContainer(Widget): background_color = Color() border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) enabled = xom.Boolean(default=True) # font foreground_color = Color() lock_children = xom.Boolean(default=False) macros = Macros() show_scrollbar = xom.Boolean(default=True) tooltip = xom.String(default="") visible = xom.Boolean(default=True) widgets = WidgetList(tagname="widget", default=[])
class Display(xom.Model): """ Model for the main Display widget. """ actions = ActionList() macros = Macros() name = xom.String(default="") widgets = WidgetList(tagname="widget", default=[]) def __init__(self, **kwds): super(Display, self).__init__(tagname="display", **kwds) self.setField("widget_type", "Display") def getType(self): return "Display" def setParentMacros(self, macros): """ Called from converter to recognize additional macros provided by parent. """ for action in self.actions: action.addMacros(macros)
class WritePvAction(Action): pv_name = xom.String() value = xom.String()
class LEDState(xom.Model): value = xom.Number(default=0) label = xom.String(default="") color = Color()
class LED(Widget): background_color = Color() bit = xom.Integer(default=0) border_alarm_sensitive = xom.Boolean(default=False) border_color = Color() border_style = xom.Enum(BORDER_STYLES) border_width = xom.Integer(default=0) data_type = xom.Enum(["bit", "enum"]) enabled = xom.Boolean(default=True) #font foreground_color = Color() pv_name = xom.String(default="") pv_value = xom.String(default="") show_boolean_label = xom.Boolean(default=False) square_led = xom.Boolean(default=False) state_count = xom.Integer(default=2) tooltip = xom.String(default="") visible = xom.Boolean(default=True) def parse(self, node): """ Turn LED XML nodes into a list of states. Handles multi-LED and 2-LED cases. Dynamically adds state_count and states fields to this Model. states field is sorted list of Models containing sub-fields value,color,label for each state. """ super(LED, self).parse(node) class LEDState(xom.Model): value = xom.Number() label = xom.String(default="") color = Color() def parse(self, node): pass # Read number of total states, default to 2 for off/on LED count = xom.Integer(tagname="state_count", default=2) child = node.firstChild while child is not None: if child.nodeName == "state_count": count.parse(child) break child = child.nextSibling self.setField("state_count", count.get()) # Create a list of all state models states = [] for i in range(self.state_count): state = LEDState() states.append(state) # Parse nodes describing states - handles 2 state LED as well as n-state LED child = node.firstChild while child is not None: try: check, fieldname, i = child.nodeName.split("_") i = int(i) if check == "state": if fieldname == "color": states[i].color.setTagName(child.nodeName, True) states[i].color.parse(child) elif fieldname == "label": states[i].label.setTagName(child.nodeName, True) states[i].label.parse(child) elif fieldname == "value": states[i].value.setTagName(child.nodeName, True) states[i].value.parse(child) except: if child.nodeName == "off_color": states[0].color.setTagName(child.nodeName, True) states[0].color.parse(child) states[0].value.setDefault(0) elif child.nodeName == "off_label": states[0].label.setTagName(child.nodeName, True) states[0].label.parse(child) states[0].value.setDefault(0) elif child.nodeName == "on_color": states[1].color.setTagName(child.nodeName, True) states[1].color.parse(child) states[1].value.setDefault(1) elif child.nodeName == "on_label": states[1].label.setTagName(child.nodeName, True) states[1].label.parse(child) states[1].value.setDefault(1) child = child.nextSibling # Transform fields into Python objects for i in range(self.state_count): states[i].setField("label", states[i].label.get()) states[i].setField("value", states[i].value.get()) # Assign 'states' field self.setField("states", states) return True
class Action(opi.Action): description = xom.String(default="")
class WritePvAction(Action): pv_name = xom.String() value = xom.String() timeout = xom.Integer(default=10) confirm_message = xom.String(default="")