Gnome backgrounds, scanner app for VIP Express (circa Jun 2004)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 

442 lines
13 KiB

#!/usr/bin/env python
# simple-glade-codegen.py
# A code generator that uses pygtk, glade and SimpleGladeApp.py
# Copyright (C) 2004 Sandino Flores Moreno
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
import sys, os, re, codecs
import tokenize, shutil, time
import xml.sax
from xml.sax._exceptions import SAXParseException
header_format = """\
#!/usr/bin/env python
# -*- coding: UTF8 -*-
# Python module %(module)s.py
# Autogenerated from %(glade)s
# Generated on %(date)s
# Warning: Do not delete or modify comments related to context
# They are required to keep user's code
import os, gtk
from SimpleGladeApp import SimpleGladeApp
glade_dir = ""
# Put your modules and data here
# From here through main() codegen inserts/updates a class for
# every top-level widget in the .glade file.
"""
class_format = """\
class %(class)s(SimpleGladeApp):
%(t)sdef __init__(self, glade_path="%(glade)s", root="%(root)s", domain=None):
%(t)s%(t)sglade_path = os.path.join(glade_dir, glade_path)
%(t)s%(t)sSimpleGladeApp.__init__(self, glade_path, root, domain)
%(t)sdef new(self):
%(t)s%(t)s#context %(class)s.new {
%(t)s%(t)sprint "A new %(class)s has been created"
%(t)s%(t)s#context %(class)s.new }
%(t)s#context %(class)s custom methods {
%(t)s#--- Write your own methods here ---#
%(t)s#context %(class)s custom methods }
"""
callback_format = """\
%(t)sdef %(handler)s(self, widget, *args):
%(t)s%(t)s#context %(class)s.%(handler)s {
%(t)s%(t)sprint "%(handler)s called with self.%%s" %% widget.get_name()
%(t)s%(t)s#context %(class)s.%(handler)s }
"""
creation_format = """\
%(t)sdef %(handler)s(self, str1, str2, int1, int2):
%(t)s%(t)s#context %(class)s.%(handler)s {
%(t)s%(t)swidget = gtk.Label("%(handler)s")
%(t)s%(t)swidget.show_all()
%(t)s%(t)sreturn widget
%(t)s%(t)s#context %(class)s.%(handler)s }
"""
main_format = """\
def main():
"""
instance_format = """\
%(t)s%(root)s = %(class)s()
"""
run_format = """\
%(t)s%(root)s.run()
if __name__ == "__main__":
%(t)smain()
"""
class NotGladeDocumentException(SAXParseException):
def __init__(self, glade_writer):
strerror = "Not a glade-2 document"
SAXParseException.__init__(self, strerror, None, glade_writer.sax_parser)
class SimpleGladeCodeWriter(xml.sax.handler.ContentHandler):
def __init__(self, glade_file):
self.indent = "\t"
self.code = ""
self.roots_list = []
self.widgets_stack = []
self.creation_functions = []
self.callbacks = []
self.parent_is_creation_function = False
self.glade_file = glade_file
self.data = {}
self.input_dir, self.input_file = os.path.split(glade_file)
base = os.path.splitext(self.input_file)[0]
module = self.normalize_symbol(base)
self.output_file = os.path.join(self.input_dir, module) + ".py"
self.sax_parser = xml.sax.make_parser()
self.sax_parser.setFeature(xml.sax.handler.feature_external_ges, False)
self.sax_parser.setContentHandler(self)
self.data["glade"] = self.input_file
self.data["module"] = module
self.data["date"] = time.asctime()
def normalize_symbol(self, base):
return "_".join( re.findall(tokenize.Name, base) )
def capitalize_symbol(self, base):
ClassName = "[a-zA-Z0-9]+"
base = self.normalize_symbol(base)
capitalize_map = lambda s : s[0].upper() + s[1:]
return "".join( map(capitalize_map, re.findall(ClassName, base)) )
def uncapitalize_symbol(self, base):
InstanceName = "([a-z])([A-Z])"
action = lambda m: "%s_%s" % ( m.groups()[0], m.groups()[1].lower() )
base = self.normalize_symbol(base)
base = base[0].lower() + base[1:]
return re.sub(InstanceName, action, base)
def startElement(self, name, attrs):
if name == "widget":
widget_id = attrs.get("id")
widget_class = attrs.get("class")
if not widget_id or not widget_class:
raise NotGladeDocumentException(self)
if not self.widgets_stack:
self.creation_functions = []
self.callbacks = []
class_name = self.capitalize_symbol(widget_id)
self.data["class"] = class_name
self.data["root"] = widget_id
self.roots_list.append(widget_id)
self.code += class_format % self.data
self.widgets_stack.append(widget_id)
elif name == "signal":
if not self.widgets_stack:
raise NotGladeDocumentException(self)
widget = self.widgets_stack[-1]
signal_object = attrs.get("object")
if signal_object:
return
handler = attrs.get("handler")
if not handler:
raise NotGladeDocumentException(self)
if handler.startswith("gtk_"):
return
signal = attrs.get("name")
if not signal:
raise NotGladeDocumentException(self)
self.data["widget"] = widget
self.data["signal"] = signal
self.data["handler"]= handler
if handler not in self.callbacks:
self.code += callback_format % self.data
self.callbacks.append(handler)
elif name == "property":
if not self.widgets_stack:
raise NotGladeDocumentException(self)
widget = self.widgets_stack[-1]
prop_name = attrs.get("name")
if not prop_name:
raise NotGladeDocumentException(self)
if prop_name == "creation_function":
self.parent_is_creation_function = True
def characters(self, content):
if self.parent_is_creation_function:
if not self.widgets_stack:
raise NotGladeDocumentException(self)
handler = content.strip()
if handler not in self.creation_functions:
self.data["handler"] = handler
self.code += creation_format % self.data
self.creation_functions.append(handler)
def endElement(self, name):
if name == "property":
self.parent_is_creation_function = False
elif name == "widget":
if not self.widgets_stack:
raise NotGladeDocumentException(self)
self.widgets_stack.pop()
def write(self):
self.data["t"] = self.indent
self.code += header_format % self.data
try:
glade = open(self.glade_file, "r")
self.sax_parser.parse(glade)
except xml.sax._exceptions.SAXParseException, e:
sys.stderr.write("Error parsing document\n")
return None
except IOError, e:
sys.stderr.write("%s\n" % e.strerror)
return None
self.code += main_format % self.data
for root in self.roots_list:
self.data["class"] = self.capitalize_symbol(root)
self.data["root"] = self.uncapitalize_symbol(root)
self.code += instance_format % self.data
self.data["root"] = self.uncapitalize_symbol(self.roots_list[0])
self.code += run_format % self.data
try:
self.output = codecs.open(self.output_file, "w", "utf-8")
self.output.write(self.code)
self.output.close()
except IOError, e:
sys.stderr.write("%s\n" % e.strerror)
return None
return self.output_file
def usage():
program = sys.argv[0]
print """\
Write a simple python file from a glade file.
Usage: %s <file.glade>
""" % program
def which(program):
if sys.platform.startswith("win"):
exe_ext = ".exe"
else:
exe_ext = ""
path_list = os.environ["PATH"].split(os.pathsep)
for path in path_list:
program_path = os.path.join(path, program) + exe_ext
if os.path.isfile(program_path):
return program_path
return None
def check_for_programs():
packages = {"diff" : "diffutils", "patch" : "patch"}
for package in packages.keys():
if not which(package):
sys.stderr.write("Required program %s could not be found\n" % package)
sys.stderr.write("Is the package %s installed?\n" % packages[package])
if sys.platform.startswith("win"):
sys.stderr.write("Download it from http://gnuwin32.sourceforge.net/packages.html\n")
sys.stderr.write("Also, be sure it is in the PATH\n")
return False
return True
def main():
if not check_for_programs():
return -1
if len(sys.argv) == 2:
code_writer = SimpleGladeCodeWriter( sys.argv[1] )
glade_file = code_writer.glade_file
output_file = code_writer.output_file
output_file_orig = output_file + ".orig"
output_file_bak = output_file + ".bak"
short_f = os.path.split(output_file)[1]
short_f_orig = short_f + ".orig"
short_f_bak = short_f + ".bak"
helper_module = os.path.join(code_writer.input_dir,SimpleGladeApp_py)
custom_diff = "custom.diff"
exists_output_file = os.path.exists(output_file)
exists_output_file_orig = os.path.exists(output_file_orig)
if not exists_output_file_orig and exists_output_file:
sys.stderr.write('File "%s" exists\n' % short_f)
sys.stderr.write('but "%s" does not.\n' % short_f_orig)
sys.stderr.write("That means your custom code would be overwritten.\n")
sys.stderr.write('Please manually remove "%s"\n' % short_f)
sys.stderr.write("from this directory.\n")
sys.stderr.write("Anyway, I\'ll create a backup for you in\n")
sys.stderr.write('"%s"\n' % short_f_bak)
shutil.copy(output_file, output_file_bak)
return -1
if exists_output_file_orig and exists_output_file:
os.system("diff -U1 %s %s > %s" % (output_file_orig, output_file, custom_diff) )
if not code_writer.write():
os.remove(custom_diff)
return -1
shutil.copy(output_file, output_file_orig)
if os.system("patch -fp0 < %s" % custom_diff):
os.remove(custom_diff)
return -1
os.remove(custom_diff)
else:
if not code_writer.write():
return -1
shutil.copy(output_file, output_file_orig)
os.chmod(output_file, 0755)
if not os.path.isfile(helper_module):
open(helper_module, "w").write(SimpleGladeApp_content)
print "Wrote", output_file
return 0
else:
usage()
return -1
SimpleGladeApp_py = "SimpleGladeApp.py"
SimpleGladeApp_content = """\
# SimpleGladeApp.py
# Module that provides an object oriented abstraction to pygtk and libglade.
# Copyright (C) 2004 Sandino Flores Moreno
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
try:
import os
import sys
import gtk
import gtk.glade
except ImportError:
print "Error importing pygtk2 and pygtk2-libglade"
sys.exit(1)
class SimpleGladeApp(dict):
def __init__(self, glade_filename, main_widget_name=None, domain=None):
gtk.glade.set_custom_handler(self.custom_handler)
if os.path.isfile(glade_filename):
self.glade_path = glade_filename
else:
glade_dir = os.path.split( sys.argv[0] )[0]
self.glade_path = os.path.join(glade_dir, glade_filename)
self.glade = gtk.glade.XML(self.glade_path, main_widget_name, domain)
if main_widget_name:
self.main_widget = self.glade.get_widget(main_widget_name)
else:
self.main_widget = None
self.signal_autoconnect()
self.new()
def signal_autoconnect(self):
signals = {}
for attr_name in dir(self):
attr = getattr(self, attr_name)
if callable(attr):
signals[attr_name] = attr
self.glade.signal_autoconnect(signals)
def custom_handler(self,
glade, function_name, widget_name,
str1, str2, int1, int2):
if hasattr(self, function_name):
handler = getattr(self, function_name)
return handler(str1, str2, int1, int2)
def __getattr__(self, data_name):
if data_name in self:
data = self[data_name]
return data
else:
widget = self.glade.get_widget(data_name)
if widget != None:
self[data_name] = widget
return widget
else:
raise AttributeError, data_name
def __setattr__(self, name, value):
self[name] = value
def new(self):
pass
def on_keyboard_interrupt(self):
pass
def gtk_widget_show(self, widget, *args):
widget.show()
def gtk_widget_hide(self, widget, *args):
widget.hide()
def gtk_widget_grab_focus(self, widget, *args):
widget.grab_focus()
def gtk_widget_destroy(self, widget, *args):
widget.destroy()
def gtk_window_activate_default(self, widget, *args):
widget.activate_default()
def gtk_true(self, *args):
return gtk.TRUE
def gtk_false(self, *args):
return gtk.FALSE
def gtk_main_quit(self, *args):
gtk.main_quit()
def main(self):
gtk.main()
def quit(self):
gtk.main_quit()
def run(self):
try:
self.main()
except KeyboardInterrupt:
self.on_keyboard_interrupt()
"""
if __name__ == "__main__":
exit_code = main()
sys.exit(exit_code)