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