Package iceprod :: Package client :: Package gtk :: Module GtkParameterList
[hide private]
[frames] | no frames]

Source Code for Module iceprod.client.gtk.GtkParameterList

  1  #!/bin/env python 
  2  # 
  3  """ 
  4    IceTray connections frame for GtkIcetraConfig application 
  5   
  6    copyright  (c) 2005 the icecube collaboration 
  7   
  8    @version: $Revision: $ 
  9    @date: $Date:  $ 
 10    @author: Juan Carlos Diaz Velez <juancarlos@icecube.wisc.edu> 
 11  """ 
 12   
 13  import pygtk 
 14  pygtk.require("2.0") 
 15  import gtk, gobject 
 16  from iceprod.core.dataclasses import * 
 17  from GtkVector import GtkVector 
 18  import logging 
 19   
 20  logger = logging.getLogger('GtkParameterList') 
 21   
22 -class GtkParameterList:
23 """ The GUI class is the controller for our application """
24 - def __init__(self,cobj):
25 26 self.cobj = cobj 27 self.store = InfoModel(self.cobj) 28 self.display = DisplayModel(self) 29 30 # setup the main window 31 self.root = gtk.Window(type=gtk.WINDOW_TOPLEVEL) 32 self.root.set_title("Parameter Table") 33 self.root.set_size_request(800, 700) 34 35 # Add scrolled window 36 self.sw = gtk.ScrolledWindow() 37 38 # Get the model and attach it to the view 39 self.mdl = self.store.get_model() 40 self.view = self.display.make_view( self.mdl ) 41 self.vbox = gtk.VBox() 42 self.sw.add(self.view) 43 self.vbox.pack_start(self.sw) 44 45 self.hbbox = gtk.HButtonBox() 46 self.b0 = gtk.Button('Add Parameter') 47 self.b1 = gtk.Button('Delete Parameter') 48 self.b0.connect('clicked', self.display.add_parameter,self.store) 49 self.b1.connect('clicked', self.display.delete_parameter,self.mdl) 50 self.hbbox.pack_start(self.b0, False, False, 1) 51 self.hbbox.pack_start(self.b1, False, False, 1) 52 53 self.vbox.pack_start(self.hbbox, False) 54 # Add our view into the main window 55 self.root.add(self.vbox) 56 self.root.show_all() 57 return
58
59 - def redraw(self, widget, event=None):
60 self.store.redraw()
61
62 -class InfoModel:
63 """ The model class holds the information we want to display """ 64
65 - def __init__(self,cobj):
66 """ Sets up and populates our gtk.TreeStore """ 67 self.tree_store = gtk.ListStore( str, str, str , str) 68 self.cobj = cobj 69 self.redraw()
70
71 - def redraw(self):
72 self.tree_store.clear() 73 params = self.cobj.GetParameters() 74 for p in params: 75 if p.GetType() == 'OMKey': 76 value = "OMKey(%s,%s)" % (p.GetValue().stringid,p.GetValue().omid) 77 row = [p.GetType(),p.GetName(), value, '' ] 78 elif p.GetType() == 'OMKeyv': 79 getvalue = lambda x: "OMKey(%s,%s)" % (x.stringid,x.omid) 80 if len(p.GetValue()) > 0: 81 value = "[%s]" % (','.join(map(getvalue,p.GetValue()))) 82 else: 83 value = "[]" % (','.join(map(getvalue,p.GetValue()))) 84 row = [p.GetType(),p.GetName(), value, '' ] 85 elif p.GetType() in VectorTypes: 86 getvalue = lambda x: x.unit and "%s*I3Units::%s" % (x.value,x.unit) \ 87 or x.value 88 if len(p.GetValue()) > 0: 89 value = "[%s]" % (','.join(map(getvalue,p.GetValue()))) 90 else: 91 value = "[]" 92 row = [p.GetType(),p.GetName(), value, '' ] 93 else: 94 row = [p.GetType(),p.GetName(), p.GetValue().value, p.GetValue().unit or '' ] 95 self.tree_store.append( row ) 96 logger.debug('|'.join(row))
97 98
99 - def add_parameter(self, param):
100 row = [param.GetType(),param.GetName(),param.GetValue().value,param.GetValue().unit or '' ] 101 self.tree_store.append( row ) 102 logger.debug('|'.join(row))
103
104 - def get_model(self):
105 """ Returns the model """ 106 if self.tree_store: 107 return self.tree_store 108 else: 109 return None
110
111 -class DisplayModel:
112 """ Displays the Info_Model model in a view """
113 - def __init__(self,parent):
114 self.parent = parent 115 self.cobj = self.parent.cobj 116 self.tips = gtk.Tooltips() 117 self.tips.enable() 118 self.popup = gtk.Menu() 119 viewconfig = gtk.MenuItem("view in browser...") 120 viewconfig.show() 121 viewconfig.connect("activate",self.showpage) 122 self.popup.append(viewconfig) 123 self.popup.show() 124 self.url = None
125
126 - def showpage(self, widget):
127 try: 128 import webbrowser 129 print self.url 130 webbrowser.open(self.url) 131 except Exception,e: 132 logger.debug(e) 133 pass
134
135 - def edit_vector(self, tv, path, viewcol):
136 sel = self.view.get_selection() 137 sel.select_path(path) 138 model, iter = sel.get_selected() 139 row = model[path] 140 pname = row[1] 141 param = self.cobj.GetParameter(pname) 142 if param: 143 if param.GetType() in VectorTypes: 144 self.mlist = GtkVector(param,self.parent)
145
146 - def showtip( self, widget, event):
147 if widget == self.view and self.view.get_path_at_pos(int(event.x),int(event.y)): 148 path,w,x,y = self.view.get_path_at_pos(int(event.x),int(event.y)) 149 model = self.view.get_model() 150 row = model[path] 151 pname = row[1] 152 param = self.cobj.GetParameter(pname) 153 154 if not isinstance(param.GetValue(),list) and param.GetValue().value.startswith('http'): 155 self.tips.set_tip(self.view, "right-click to view in browser") 156 else: 157 self.tips.set_tip(self.view, param.GetDescription()) 158 self.tips.enable()
159
160 - def on_selection_changed(self,selection):
161 pname = None 162 163 model, iter = selection.get_selected() 164 if iter: 165 try: 166 ptype = model.get_value(iter, 0) 167 pname = model.get_value(iter, 1) 168 param = self.cobj.GetParameter(pname) 169 logger.debug("selected: %s %s" % (ptype,pname)) 170 171 self.tips.set_tip(self.view, param.GetDescription()) 172 173 if ptype in VectorTypes: 174 self.renderer2.set_property( 'editable', False) 175 else: 176 self.renderer2.set_property( 'editable', True) 177 except: pass
178 179
180 - def make_view( self, model ):
181 """ Form a view for the Tree Model """ 182 self.view = gtk.TreeView( model ) 183 self.selection = self.view.get_selection() 184 self.selection.connect('changed', self.on_selection_changed) 185 self.view.connect( 'row-activated', self.edit_vector ) 186 self.view.connect( 'motion-notify-event', self.showtip ) 187 188 # setup the text cell renderer and allows these 189 # cells to be edited. 190 self.renderer0 = gtk.CellRendererText() 191 self.renderer0.set_property( 'editable', True) 192 self.renderer0.connect( 'edited', self.col0_edited_cb, model ) 193 194 self.renderer1 = gtk.CellRendererText() 195 self.renderer1.set_property( 'editable', True) 196 self.renderer1.connect( 'edited', self.col1_edited_cb, model ) 197 198 self.renderer2 = gtk.CellRendererText() 199 self.renderer2.set_property( 'editable', True ) 200 self.renderer2.connect( 'edited', self.col2_edited_cb, model ) 201 202 self.renderer3 = gtk.CellRendererText() 203 self.renderer3.set_property( 'editable', True ) 204 self.renderer3.connect( 'edited', self.col3_edited_cb, model ) 205 206 self.column0 = gtk.TreeViewColumn("Type",self.renderer0, text=0) 207 self.column1 = gtk.TreeViewColumn("Name",self.renderer1, text=1) 208 self.column2 = gtk.TreeViewColumn("Value",self.renderer2,text=2 ) 209 self.column3 = gtk.TreeViewColumn("Unit",self.renderer3,text=3 ) 210 211 self.view.append_column( self.column0 ) 212 self.view.append_column( self.column1 ) 213 self.view.append_column( self.column2 ) 214 self.view.append_column( self.column3 ) 215 216 self.view.connect('button-press-event', self.clicked) 217 218 return self.view
219
220 - def col0_edited_cb( self, cell, path, new_text, model ):
221 """ 222 Canges the type of the parameter (for manually added params) 223 @todo: add type checking for input values 224 """ 225 logger.debug("Change '%s' to '%s'" % (model[path][0], new_text)) 226 row = model[path] 227 pname = row[1] 228 param = self.cobj.GetParameter(pname) 229 if param: 230 # Some kind of type checking should happen here 231 param.SetType(u'%s' % new_text) 232 if new_text in VectorTypes and not isinstance(param.GetValue(),list): 233 param.SetValue([param.GetValue()]) 234 235 row[0] = u'%s' % new_text 236 237 self.parent.redraw(None,None)
238
239 - def col1_edited_cb( self, cell, path, new_text, model ):
240 """ 241 Canges the name of the parameter (for manually added params) 242 @todo: add type checking for input values 243 """ 244 logger.debug("Change '%s' to '%s'" % (model[path][2], new_text)) 245 row = model[path] 246 pname = row[1] 247 param = self.cobj.GetParameter(pname) 248 if param: 249 self.cobj.RemoveParameter(pname) 250 param.SetName(u'%s' % new_text) 251 self.cobj.AddParameter(param) 252 row[1] = u'%s' % new_text
253
254 - def clicked(self, view, event):
255 if event.button == 3 and view.get_path_at_pos(int(event.x), int(event.y)): 256 path, col, cellx, celly = view.get_path_at_pos(int(event.x), int(event.y)) 257 self.view.grab_focus() 258 selection = self.view.get_selection() 259 if not selection.path_is_selected(path): 260 self.view.set_cursor( path, col, 0) 261 262 model, iter = selection.get_selected() 263 pname = model.get_value(iter, 1) 264 pvalue = self.cobj.GetParameter(pname).GetValue().value 265 if pvalue.startswith('http'): 266 self.url = pvalue 267 self.popup.popup( None, None, None, event.button, event.time) 268 269 return True
270
271 - def parse_val(self,ptype,value):
272 if ptype in VectorTypes: 273 if ptype.startswith("OMKey"): 274 valvect = re.findall(r'OMKey\(\s*[0-9]+\s*,\s*[0-9]+\s*\)',value) 275 valvect = map(lambda x: self.parse_val("OMKey",x),valvect) 276 return valvect 277 else: 278 val = value.strip("[").strip("]").strip().split(",") 279 val = map(lambda x: x.strip("\""),val) 280 281 if ptype.startswith("string") or ptype.startswith("bool"): 282 return map(Value,val) 283 else: 284 vals = map(lambda x: x.split("*I3Units::")[0],val) 285 units = map(lambda x: (len(x.split("*I3Units::")) > 1 and \ 286 x.split("*I3Units::") or [None,None])[1] ,val) 287 return map(lambda x,y: Value(x,y),vals,units) 288 elif ptype == 'OMKey' and value.startswith("OMKey"): 289 val = value.replace("OMKey",'').replace("(",'').replace(")",'').split(",") 290 return pyOMKey(val[0],val[1]) 291 else: return Value(value)
292
293 - def col2_edited_cb( self, cell, path, new_text, model ):
294 """ 295 Canges the value of the parameter 296 @todo: add type checking for input values 297 @todo: add descriptions 298 """ 299 logger.debug("Change '%s' to '%s'" % (model[path][2], new_text)) 300 row = model[path] 301 pname = row[1] 302 param = self.cobj.GetParameter(pname) 303 if param: 304 if param.GetType() in VectorTypes: 305 return 306 else: 307 try: 308 unit = model[path][3] 309 param.SetValue(self.parse_val(param.GetType(),new_text)) 310 if unit: 311 param.GetValue().SetUnit(unit) 312 row[2] = u'%s' % new_text 313 except Exception,e: 314 logger.error(str(e)+": unable to parse value '%s'"% new_text)
315
316 - def col3_edited_cb( self, cell, path, new_text, model ):
317 """ 318 Canges the value of the parameter 319 @todo: add type checking for input values 320 @todo: add descriptions 321 """ 322 logger.debug("Change '%s' to '%s'" % (model[path][3], new_text)) 323 row = model[path] 324 pname = row[1] 325 param = self.cobj.GetParameter(pname) 326 if param and new_text: 327 if param.GetType().startswith('OMKey'): 328 logger.error("type '%s' - does not accept I3Units"%param.GetType()) 329 return 330 elif param.GetType() in VectorTypes: 331 map(lambda x:x.SetUnit(u'%s' % new_text),param.GetValue()) 332 else: 333 param.GetValue().SetUnit(u'%s' % new_text) 334 row[3] = u'%s' % new_text
335
336 - def add_parameter(self, b, model):
337 """ 338 Manually add a parameter 339 """ 340 param = Parameter() 341 param.SetName('new_parameter') 342 param.SetType('string') 343 param.SetValue(Value('NULL')) 344 self.cobj.AddParameter(param) 345 model.add_parameter(param)
346 347
348 - def delete_parameter(self, b, mymodel):
349 sel = self.view.get_selection() 350 model, iter = sel.get_selected() 351 pname = mymodel.get_value(iter,1) 352 logger.debug("deleting %s" % pname) 353 self.cobj.RemoveParameter(pname) 354 model.remove(iter)
355