#!/usr/bin/python # Guikachu Copyright (C) 2001-2003 ÉRDI Gergõ # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # This script creates a bunch of skeleton C files from a Guikachu # document. # # TODO: # * Support for other widget types import libxml2 import sys guikachu_filename = sys.argv[1] proj_name = guikachu_filename # FIXME: Strip .guikachu or something forms = [] menus = {} class Writer: def __init__ (self, filename): print "Creating '%s'" % filename self.fd = open (filename, "w") def __del__ (self): self.fd.close () def write (self, content): self.fd.writelines (content) class Form: def __init__ (self, node): self.id = node.prop ("id") self.menu = None self.widgets = [] self.parse (node) def parse (self, node): curr_node = node.children while curr_node: if curr_node.name == "menu": self.menu = curr_node.prop ("id") if curr_node.name == "widgets": self.parse_widgets (curr_node) curr_node = curr_node.next def parse_widgets (self, node): widget_node = node.children while widget_node: widget = Widget (widget_node) if widget: self.widgets.append (widget) widget_node = widget_node.next def write_code (self): impl = Writer ("form_%s.c" % self.id) header = Writer ("form_%s.h" % self.id) self.write_impl (impl) self.write_header (header) def write_header (self, writer): writer.write ('#include \n' '#include \n\n') writer.write ('Boolean form_%s_handler (EventPtr event);\n\n' % self.id) for widget in self.widgets: for event in widget.events: writer.write ("Boolean widget_%s_%s_cb ();\n" % (widget.id, event.name)) def write_impl (self, writer): writer.write ('#include "form_%s.h"\n' % self.id) if self.menu: writer.write ('#include "menu_%s.h"\n' % self.menu) writer.write ('#include "%s.h"\n\n' % proj_name) self.write_event_handler (writer) def write_event_handler (self, writer): writer.write ("Boolean form_%s_handler (EventPtr event)" % self.id) writer.write (""" { Boolean handled = false; switch (event->eType) { case frmOpenEvent: FrmDrawForm (FrmGetActiveForm ()); handled = true; break;\n""") if self.menu: writer.write (""" case menuEvent: handled = menu_%s_handler (event); break;\n""" % self.menu) for event in self.widget_events (): self.write_widget_event_handler (writer, event) writer.write ( """ } return handled; } """) def widget_events (self): events = [] for widget in self.widgets: for event in widget.events: if not event in events: events.append (event) return events def write_widget_event_handler (self, writer, event): writer.write ( """ case %sEvent: switch (event->data.%s) {""" % (event.name, event.widget_field)) for widget in self.widgets: if event in widget.events: writer.write ( """ case %s: handled = widget_%s_%s_cb (); break; """ % (widget.id, widget.id, event.name)) writer.write ( """ }\n""") def Widget (node): if node.name in TriggerControl.widgets: return TriggerControl (node) if node.name in Control.widgets: return Control (node) return None class Event: def __init__ (self, name): self.name = name def __eq__ (self, other): return self.name == other.name class ControlEvent (Event): def __init__ (self, name): Event.__init__ (self, name) self.widget_field = name + ".controlID" class Control: widgets = [ "button", "pushbutton", "checkbox" ] events = [ ControlEvent ("ctlEnter") ] def __init__ (self, node): self.id = node.prop ("id") class TriggerControl (Control): widgets = [ "popup_trigger", "selector_trigger" ] events = [ ControlEvent ("ctlEnter"), ControlEvent ("ctlSelect") ] def __init__ (self, node): Control.__init__ (self, node) class Menu: def __init__ (self, node): self.menuitems = [] self.id = node.prop ("id") self.read_menu (node) def write_code (self): impl = Writer ("menu_%s.c" % self.id) header = Writer ("menu_%s.h" % self.id) self.write_impl (impl) self.write_header (header) def write_header (self, writer): writer.write ('#include \n' '#include \n\n') writer.write ("#ifndef menu_%s_H\n" % self.id) writer.write ("#define menu_%s_H\n\n" % self.id) writer.write ("Boolean menu_%s_handler (EventPtr event);\n\n" % self.id) for i in self.menuitems: writer.write ("Boolean %s ();\n" % self.item_stub_name (i)) writer.write ("\n#endif /* menu_%s_H */\n" % self.id) def write_impl (self, writer): writer.write ('#include "menu_%s.h"\n' % self.id) writer.write ('#include "%s.h"\n\n' % proj_name) self.write_event_handler (writer) def write_event_handler (self, writer): writer.write ("Boolean menu_%s_handler (EventPtr event)" % self.id) writer.write ( """ { Boolean handled = false; switch (event->data.menu.itemID) {""") for i in self.menuitems: writer.write ( """ case %s: handled = %s (); break; """ % (i, self.item_stub_name (i))) writer.write ( """ } return handled; } """) def item_stub_name (self, item): return "%s_%s_activate_cb" % (self.id, item) def read_menu (self, node): submenu_node = node.children while submenu_node: if submenu_node.name == "submenu": self.read_submenu (submenu_node) submenu_node = submenu_node.next def read_submenu (self, node): item_node = node.children while item_node: if item_node.name == "menuitem": self.read_menuitem (item_node) item_node = item_node.next def read_menuitem (self, node): self.menuitems.append (node.prop ("id")) def do_resource (node): if node.type != "element": return if node.name == "menu": menu = Menu (node) menus[menu.id] = menu if node.name == "form": form = Form (node) forms.append (form) def do_resources (root_node): res_node = root_node.children while res_node: do_resource (res_node) res_node = res_node.next parser = libxml2.parseFile doc = parser (guikachu_filename) do_resources (doc.getRootElement ()) doc.freeDoc () for form in forms: form.write_code () for menu in menus.values (): menu.write_code ()