Convert other enums to int for Python 2.5 (Stephen Watson).
[rox-lib/lack.git] / python / rox / templates.py
blob5c05c823efe0d899a71f46ba4b57b97683230097
1 """Support for loading glade files from your application directory.
3 The simplest interface will be templates.load() which will return a set
4 of widgets loaded from $APP_DIR/Templates.glade, e.g.
5 class MyWindow:
6 def __init__(self):
7 widgets=templates.load()
8 self.window=widgets.getWindow('main')
9 self.entry=widgets['text_entry']
10 widgets.autoConnect(self)
11 self.window.show_all()
13 If you wish to re-use a window then you should use the Templates class:
14 widgets=templates.Templates()
15 windows=[]
16 for i in range(10):
17 set=widgets.getWidgetSet('main')
18 # ... connect signal handlers
19 window=set.getWindow('main')
20 windows.append(window)
21 """
23 import os, sys
24 import errno
26 import rox
27 import gtk.glade as glade
29 def _get_templates_file_name(fname):
30 if not fname:
31 fname='Templates.glade'
32 if not os.path.isabs(fname):
33 fname=os.path.join(rox.app_dir, fname)
34 return fname
36 def _wrap_window(win):
37 if not win.get_data('rox_toplevel_ref'):
38 rox.toplevel_ref()
39 win.connect('destroy', rox.toplevel_unref)
40 win.set_data('rox_toplevel_ref', True)
41 return win
43 class Templates:
44 """Class holding a loaded glade file."""
46 def __init__(self, name=None):
47 """Load the glade file. If name is an absolute path name then load
48 it, if a relative path name load that from the appdir or if None
49 the load $APP_DIR/Templates.glade."""
50 fname=_get_templates_file_name(name)
52 self.xml=file(fname, 'r').read()
53 self.connect_to=None
54 self.signals={}
56 def autoConnect(self, dict_or_instance):
57 """Specify what to use to connect the signals when an instance of the
58 widgets is created. dict_or_instance is either a dictionary where the
59 signal handlers are indexed by the name of the handler in the glade
60 file, or an instance of a class where the methods have the same
61 names as given in the glade file."""
63 self.connect_to=dict_or_instance
65 def connect(self, handler_name, func):
66 """Manually specify the handler function for a signal. These are
67 not set until getWidgetSet is called."""
69 self.signals[handler_name]=func
71 def getWidgetSet(self, root=''):
72 """Return a WidgetSet instance containing the widgets defined by
73 the glade file. If root is given it is the top level widget to return.
74 The signal handlers specified in connect() or autoConnect() are
75 connected at this point.
76 """
78 widgets=WidgetSet(self.xml, root)
79 if self.connect_to:
80 widgets.autoConnect(self.connect_to)
81 for name in self.signals:
82 widgets.connect(name, self.signals[name])
83 return widgets
85 class WidgetSet:
86 """A set of widget instances created from a glade file."""
88 def __init__(self, xml, root=''):
89 """A set of widget instances created from the glade file.
90 xml - the contents of the glade file.
91 root - top level widget to create (and all is contained widgets), or
92 '' to create all.
93 """
95 self.widgets=glade.xml_new_from_buffer(xml, len(xml), root)
97 def autoConnect(self, dict_or_instance):
98 """Specify what to use to connect the signals.
99 dict_or_instance is either a dictionary where the
100 signal handlers are indexed by the name of the handler in the glade
101 file, or an instance of a class where the methods have the same
102 names as given in the glade file."""
104 self.widgets.signal_autoconnect(dict_or_instance)
106 def connect(self, name, func):
107 """Manually specify the handler function for a signal."""
109 self.widgets.signal_connect(name, func)
111 def getWidget(self, name):
112 """Return the named widget."""
113 return self.widgets.get_widget(name)
115 def getWindow(self, name):
116 """Return the named widget, which should be a gtk.Window. The
117 window is tracked by the window counting system, see
118 rox.toplevel_ref()."""
119 return _wrap_window(self.getWidget(name))
121 def __getitem__(self, key):
122 """Return the named widget."""
124 widget=self.widgets.get_widget(key)
125 if not widget:
126 raise KeyError, key
127 return widget
129 def load(fname=None, root='', dict_or_instance=None):
130 """Load the templates file and return the set of widgets.
131 fname - path to templates file: If it is an absolute path name then load
132 it, if a relative path name load that from the appdir or if None
133 the load $APP_DIR/Templates.glade.
134 root - name of top level widget (and all child widgets) to create
135 dict_or_instance - what to use to connect the signals.
136 It is either a dictionary where the
137 signal handlers are indexed by the name of the handler in the glade
138 file, or an instance of a class where the methods have the same
139 names as given in the glade file.
141 template=Templates(fname)
142 if dict_or_instance:
143 template.autoConnect(dict_or_instance)
144 return template.getWidgetSet(root)