def base_widget(element): element_tag = element.tag.lower() base_object(element) # add basic node features # all text is handled within this try/except block try: if element.text is not None: element_text = element.text.strip() if WidgetRegister.types[element_tag].get('single-line-text',False) is True: element_text = element.text.replace("\n","") indent() # indent if necessary Compiler.code += element.get("id") + "." + WidgetRegister.types[element_tag]['text'] + "('" + element_text + "')\n" except KeyError: pass # element must not support text # handle properties handleProps(WidgetRegister.types['qwidget'], element) if WidgetRegister.types[element_tag].get('isqt',False) is False: # if this is an oxide widget handleProps(WidgetRegister.types['basewidget'], element) # give it oxide properties # handle signal-slot mechanisms handleSlots(WidgetRegister.types['qwidget'], element) if WidgetRegister.types[element_tag].get('isqt',False) is False: # if this is an oxide widget handleSlots(WidgetRegister.types['basewidget'], element) # give it oxide slots
def Compiler_BoxLayout(element): # @NoSelf for child in element: oxide.parsing.widgets.core.parse_abstract_element(child) indent() if child.tag.lower() in WidgetRegister.layoutCompilers.keys(): # the child is layout Compiler.code += element.get("id") + ".addLayout(" + child.get("id") + ")\n" else: # the child must be a widget Compiler.code += element.get("id") + ".addWidget(" + child.get("id") + ")\n"
def parse_layout_children(element): # this function is obsolete if element.tag.lower() in BoxLayouts: # layout is a child of QBoxLayout for child in element: # for all of the children under the layout parse_abstract_element(child) # parse this child indent() if child.tag.lower() in Layouts: # the child is layout Compiler.code += element.get("id") + ".addLayout(" + child.get("id") + ")\n" else: # the child must be a widget Compiler.code += element.get("id") + ".addWidget(" + child.get("id") + ")\n"
def Compiler_GeneralContainer(element): # @NoSelf if element.__len__() > 0: # if the container has children if element.__len__() == 1: Compiler.direct_resources_child = False # don't create classes for the children's code oxide.parsing.widgets.core.parse_abstract_element(element[0]) # perform special operations on the child if element[0].tag.lower() in WidgetRegister.layoutCompilers.keys(): indent() id = element.get('id') if WidgetRegister.types[element.tag.lower()].get('accepts-central-widget',False) is True: Compiler.code += element.get('id') + "__CENTRALWIDGET" + " = QWidget()\n" Compiler.code += element.get('id') + ".setCentralWidget(" + element.get('id') + "__CENTRALWIDGET)\n" id = element.get('id') + "__CENTRALWIDGET" Compiler.code += id + ".setLayout(" + element[0].get('id') + ")\n" elif WidgetRegister.types[element.tag.lower()].get('accepts-central-widget',False) is True: indent() Compiler.code += element.get('id') + ".setCentralWidget(" + element[0].get('id') + ")\n"
def base_object(element): element_tag = element.tag.lower() # check that the element represents a known widget type try: WidgetRegister.types[element_tag] except KeyError: raise UnkownWidgetError("'" + element.tag + "' is not a known widget type") # here we put in the constructor and check that this is a known widget type if Compiler.direct_resources_child is False: # the code should not be wrapped in a class Compiler.code += "\n" if element.get("id") is None: # if the id has been omitted addDefaultId(element) # generate a default one and add it to the element if Compiler.to_be_own_class is True: element.set("id","self." + element.get('id')) indent() Compiler.code += element.get("id") + " = " + WidgetRegister.types[element_tag]['widgetName'] + "(" if WidgetRegister.types[element_tag].get('isqt',False) is False: # if this is an oxide widget Compiler.code += "'" + prepStr(element.get("styletype","default")) + "'" Compiler.code += ")\n" else: # the code should be wrapped in a class if element.get('name') is None: raise MissingAttributeError(element.tag + " has no name.") if element.get('name').startswith("__"): raise ForbiddenNameError("'name' attribute may not begin with '__'") Compiler.code += "class " + element.get("name") + "(" + WidgetRegister.types[element_tag]['widgetName'] + "):\n" element.set("id","self") add_class_funcs(WidgetRegister.types[element_tag]['widgetName']) # add any utility functions for the class # add the model code add_model(Compiler.current_interfacename,element.get('name')) # __init__ function definition Compiler.code += Compiler.model_indent + "def __init__(self, " + ", ".join(WidgetRegister.types[element_tag].get('init_args',[])) + "):\n" Compiler.code += Compiler.model_indent*2 + WidgetRegister.types[element_tag]['widgetName'] + ".__init__(self, " # basic constructor if WidgetRegister.types[element_tag].get('isqt',False) is False: # if this is an oxide widget Compiler.code += "'" + prepStr(element.get("styletype","default")) + "'" # the add the style type Compiler.code += ", ".join(WidgetRegister.types[element_tag].get('init_args',[])) + ")\n" # give it the necessary __init__ arguments handleProps(WidgetRegister.types[element_tag],element) # handle properites handleSlots(WidgetRegister.types[element_tag], element) # handle events/signals/slots if WidgetRegister.types[element_tag].get('isqt',False) is False: # if this is an oxide widget handleStyleProps(WidgetRegister.types[element_tag],element)
def handleSlots(widgetType, element): try: for propname,signalname in widgetType['slots'].items(): # iterate through slots of given widgetType if element.get(propname) is not None: # if the slot has been assigned for the element slotcode = element.get(propname) # default: assign to a model function match_object = re.match("(\w+)\((.*)\)", slotcode) if match_object: # if the slot passes extra data or is a utility function argscode = "" if utility_function_aliases.get(match_object.group(1),None) is not None: funcname = "util_funcs." + utility_function_aliases[match_object.group(1)] argscode = element.get("id") + ", " + match_object.group(2) else: funcname = match_object.group(1) argscode = match_object.group(2) slotcode = "lambda: " + funcname + "(" + argscode + ")" indent() if widgetType.get("isqt",False) is True: # if this is a qt widget Compiler.code += element.get("id") + "." + signalname + ".connect(" + slotcode + ")\n" # use the signal slot mechanism else: # otherwise this must be an oxide widget Compiler.code += element.get("id") + "." + signalname + " = " + slotcode + "\n" # so use the event handler system except KeyError: pass # just in case widgetType['slots'] doesn't exist
def parse_children(element): if element[0].tag.lower() in Layouts: # the children are arranged in a layout base_layout(element[0]) # initiate the layout parse_layout_children(element[0]) if element.tag.lower() == "window": # a window cannot have a layout set, so we need to add a central widget indent() Compiler.code += element.get('id') + "_CENTRALWIDGET = QWidget()\n" # just a basic QWidget will do indent() Compiler.code += element.get('id') + ".setCentralWidget(" + element.get('id') + "_CENTRALWIDGET)\n" indent() Compiler.code += element.get("id") + "_CENTRALWIDGET.setLayout(" + element[0].get("id") + ")\n" else: indent() Compiler.code += element.get("id") + ".setLayout(" + element[0].get("id") + ")\n" if element.tag.lower() == "splitter": for child in element: parse_abstract_element(child) Compiler.code += element.get("id") + ".addWidget(" + child.get('id') + ")\n"
def handleStyleProps(widgetType, element): for name,value in element.attrib.items(): if name in widgetType.get('style-properties',{}).values(): new_element = Element(name) # create an element to be passed to style.getValue() m = re.match("([\w-]+):(.+)",value) # extract the data from the property if m is None: # the property is not in the correct format raise BadFormatError(element.get('id') + " has incorrectly formatted '" + name + "' attribute") else: # prepare the element for style.getValue new_element.set(m.group(1), m.group(2)) value = str(getValue(new_element,runtime=False)) # get the value to set ##### Set the Value of Each State in the Widget's Styledict to the New Value ##### indent() # indent if neccesary Compiler.code += element.get("id") + ".styledict['normal']['" + name + "'] = " + value + "\n" for state in States: # for every state, plus the internal 'normal' state, add the appropriate code indent() # again, indent if neccesary Compiler.code += element.get("id") + ".styledict['" + state + "']['" + name + "'] = " + value + "\n" ##### Set the Current Value for the Widget to the New Value ##### indent() # once more, indent if neccesary Compiler.code += element.get('id') + "." + {v:k for k, v in widgetType.get('style-properties',{}).items()}[name] \ + " = " + value + "\n"