lisp_codegen.py
来自「用python写的ide开发环境,巨强大,不过需要wxpython的支持」· Python 代码 · 共 1,352 行 · 第 1/4 页
PY
1,352 行
global for_version try: for_version = tuple([int(t) for t in app_attrs['for_version'].split('.')[:2]]) except (KeyError, ValueError): if common.app_tree is not None: for_version = common.app_tree.app.for_version else: for_version = (2, 4) # default... try: _use_gettext = int(app_attrs['use_gettext']) except (KeyError, ValueError): _use_gettext = False try: _overwrite = int(app_attrs['overwrite']) except (KeyError, ValueError): _overwrite = False # add coding (PEP 263) try: _encoding = app_attrs['encoding'] except (KeyError, ValueError): _encoding = None classes = {} _current_extra_modules = {} header_lines = [';;; generated by wxGlade %s on %s%s\n\n' % \ (common.version, time.asctime(), common.generated_from()), '(asdf:operate \'asdf:load-op \'wxcl)\n', '(use-package \"FFI\")\n' '(ffi:default-foreign-language :stdc)\n\n' ] if not config.preferences.write_timestamp: header_lines[0] = ';;; generated by wxGlade %s%s\n\n' % \ (common.version, common.generated_from()) import_packages = set (["wxCL", "wxFrame", "wx_main", "wx_wrapper", "wxWindow", "wxColour", "wxEvtHandler", "wxEvent"])# add coding (PEP 263)# if _encoding:# header_lines.insert(0, "# -*- coding: %s -*-\n" % _encoding) multiple_files = multi_files if not multiple_files: global output_file, output_file_name if not _overwrite and os.path.isfile(out_path): # the file exists, we must keep all the lines not inside a wxGlade # block. NOTE: this may cause troubles if out_path is not a valid # lisp file, so be careful! previous_source = SourceFileContent(out_path) else: # if the file doesn't exist, create it and write the ``intro'' previous_source = None output_file = cStringIO.StringIO() output_file_name = out_path#-SKS for line in header_lines:#-SKS output_file.write(line) output_file.write('<%swxGlade extra_modules>\n' % nonce) output_file.write('\n') else: previous_source = None global out_dir if not os.path.isdir(out_path): raise XmlParsingError("'path' must be a directory when generating"\ " multiple output files") out_dir = out_pathdef finalize(): """\ Writer ``finalization'' function: flushes buffers, closes open files, ... """ if previous_source is not None: # insert all the new custom classes inside the old file tag = '<%swxGlade insert new_classes>' % nonce if previous_source.new_classes: code = "".join(previous_source.new_classes) else: code = "" previous_source.content = previous_source.content.replace(tag, code) tag = '<%swxGlade extra_modules>\n' % nonce code = "".join(_current_extra_modules.keys()) previous_source.content = previous_source.content.replace(tag, code) # now remove all the remaining <123415wxGlade ...> tags from the # source: this may happen if we're not generating multiple files, # and one of the container class names is changed tags = re.findall('(<%swxGlade replace ([a-zA-Z_]\w*) +\w+>)' % nonce, previous_source.content) for tag in tags: indent = previous_source.spaces.get(tag[1], tabs(2)) comment = '%s# content of this block not found: ' \ 'did you rename this class?\n%spass\n' % (indent, indent) previous_source.content = previous_source.content.replace(tag[0], comment) # ALB 2004-12-05 tags = re.findall('<%swxGlade event_handlers \w+>' % nonce, previous_source.content) for tag in tags: previous_source.content = previous_source.content.replace(tag, "") # write the new file contents to disk common.save_file(previous_source.name, previous_source.content, 'codegen') elif not multiple_files: global output_file em = "".join(_current_extra_modules.keys()) content = output_file.getvalue().replace( '<%swxGlade extra_modules>\n' % nonce, em) output_file.close() try: common.save_file(output_file_name, content, 'codegen') # make the file executable if _app_added: os.chmod(output_file_name, 0755) except IOError, e: raise XmlParsingError(str(e)) except OSError: pass # this isn't necessary a bad error del output_filedef test_attribute(obj): """\ Returns True if 'obj' should be added as an attribute of its parent's class, False if it should be created as a local variable of __do_layout. To do so, tests for the presence of the special property 'attribute' """ try: return int(obj.properties['attribute']) except (KeyError, ValueError): return True # this is the defaultdef add_object(top_obj, sub_obj): """\ adds the code to build 'sub_obj' to the class body of 'top_obj'. """ global import_packages try: klass = classes[top_obj.klass] except KeyError: klass = classes[top_obj.klass] = ClassLines() try: builder = obj_builders[sub_obj.base] except KeyError: # no code generator found: write a comment about it klass.init.extend(['\n', ';;; code for %s (type %s) not generated: ' 'no suitable writer found' % (sub_obj.name, sub_obj.klass),'\n']) else: try: sub_obj.name = sub_obj.name.replace('_','-') sub_obj.parent.name = sub_obj.parent.name.replace('_','-') if(sub_obj.name != "spacer"): class_lines.append(sub_obj.name) if (sub_obj.klass == "wxBoxSizer" or sub_obj.klass == "wxStaticBoxSizer" or sub_obj.klass == "wxGridSizer" or sub_obj.klass == "wxFlexGridSizer"): import_packages = import_packages | set(["wxSizer"]) else: if (sub_obj.klass != "spacer"): import_packages = import_packages | set([sub_obj.klass]) if (sub_obj.klass == "wxMenuBar" ): import_packages = import_packages | set(["wxMenu"]) init, props, layout = builder.get_code(sub_obj) except: print sub_obj raise # this shouldn't happen if sub_obj.in_windows: # the object is a wxWindow instance # --- patch 2002-08-26 ------------------------------------------ if sub_obj.is_container and not sub_obj.is_toplevel: init.reverse() klass.parents_init.extend(init) else: klass.init.extend(init) # --------------------------------------------------------------- # ALB 2004-12-05 mycn = getattr(builder, 'cn', cn) if hasattr(builder, 'get_events'): evts = builder.get_events(sub_obj) for id, event, handler in evts: klass.event_handlers.append((id, mycn(event), handler)) elif 'events' in sub_obj.properties: id_name, id = generate_code_id(sub_obj) #if id == '-1': id = 'self.%s.GetId()' % sub_obj.name if id == '-1': id = '#obj.%s' % sub_obj.name for event, handler in sub_obj.properties['events'].iteritems(): klass.event_handlers.append((id, mycn(event), handler)) else: # the object is a sizer # ALB 2004-09-17: workaround (hack) for static box sizers...# SKS- if sub_obj.base == 'wxStaticBoxSizer': #SKS- klass.parents_init.insert(1, init.pop(0)) klass.sizers_init.extend(init) klass.props.extend(props) klass.layout.extend(layout) if multiple_files and \ (sub_obj.is_toplevel and sub_obj.base != sub_obj.klass): key = 'from %s import %s\n' % (sub_obj.klass, sub_obj.klass) klass.dependencies[key] = 1## for dep in _widget_extra_modules.get(sub_obj.base, []): for dep in getattr(obj_builders.get(sub_obj.base), 'import_modules', []): klass.dependencies[dep] = 1def add_sizeritem(toplevel, sizer, obj, option, flag, border): """\ writes the code to add the object 'obj' to the sizer 'sizer' in the 'toplevel' object. """ # an ugly hack to allow the addition of spacers: if obj_name can be parsed # as a couple of integers, it is the size of the spacer to add global import_packages sizer.name = sizer.name.replace('_','-') obj_name = obj.name try: w, h = [ int(s) for s in obj_name.split(',') ] except ValueError: if obj.base == 'wxNotebook' and for_version < (2, 5): obj_name = cn('wxNotebookSizer') + '(%s)' % obj_name else: obj_name = '(%d, %d)' % (w, h) # it was the dimension of a spacer try: klass = classes[toplevel.klass] except KeyError: klass = classes[toplevel.klass] = ClassLines() flag = '%s' % cn_f(flag) flag = flag.strip().replace('|',' ') if flag.find(' ') != -1: flag = '(logior %s)' % flag if (obj.klass == "wxBoxSizer" or obj.klass == "wxStaticBoxSizer" or obj.klass == "wxGridSizer" or obj.klass == "wxFlexGridSizer"): buffer = '(wxSizer_AddSizer (slot-%s obj) (slot-%s obj) %s %s %s nil)\n' % \ (sizer.name, obj_name, option, flag, cn_f(border)) else: buffer = '(wxSizer_AddWindow (slot-%s obj) (slot-%s obj) %s %s %s nil)\n' % \ (sizer.name, obj_name, option, flag,cn_f(border)) print klass.layout.append(buffer)def add_class(code_obj): """\ Generates the code for a custom class. """ global _current_extra_modules, import_packages if not multiple_files: # in this case, previous_source is the SourceFileContent instance # that keeps info about the single file to generate prev_src = previous_source else: # let's see if the file to generate exists, and in this case # create a SourceFileContent instance filename = os.path.join(out_dir, code_obj.klass.replace('.', '_') + '.py') if _overwrite or not os.path.exists(filename): prev_src = None else: prev_src = SourceFileContent(filename) _current_extra_modules = {} if classes.has_key(code_obj.klass) and classes[code_obj.klass].done: return # the code has already been generated try:#SKS- builder = obj_builders[code_obj.base] builder="" mycn = getattr(builder, 'cn', cn) mycn_f = getattr(builder, 'cn_f', cn_f) except KeyError: raise # this is an error, let the exception be raised if prev_src is not None and prev_src.classes.has_key(code_obj.klass): is_new = False indentation = prev_src.spaces[code_obj.klass] else: # this class wasn't in the previous version of the source (if any) is_new = True indentation = tabs(2)## mods = _widget_extra_modules.get(code_obj.base) mods = getattr(builder, 'extra_modules', []) if mods: for m in mods: _current_extra_modules[m] = 1 buffer = [] write = buffer.append for l in header_lines: write(l) for l in import_packages: write('(use-package :%s)\n' % l) if not classes.has_key(code_obj.klass): # if the class body was empty, create an empty ClassLines classes[code_obj.klass] = ClassLines()## # first thing to do, call the property writer: we do this now because it## # can have side effects that modify the ClassLines instance (this is used## # in the toplevel menubar)## props_builder = obj_properties.get(code_obj.base)## write_body = len(classes[code_obj.klass].props)## if props_builder:## obj_p = obj_properties[code_obj.base](code_obj)## if not write_body: write_body = len(obj_p)## else: obj_p = [] tab = indentation if is_new: base = mycn(code_obj.base) if code_obj.preview and code_obj.klass == base: import random klass = code_obj.klass + ('_%d' % random.randrange(10**8, 10**9)) else: klass = code_obj.klass write('\n(defclass %s()\n' % klass) write("\t((top-window :initform nil :accessor slot-top-window)") for l in class_lines: write("\n"+tab+"("+l+" :initform nil :accessor slot-"+l+")") write("))\n") write("\n(defun make-%s ()\n" % klass) write(tab+"(let ((obj (make-instance '%s)))\n" % klass) write(tab+" (init obj)\n") write(tab+" (set-properties obj)\n") write(tab+" (do-layout obj)\n") write(tab+" obj))\n") write('\n(defmethod init ((obj %s))\n' % klass) write("\"Method creates the objects contained in the class.\"\n") # __init__ begin tag write(indentation + ';;;begin wxGlade: %s.__init__\n' % code_obj.klass) prop = code_obj.properties style = prop.get("style", None) if style: style = mycn_f(style) style = style.strip().replace('.','') style = style.replace('|',' ') if style.find(' ') != -1: style = '(logior %s)' % style if code_obj.base == "wxFrame": write(indentation + "(setf (slot-top-window obj) (wxFrame_create nil -1 \"\" -1 -1 -1 -1 %s))\n" % style) else: if code_obj.base == "wxDialog": write(indentation + "(setf (slot-top-window obj) (wxDialog_create nil -1 \"\" -1 -1 -1 -1 %s))\n" % style) import_packages = import_packages | set(['wxDialog'])
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?