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