def parse_interface(interfacename): tree = xmlparse("views" + QDir.separator() + interfacename + ".xml").getroot() # get the tree Compiler.current_interfacename = interfacename # set the current interfacename imported = [] # this is the list of interfaces to parse after this one Compiler.code += "from PySide.QtGui import *\nfrom PySide.QtCore import *\n" # import PySide Compiler.code += "from oxide.widgets.all import *\n" # import Oxide if interfacename == Compiler.start: # if this is the start interface, create a QApplication Compiler.code += "import sys\n" # using sys.argv, Compiler.code += "app = OxideApplication(sys.argv)\n" # create a QApplication add_util_funcs() # add the utility functions add_model(interfacename,"__main__") # now add the model code to the output file for element in tree: # iterate through the elements in the tree if element.tag.lower() == "animations": # here we handle the special 'animations' tag Compiler.to_be_own_class = False # there is no way that we're in the resources tag here for animation in element: # go through each animation parse_animation(animation) # and parse it elif element.tag.lower() == "window": # here we handle the window Compiler.to_be_own_class = False # there is no way that we're in the resources tag here parse_toplevel(element) # using parse_window elif element.tag.lower() == "resources": Compiler.to_be_own_class = True for child in element: Compiler.direct_resources_child = True parse_abstract_element(child) Compiler.direct_resources_child = False Compiler.direct_resources_child = False elif element.tag.lower() == "import": Compiler.code += "import " + element.get('interface') + "\n" imported.append(element.get('interface')) if interfacename == Compiler.start: # to finish up, if this is the start file Compiler.code += "sys.exit(app.exec_())\n" # run the application # now it has come time to put the code on the filesystem if not QDir("bin").exists(): # if the 'bin' folder doesn't exist QDir().mkdir("bin") # create it interfacefile = open(Compiler.gendir + QDir.separator() + interfacename + ".py", 'w') interfacefile.write(Compiler.code) # write Compiler.code to the file Compiler.code = "" # reset Compiler.code for interface in imported: parse_interface(interface)
def processModels(): for filename in QDir("models").entryList(QDir.Files): out = "" for line in open("models" + QDir.separator() + filename).readlines(): try: if not line.strip()[0] == "#": if line[:8] == "from " + app.manifest.get('gendir',"bin"): out += "# " + line; else: out += line else: out += line except IndexError: # it must have just been a newline (lstrip makes it ""), so there is no index 0 out += "\n" f = open("models" + QDir.separator() + filename, 'w') f.write(out) f.close()
def getConfigStyleDict(): styledict = {} #initialize the new styledict # get the tree from the style.xml file tree = xmlparse("config" + QDir.separator() + "style.xml").getroot() for styletype in tree: # iterate over the types of widget styletype_key = styletype.tag.lower() if styletype.tag.lower().startswith("default-") else styletype.tag styledict[styletype_key] = {} # create a new dictionary for the style-type for state in States: styledict[styletype_key][state] = {} styledict[styletype_key]['normal'] = {} styledict[styletype_key]['durations'] = {} for styledef_or_statedef in styletype: if styledef_or_statedef.tag.lower() in States: for styledef in styledef_or_statedef: styledict[styletype_key][styledef_or_statedef.tag.lower()][styledef.tag.lower()] = getValue(styledef) elif styledef_or_statedef.tag.lower() in StateTransitions: if styledef_or_statedef.get('time') is None: raise StyleError(styletype.tag + " => " + styledef_or_statedef.tag + " must have 'time' attribute") styledict[styletype_key]['durations'][styledef_or_statedef.tag.lower()] = int(styledef_or_statedef.get('time')) else: for state in States: styledict[styletype_key][state][styledef_or_statedef.tag.lower()] = getValue(styledef_or_statedef) styledict[styletype_key]['normal'][styledef_or_statedef.tag.lower()] = getValue(styledef_or_statedef) return styledict
def addImages(self, directory, images): self.directory = directory json_file_name = self.directory.path() + QDir.separator() + 'box2d.json' if os.path.exists(json_file_name): try: with open(json_file_name) as f: self.images = [Image(self.directory, json_dict=js_image) for js_image in json.load(f)] except ValueError, e: self.images = [Image(self.directory, file_name=image) for image in images]
def __init__(self, directory, filename): self.directory = directory self.filename = filename image = QImage(self.directory + QDir.separator() + self.filename) Rect.__init__(self, Point(), Size(image.width(), image.height())) cropped_image, x, y, width, height = self.__getCrop(image, False) self.crop = Rect(Point(x, y), Size(width, height)) self.rotated = False
def old_add_model(interfacename,scope): try: f = open("models" + QDir.separator() + interfacename + Compiler.model_extension) # try to open the model file except IOError: # there must not be a model for this interface name print "Warning: interface '" + interfacename + "' is missing a model" return for line in f.readlines(): # the if statement prevents generated files from importing each other when we don't want them to if not line.startswith("from " + Compiler.gendir + "."): Compiler.code += line # add the code, under the above condition Compiler.code += "\n" #in case there's not newline at the end of the file
def rewrite_model(interfacename): try: in_file = open("models" + QDir.separator() + interfacename + Compiler.model_extension) # try to open the model file except IOError: # there must not be a model for this interface name print "Warning: interface '" + interfacename + "' is missing a model" return outcode = "from PySide.QtGui import *\nfrom PySide.QtCore import *\nfrom oxide.widgets.all import *\nfrom oxide.widgets import util_funcs\nimport sys\n" # now we won't get errors on import of the rewritten model for line in in_file.readlines(): # the if statement prevents generated files from importing each other when we don't want them to if not line.startswith("from " + Compiler.gendir + "."): # if the line does not import from the gendir match_object = re.match("class (\w+)" + Compiler.modelclass_extension + "\(\w+\):", line) if match_object: line = "class " + match_object.group(1) + Compiler.modelclass_extension + "():\n" outcode += line # add the code, under the above condition sep = QDir.separator() try: out_file = open(Compiler.gendir + sep + "tmp" + sep + "models" + sep + interfacename + Compiler.model_extension,'w') # create the new file except IOError: # could not create the new file print "Could not create file in gendir" sys.exit() out_file.write(outcode)
def addImages(self, directory, images): self.directory = directory json_file_name = self.directory.path() + QDir.separator( ) + 'box2d.json' if os.path.exists(json_file_name): try: with open(json_file_name) as f: self.images = [ Image(self.directory, json_dict=js_image) for js_image in json.load(f) ] except ValueError, e: self.images = [ Image(self.directory, file_name=image) for image in images ]
def run(self): if not self.directory or not len(self.images): return self.prepare_progress_signal.emit(0) self.packing_progress_signal.emit(0) self.verify_progress_signal.emit(0) self.saving_progress_signal.emit(0) images = [] for i, image in enumerate(self.images): self.prepare_progress_signal.emit(int(100 * (i + 1) / float(len(self.images)))) images.append(Image(self.directory, image)) bin_packing = self.method["type"](self.bin_size, images, bin_parameters=self.bin_parameter[self.method["name"]]) bin_packing.saveAtlases(self.directory + QDir.separator()) self.update_bins.emit(bin_packing.bins) self.on_end.emit(True)
def print_error(type,error,tb): # @ReservedAssignment # re-implementation of sys.excepthook tb = traceback.extract_tb(tb) if os.path.exists("models" + QDir.separator() + os.path.basename(tb[-1][0])): sys.stderr.write("Error in model " + ".".join(os.path.basename(tb[-1][0]).split(".")[:-1]) + ", line " + str(tb[-1][1]) + " in " + str(tb[-1][2]) + ":\n" + " " + tb[-1][3] + "\n") elif issubclass(error.__class__,InterfaceError): sys.stderr.write("Error in view " + error.interface + ".xml:\n") sys.stderr.write(str(type)[:-2].split(".")[-1] + ": ") if not isinstance(error, IOError) and not isinstance(error, OSError): for arg in error.args: sys.stderr.write(arg) else: sys.stderr.write(error.strerror) sys.exit()
def add_model(interfacename, scope): code = "" rewrite_model(interfacename) # get the rewritten model and load it up model = __import__("bin.tmp.models." + interfacename) exec "model = model.tmp.models." + interfacename sep = QDir.separator() tmp_model_dir = Compiler.gendir + sep + "tmp" + sep + "models" + sep + interfacename + Compiler.model_extension for cls in inspect.getmembers(model, inspect.isclass): try: # a TypeError can occur if objects are builtins # make sure the class we are inspecting was not imported, we only want classes defined in this file if inspect.getfile(cls[1]) == os.path.abspath(tmp_model_dir): # if the main model should be selected if scope == "__main__": # this covers the scoping issue, any classes not ending with "_model" can be used for this scope if cls[0].endswith("_model"): continue # for all lines except the definition line for line in inspect.getsource(cls[1]).split("\n"): #[1:]: # make sure that classmethod and staticmethod decorators are ignored # if not line.lstrip().startswith("@classmethod") and not line.lstrip().startswith("@staticmethod"): code += line + "\n" # add the line, but minus one indent # code += line.replace(Compiler.model_indent,"",1) + "\n" else: # this covers the scoping issue, any class named Scope_model will be used if scope + Compiler.modelclass_extension != cls[0]: continue # add the members of this class to the output code, all but the line for the definition code += "\n".join( inspect.getsource(cls[1]).split("\n")[1:] ) except TypeError: pass Compiler.code += code
def compile(interfacename, dist=False): # @ReservedAssignment code = "" mainWindowId = None code += "from PySide.QtGui import *\nfrom PySide.QtCore import *\nimport sys\n" if interfacename == app.manifest['start']: code += "app = QApplication(sys.argv)\n" a = captan.style.parseStyle() code += "app.setStyleSheet('''" + a + "''')\n" print a # only create a QApplication if it is the main file for filename in [ f for f in os.listdir("views") if os.path.isfile(os.path.join("views",f)) ]: if not filename == interfacename + ".xml" and interfacename == app.manifest['start']: code += "import " if not dist: code += "bin." code += ".".join(filename.split(".")[:-1]) + " as " + ".".join(filename.split(".")[:-1]) + "\n" code += getFuncs(interfacename) if interfacename == app.manifest['start']: try: # call the end function if it exists exec "models." + interfacename + ".init" code += "init(sys.argv)\n" except: pass # init should only be called for the main file tree = xmlparse("views" + QDir.separator() + interfacename + '.xml') tree = tree.getroot() # get the tree for element in tree: # parse the top-level tags if element.tag.lower() == "window": # the MainWindow if element.get("id") is None: captan.children.addDefaultId(element) mainWindowId = element.get("id") code += parseWindow(element, tree, mainWindowId, interfacename) # delegate the task to captan.main.parseWindow elif element.tag.lower() == "buffer": code += parseBuffer(element,interfacename) if mainWindowId is not None: # show the MainWindow, if there is one code += mainWindowId + ".show()\n" if interfacename == app.manifest['start']: # execute the app if it is the main view code += "APP_RESULT = app.exec_()\n" # execute the application and get the result try: # call the end function if it exists exec "models." + interfacename + ".end" code += "end(APP_RESULT)\n" except: pass code += "sys.exit(APP_RESULT)\n" f = open(getProjectFile(interfacename + ".py"),'w') f.write(code)
def loadImage(self): self.image = QImage(self.directory.path() + QDir.separator() + self.file_name)
def save(self): with open(self.directory.path() + QDir.separator() + 'box2d.json', 'w') as js: figures_ = [image.getDict() for image in self.images] json.dump(obj=figures_, fp=js, separators=(',', ':'), indent=4)
def __fileNameWoExt(self): image = QFileInfo(self.directory + QDir.separator() + self.filename) return image.absoluteDir().absolutePath() + QDir.separator() + image.baseName()
def compile(): # @ReservedAssignment open("id.num.txt","w").write("0") # initialize the id.num.txt file, see 'oxide.parsing.util.defaultId' parse_interface(Compiler.start) # now we parse the starting interface of the oxide app copy_tree("config",Compiler.gendir + QDir.separator() + "config") # copy data/settings into output folder copy_tree("resources",Compiler.gendir + QDir.separator() + "resources") # copy resources into output folder