1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import pygtk
22 import gobject
23 pygtk.require('2.0')
24 import gtk
25 import sqlobject
26 from sqlobject.col import *
27 import ConfigParser
28 import widgets
29
31 """reads configuration settings from <i>filename</i> and returns an URI that can be passed as
32 connection string to <i>connectionForURI(connection_string)</i> from sqlobject. If the second
33 parameter <i>passw</i> is given, it will use this as password for the string even if a password
34 is found in the configuration file. If no password is found nor passed as argument, the URI will
35 be formed without password."""
36 config_parser = ConfigParser.SafeConfigParser()
37 config_parser.read(filename)
38 dbms = config_parser.get("dbconn","dbms")
39 host = config_parser.get("dbconn","host")
40 port = config_parser.get("dbconn","port")
41 db = config_parser.get("dbconn","db")
42 user = config_parser.get("dbconn","user")
43 if passw:
44 pw = passw
45 else:
46 pw = config_parser.get("dbconn","pw")
47
48 if len(pw) > 0:
49 user ="%s:%s" %(user, pw)
50 if len(user)> 0:
51 user ="%s@" % (user,)
52
53 connstr = "%s://%s%s/%s" % (dbms,user,host,db)
54
55 return connstr
56
57
59 coltype = gobject.TYPE_NONE
60 if type(column) is SOStringCol:
61 coltype = gobject.TYPE_STRING
62 elif type(column) is SOIntCol:
63 coltype = gobject.TYPE_INT
64 elif type(column) is SODecimalCol:
65
66 coltype = gobject.TYPE_FLOAT
67 elif type(column) is SOFloatCol:
68 coltype = gobject.TYPE_FLOAT
69 elif type(column) is SOBoolCol:
70 coltype = gobject.TYPE_BOOLEAN
71 elif type(column) is SOCurrencyCol:
72
73 coltype = gobject.TYPE_FLOAT
74 elif type(column) is SODateTimeCol:
75 coltype = gobject.TYPE_STRING
76 elif type(column) is SODateCol:
77 coltype = gobject.TYPE_STRING
78 elif type(column) is SOTimeCol:
79 coltype = gobject.TYPE_STRING
80 elif type(column) is SOUnicodeCol:
81 coltype = gobject.TYPE_STRING
82 elif type(column) is SOPickelCol:
83 coltype = gobject.TYPE_OBJECT
84 elif type(column) is SOForeignKey:
85 coltype = gobject.TYPE_INT
86
87 elif type(column) is SOMultipleJoin:
88 coltype = gobject.TYPE_OBJECt
89 return coltype
90
92 """a Treemodel that can be used with gtk.TreeView. This model helps combining
93 the power of SQLObject and pygtk"""
94 select_list = []
95 select_args = None
96 sql_object = None
97 __where_clause = ()
98
99
100
102 """The constructor takes a SQLObject Class (not an Instance!) as only argument. However, the
103 model does not contain any data yet on construction time. To fill the model with data you have
104 to call the method <i>refresh()</i>"""
105 gtk.GenericTreeModel.__init__(self)
106 self.sql_object = sql_object
107
108 self.select = self.sql_object.select
109
111 return gtk.TREE_MODEL_LIST_ONLY|gtk.TREE_MODEL_ITERS_PERSIST
112
114 "returns the number of cols of the model"
115 return len(self.sql_object.sqlmeta.columnList)
116
120
122 try:
123 return self.select_list[path[0]]
124 except IndexError:
125 return None
126
129
131 name = '_SO_val_'+self.sql_object.sqlmeta.columnList[column].name
132 return rowref.__dict__[name]
133
135 try:
136 i = self.select_list.index(rowref)+1
137 return self.select_list[i]
138 except IndexError:
139 return None
140
142 if rowref:
143 return None
144 else:
145 return self.select_list[0]
146
149
151 if rowref:
152 return 0
153 else:
154 return len(self.select_list)
155
157 if rowref:
158 return None
159 try:
160 return self.select_list[0]
161 except IndexError:
162 return None
163
166
168 for column in self.sql_object.sqlmeta.columnList:
169 if column.name == col_name:
170 return self.sql_object.sqlmeta.columnList.index(column)
171
172
174 """in order to be able to navigate forward and backward through the list, this method has been added
175 to complement <i>iter_next()</i>."""
176 pathstr="0"
177 path = self.get_path(iter)
178 if path[0]>0:
179 index = path[0]
180 index = index-1
181 pathstr =str(index)
182 return self.get_iter_from_string(pathstr)
183
185 """fills the list with instances. Arguments are like in SQLObject.select().
186 If no argument is given, the last used arguments are used. To make a full select,
187 call flush before refresh"""
188 if len(value)>0:
189 self.__where_clause = value
190 select_result = self.select(*value)
191 self.select_list = list(select_result)
192
194 """flushes the argument buffer that keeps the last used argument with refresh()."""
195 self.__where_clause = ()
196
198 """Creates a new SqlObject instance and appends it to the model, no matter if it complies with the
199 last used select parameters. The parameters are just the same as if for the corresponding SqlObject
200 class."""
201 new_row = self.sql_object(**values)
202 self.select_list.append(new_row)
203 path = self.select_list.index(new_row)
204 self.row_inserted(path,self.get_iter(path))
205
206
208 row = self.get_row(iter)
209 row.set(**values)
210 self.row_changed(self.get_path(iter),iter)
211
212
214 try:
215 return self.select_list[self.get_path(iter)[0]]
216 except:
217 return None
218
220 row = self.get_row(iter)
221 del_id = row.id
222 path = self.get_path(iter)
223 self.select_list.remove(row)
224 self.row_deleted(path)
225 self.sql_object.delete(del_id)
226
227
228
229
230
232 """This Class controls representation and manipulation of row data (SQLObject Instance) through
233 pygtk widgets"""
234 __row = None
235 widgets = []
236
247
262
282
283
285 """Sets the widget contents to the values of the assigned SqlObject instance. This can also be used
286 to explicitely update the widgets' contents, for example when widgets are added to the controller
287 after an SqlObject instance has been set, or simply to implement a reset button in a data form."""
288 if self.__row:
289 for w in self.widgets:
290 field_name, widget = w
291 field_name = '_SO_val_'+field_name
292 value = self.__row.__dict__[field_name]
293 self.set_widget_value(widget, value)
294 else:
295 for w in self.widgets:
296 field_name, widget = w
297 field_name = '_SO_val_'+field_name
298 self.set_widget_value(widget, "")
299
300
301 - def set_row(self, sqlobj_instance):
302 """row is an sqlobject instance or None"""
303 if sqlobj_instance:
304 self.__row = sqlobj_instance
305 self.reset()
306
309
311 """writes the values of the widgets to the assigned SqlObject instance fields. This implies
312 that the values are written to the database, unless lazy update is set. See SqlObject
313 documentation for more details"""
314 values = dict()
315 for w in self.widgets:
316 value = None
317 field_name, widget = w
318 value = self.get_widget_value(widget)
319 print value
320 if value:
321 values[field_name] = value
322 self.__row.set(**values)
323
330
332 """calls set_editable of all the widgets assigned to the controller. You should provide a method
333 set_editable(True|False) with your own compound widgets. If you don't, it won't rise an an exception
334 but obviously it won't work either."""
335 for w in self.widgets:
336 field_name, widget = w
337 if hasattr(widget, 'set_editable'):
338 widget.set_editable(editable)
339
340
342 """A controller for navigating through a SqlListModel"""
344 self.model = sql_list_model
345 self.iter = self.model.get_iter_first()
346 self.set_row(self.model.get_row(self.iter))
347
349 """Sets the controller to the next SqlObject Instance in the list"""
350 if not self.iter:
351 return
352 if self.is_dirty():
353 self.commit()
354 if self.model.iter_next(self.iter):
355 self.iter = self.model.iter_next(self.iter)
356 self.set_row(self.model.get_row(self.iter))
357
359 if not self.iter:
360 return
361 """Sets the controller to the previous SqlObject Instance in the list"""
362 if self.is_dirty():
363 self.commit()
364 self.iter = self.model.iter_previous(self.iter)
365 self.set_row(self.model.get_row(self.iter))
366