/[ascend]/trunk/pygtk/interface/gtkbrowser.py
ViewVC logotype

Contents of /trunk/pygtk/interface/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 176 - (show annotations) (download) (as text)
Tue Jan 10 06:22:23 2006 UTC (13 years, 8 months ago) by johnpye
File MIME type: text/x-python
File size: 24919 byte(s)
Completed PyGTK plotting using matplotlib
1 #!/usr/bin/env python
2
3 import pygtk
4 pygtk.require('2.0')
5 import gtk
6 import gtk.glade
7 import pango
8 import re
9 import preferences
10 import urlparse
11 import optparse
12
13 import sys, dl
14 # This sets the flags for dlopen used by python so that the symbols in the
15 # ascend library are made available to libraries dlopened within ASCEND:
16 sys.setdlopenflags(dl.RTLD_GLOBAL|dl.RTLD_NOW)
17 import ascend
18
19 # This is my first ever GUI code so please be nice :)
20
21 # The fancy tree-view gizmo is the GtkTreeView object. See the article
22 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/300304
23 # for the original source code on which my implementation was based.
24
25 GLADE_FILE = "/home/john/src/ascend/trunk/pygtk/interface/ascend.glade"
26
27 class Browser:
28
29 # ---------------------------------
30 # SETUP
31
32 def __init__(self):
33 #--------
34 # load the file referenced in the command line, if any
35
36 parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
37 # add options here if we want
38
39 parser.add_option("-m", "--model"
40 ,action="store", type="string", dest="model"
41 ,help="specify the model to instantiate upon loading modules")
42 (options, args) = parser.parse_args()
43
44 #print "OPTIONS_______________:",options
45
46 #--------
47 # load up the preferences ini file
48
49 self.prefs = preferences.Preferences()
50
51 #--------
52 # initialise ASCEND
53
54 self.library = ascend.Library()
55
56 self.sim = None
57
58 #-------------------
59 # Set up the window and main widget actions
60
61 glade = gtk.glade.XML(GLADE_FILE,"browserwin")
62
63 self.window = glade.get_widget("browserwin")
64 if not self.window:
65 raise RuntimeError("Couldn't load window from glade file")
66
67 _display = self.window.get_screen().get_display().get_name();
68 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
69 if _geom:
70 self.window.resize(_geom[0],_geom[1]);
71 self.window.move(_geom[2],_geom[3]);
72
73 self.window.connect("delete_event", self.delete_event)
74
75 self.browserpaned=glade.get_widget("browserpaned");
76 _geom2=self.prefs.getGeometryValue(_display,"browserpaned");
77 if _geom2:
78 self.browserpaned.set_position(_geom2);
79
80 self.openbutton=glade.get_widget("openbutton")
81 self.openbutton.connect("clicked",self.open_click)
82
83 self.reloadbutton=glade.get_widget("reloadbutton")
84 self.reloadbutton.connect("clicked",self.reload_click)
85
86 self.solvebutton=glade.get_widget("solvebutton")
87 self.solvebutton.connect("clicked",self.solve_click)
88
89 self.checkbutton=glade.get_widget("checkbutton")
90 self.checkbutton.connect("clicked",self.check_click)
91
92 self.autotoggle=glade.get_widget("autotoggle")
93 self.autotoggle.connect("toggled",self.auto_toggle)
94
95 self.methodrunbutton=glade.get_widget("methodrunbutton")
96 self.methodrunbutton.connect("clicked",self.methodrun_click)
97
98 self.methodsel=glade.get_widget("methodsel")
99
100 self.maintabs = glade.get_widget("maintabs")
101
102 self.statusbar = glade.get_widget("statusbar")
103
104 #-------------------
105 # waitwin
106
107 self.waitwin = gtk.gdk.Window(self.window.window,
108 gtk.gdk.screen_width(),
109 gtk.gdk.screen_height(),
110 gtk.gdk.WINDOW_CHILD,
111 0,
112 gtk.gdk.INPUT_ONLY)
113
114 _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
115 self.waitwin.set_cursor(_cursor)
116
117 #-------------------
118 # pixbufs to be used in the error listing
119
120 self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
121 self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
122 self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
123 self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
124
125 #--------------------
126 # set up the context menu for fixing/freeing vars
127
128 self.treecontext = gtk.Menu();
129 self.fixmenuitem = gtk.MenuItem("Fix");
130 self.freemenuitem = gtk.MenuItem("Free");
131 self.plotmenuitem = gtk.MenuItem("Plot");
132 self.fixmenuitem.show()
133 self.freemenuitem.show()
134 self.plotmenuitem.show()
135 self.treecontext.append(self.fixmenuitem);
136 self.treecontext.append(self.freemenuitem);
137 self.treecontext.append(self.plotmenuitem);
138 self.fixmenuitem.connect("activate",self.fix_activate)
139 self.freemenuitem.connect("activate",self.free_activate)
140 self.plotmenuitem.connect("activate",self.plot_activate)
141 if not self.treecontext:
142 raise RuntimeError("Couldn't create browsercontext")
143 #--------------------
144 # set up the error view
145
146 self.errorview = glade.get_widget("errorview")
147 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
148 self.errorstore = gtk.TreeStore(*errstorecolstypes)
149 errtitles = ["","Location","Message"];
150 self.errorview.set_model(self.errorstore)
151 self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
152
153 i = 0
154 for tvcolumn in self.errcols[:len(errtitles)]:
155 tvcolumn.set_title(errtitles[i])
156 self.errorview.append_column(tvcolumn)
157
158 if i>0:
159 _renderer = gtk.CellRendererText()
160 tvcolumn.pack_start(_renderer, True)
161 tvcolumn.add_attribute(_renderer, 'text', i)
162 if(i==2):
163 tvcolumn.add_attribute(_renderer, 'foreground', 3)
164 tvcolumn.add_attribute(_renderer, 'weight', 4)
165 else:
166 _renderer1 = gtk.CellRendererPixbuf()
167 tvcolumn.pack_start(_renderer1, False)
168 tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
169
170 i = i + 1
171
172
173 #--------------------
174 # set up the error reporter callback
175 self.reporter = ascend.getReporter()
176 self.reporter.setPythonErrorCallback(self.error_callback)
177
178 #-------------------
179 # set up the module view
180
181 self.modtank = {}
182 self.moduleview = glade.get_widget("moduleview")
183 modulestorecoltypes = [str, str]
184 self.modulestore = gtk.TreeStore(*modulestorecoltypes)
185 moduleviewtitles = ["Module name", "Filename"]
186 self.moduleview.set_model(self.modulestore)
187 self.modcols = [ gtk.TreeViewColumn() for _type in modulestorecoltypes]
188 i = 0
189 for modcol in self.modcols[:len(moduleviewtitles)]:
190 modcol.set_title(moduleviewtitles[i])
191 self.moduleview.append_column(modcol)
192 _renderer = gtk.CellRendererText()
193 modcol.pack_start(_renderer, True)
194 modcol.add_attribute(_renderer, 'text', i)
195 i = i + 1
196 self.moduleview.connect("row-activated", self.module_activated )
197
198 #-------------------
199 # RE for units matching
200 self.units_re = re.compile("([-+]?(\d+(\.\d*)?|\d*\.d+)([eE][-+]?\d+)?)\s*(.*)");
201
202 #--------------------
203 # set up the methods combobox
204
205 self.methodstore = gtk.ListStore(str)
206 self.methodsel.set_model(self.methodstore)
207 _methodrenderer = gtk.CellRendererText()
208 self.methodsel.pack_start(_methodrenderer, True)
209 self.methodsel.add_attribute(_methodrenderer, 'text',0)
210
211 #--------
212 # set up the instance browser view
213
214 self.otank = {}
215 self.treeview = glade.get_widget("browserview")
216 columns = [str,str,str,str,int,bool]
217 self.treestore = gtk.TreeStore(*columns)
218 titles = ["Name","Type","Value"];
219 self.treeview.set_model(self.treestore)
220 self.tvcolumns = [ gtk.TreeViewColumn() for _type in columns[:len(titles)] ]
221
222 self.treeview.connect("row-expanded", self.row_expanded )
223 self.treeview.connect("button-press-event", self.tree_click )
224
225 # data columns are: name type value colour weight editable
226
227 i = 0
228 for tvcolumn in self.tvcolumns[:len(titles)]:
229 tvcolumn.set_title(titles[i])
230 self.treeview.append_column(tvcolumn)
231
232 renderer = gtk.CellRendererText()
233 tvcolumn.pack_start(renderer, True)
234 tvcolumn.add_attribute(renderer, 'text', i)
235 tvcolumn.add_attribute(renderer, 'foreground', 3)
236 tvcolumn.add_attribute(renderer, 'weight', 4)
237 if(i==2):
238 tvcolumn.add_attribute(renderer, 'editable', 5)
239 renderer.connect('edited',self.cell_edited_callback)
240 i = i + 1
241
242
243 if(len(args)==1):
244 self.do_open(args[0])
245
246 print "Options: ",options
247
248 if options.model:
249 try:
250 _t =self.library.findType(options.model);
251 self.do_sim(_t);
252 except RuntimeError, e:
253 self.reporter.reportError("Failed to create instance of '%s': %s" %(options.model, str(e)));
254
255 def run(self):
256 self.window.show()
257 gtk.main()
258
259 # --------------------------------------------
260 # MAJOR GUI COMMANDS
261
262
263 def do_open(self,filename):
264 # TODO does the user want to lose their work?
265 # TODO do we need to chdir?
266
267 _context = self.statusbar.get_context_id("do_open")
268
269 self.errorstore.clear()
270
271 self.treestore.clear()
272 self.otank = {}
273
274 # self.library.clear()
275
276 self.statusbar.push(_context,"Loading '"+filename+"'")
277 self.library.load(filename)
278 self.statusbar.pop(_context)
279
280 self.filename = filename
281
282 # Load the current list of modules into self.modules
283 self.modtank = {}
284 self.modulestore.clear()
285 modules = self.library.getModules()
286 for m in reversed(modules):
287 _n = str( m.getName() )
288 _f = str( m.getFilename() )
289 #print "ADDING ROW name %s, file = %s" % (_n, _f)
290 _r = self.modulestore.append(None, [ _n, _f ])
291 for t in self.library.getModuleTypes(m):
292 _n = t.getName()
293 #print "ADDING TYPE %s" % _n
294 _piter = self.modulestore.append(_r , [ _n, "" ])
295 _path = self.modulestore.get_path(_piter)
296 self.modtank[_path]=t
297
298 #print "DONE ADDING MODULES"
299
300 self.sim = None;
301 self.maintabs.set_current_page(0);
302
303 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
304 # for details on how the 'wait cursor' is done.
305 def start_waiting(self, message):
306 self.waitcontext = self.statusbar.get_context_id("waiting")
307 self.statusbar.push(self.waitcontext,message)
308
309 if self.waitwin:
310 self.waitwin.show()
311
312 while gtk.events_pending():
313 gtk.main_iteration()
314
315 def stop_waiting(self):
316 if self.waitwin:
317 self.statusbar.pop(self.waitcontext)
318 self.waitwin.hide()
319
320 def do_sim(self, type_object):
321 self.sim = None;
322 # TODO: clear out old simulation first!
323
324 print "DO_SIM(%s)" % str(type_object.getName())
325 self.start_waiting("Compiling...")
326
327 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim")
328 print "...DONE 'getSimulation'"
329 self.stop_waiting()
330
331 self.start_waiting("Building simulation...")
332 print "BUILDING SIMULATION"
333 self.sim.build()
334 print "DONE BUILDING"
335 self.stop_waiting()
336
337 # empty things out first
338 self.methodstore.clear()
339 self.treestore.clear()
340
341 # methods
342 _methods = self.sim.getType().getMethods()
343 _activemethod = None;
344 for _m in _methods:
345 _i = self.methodstore.append([_m.getName()])
346 if _m.getName()=="default_self":
347 self.methodsel.set_active_iter(_i)
348
349 # instance hierarchy
350 self.otank = {} # map path -> (name,value)
351 self.make( self.sim.getName(),self.sim.getModel() )
352 self.maintabs.set_current_page(1);
353
354 def do_solve(self):
355 if not self.sim:
356 self.reporter.reportError("No model selected yet")
357 return;
358
359 self.start_waiting("Solving...")
360
361 self.sim.solve(ascend.Solver("QRSlv"))
362
363 self.stop_waiting()
364 self.refreshtree()
365
366 def do_check(self):
367 if not self.sim:
368 self.reporter.reportError("No model selected yet")
369
370 self.start_waiting("Checking system...")
371
372 if self.sim.check():
373 self.reporter.reportNote("System check OK")
374
375 self.sim.checkDoF()
376
377 self.stop_waiting()
378
379 self.refreshtree()
380
381 def do_method(self,method):
382 if not self.sim:
383 self.reporter.reportError("No model selected yet")
384
385 self.sim.run(method)
386 self.refreshtree()
387
388 # --------------------------------------------
389 # MODULE LIST
390
391 def module_activated(self, treeview, path, column, *args):
392 modules = self.library.getModules()
393 print "PATH",path
394 if len(path)==1:
395 self.reporter.reportNote("Launching of external editor not yet implemented")
396 elif len(path)==2:
397 if(self.modtank.has_key(path)):
398 _type = self.modtank[path];
399 self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
400 self.do_sim(_type)
401 else:
402 self.reporter.reportError("Didn't find type corresponding to row")
403
404 # --------------------------------------------
405 # INSTANCE TREE
406
407 def get_tree_row_data(self,instance):
408 _value = str(instance.getValue())
409 _type = str(instance.getType())
410 _name = str(instance.getName())
411 _fgcolor = "black"
412 _fontweight = pango.WEIGHT_NORMAL
413 _editable = False
414 if instance.getType().isRefinedSolverVar():
415 _editable = True
416 if instance.isFixed():
417 _fgcolor = "#008800"
418 _fontweight = pango.WEIGHT_BOLD
419 else:
420 _fgcolor = "#000088"
421 _fontweight = pango.WEIGHT_BOLD
422 elif instance.isBool() or instance.isReal() or instance.isInt():
423 # TODO can't edit constants that have already been refined
424 _editable = True
425
426 #if(len(_value) > 80):
427 # _value = _value[:80] + "..."
428
429 return [_name, _type, _value, _fgcolor, _fontweight, _editable]
430
431 def get_error_row_data(self,sev,filename,line,msg):
432 _sevicon = {
433 0: self.iconok
434 ,1: self.iconinfo
435 ,2: self.iconwarning
436 ,3: self.iconerror
437 ,4: self.iconinfo
438 ,5: self.iconwarning
439 ,6: self.iconerror
440 }[sev]
441
442 _fontweight = pango.WEIGHT_NORMAL
443 if sev==6:
444 _fontweight = pango.WEIGHT_BOLD
445
446 _fgcolor = "black"
447 if sev==4:
448 _fgcolor = "#888800"
449 elif sev==5:
450 _fgcolor = "#884400"
451 elif sev==6:
452 _fgcolor = "#880000"
453 elif sev==0:
454 _fgcolor = "#008800"
455
456 if not filename and not line:
457 _fileline = ""
458 else:
459 if(len(filename) > 25):
460 filename = "..."+filename[-22:]
461 _fileline = filename + ":" + str(line)
462
463 _res = [_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight]
464 #print _res
465 return _res
466
467 def make_row( self, piter, name, value ):
468
469 _piter = self.treestore.append( piter, self.get_tree_row_data(value) )
470 return _piter
471
472 def refreshtree(self):
473 # @TODO FIXME use a better system than colour literals!
474 for _path in self.otank: # { path : (name,value) }
475 _iter = self.treestore.get_iter(_path)
476 _name, _instance = self.otank[_path]
477 self.treestore.set_value(_iter, 2, _instance.getValue())
478 if _instance.getType().isRefinedSolverVar():
479 if _instance.isFixed() and self.treestore.get_value(_iter,3)=="#000088":
480 self.treestore.set_value(_iter,3,"#008800")
481 elif not _instance.isFixed() and self.treestore.get_value(_iter,3)=="#008800":
482 self.treestore.set_value(_iter,3,"#000088")
483
484 def cell_edited_callback(self, renderer, path, newtext, **kwargs):
485 # get back the Instance object we just edited (having to use this seems like a bug)
486 path = tuple( map(int,path.split(":")) )
487
488 if not self.otank.has_key(path):
489 raise RuntimeError("cell_edited_callback: invalid path '%s'" % path)
490 return
491
492 _name, _instance = self.otank[path]
493
494 if _instance.isReal():
495 # only real-valued things can have units
496
497 try:
498 # match a float with option text afterwards, optionally separated by whitespace
499 _match = re.match(self.units_re,newtext)
500 if not _match:
501 self.reporter.reportError("Not a valid value-and-optional-units")
502 return
503
504 _val = _match.group(1)
505 _units = _match.group(5)
506 #_val, _units = re.split("[ \t]+",newtext,2);
507 except RuntimeError:
508 self.reporter.reportError("Unable to split value and units")
509 return
510 print "val = ",_val
511 print "units = ",_units
512
513 # parse the units, throw an error if no good
514 try:
515 _val = float(_val)
516 except RuntimeError:
517 self.reporter.reportError("Unable to convert number part '%s' to float" % _val)
518
519 if _units.strip() == "":
520 _u = _instance.getType().getPreferredUnits()
521 if _u == None:
522 _u = _instance.getDimensions().getDefaultUnits()
523 self.reporter.reportNote("Assuming units '%s'" % _u.getName().toString() )
524 else:
525 try:
526 _u = ascend.Units(_units)
527 self.reporter.reportNote("Parsed units %s" % _units)
528 except RuntimeError:
529 self.reporter.reportError("Unrecognisable units '%s'" % _units)
530 return
531
532 if _instance.getDimensions() != _u.getDimensions():
533
534 if _u.getDimensions().isDimensionless():
535 _units = "[dimensionless]"
536
537 _my_dims = _instance.getDimensions().getDefaultUnits()
538 if _instance.getDimensions().isDimensionless():
539 _my_dims = "[dimensionless]"
540
541 self.reporter.reportError("Incompatible units '%s' (must fit with '%s')"
542 % (_units, _my_dims) )
543 return
544
545 if _units.strip() != "" and not _instance.getDimensions().isDimensionless():
546 self.prefs.setPreferredUnits(str(_instance.getType().getName()), _units);
547
548 _conv = float(_u.getConversion())
549 # self.reporter.reportNote("Converting: multiplying '%s %s' by factor %s to get SI units" % (_val, _units, _conv) )
550 _val = _val * _conv;
551
552 self.reporter.reportNote("Setting '%s' to '%f'" % (_name, _val))
553
554 if _instance.getType().isRefinedSolverVar():
555 # set the 'fixed' flag as well
556 _instance.setFixedValue(float(_val))
557 else:
558 _instance.setRealValue(float(_val))
559 else:
560 if _instance.isBool():
561 _lower = newtext.lower();
562 if _lower.startswith("t") or _lower.startswith("y") or _lower.strip()=="1":
563 newtext = 1
564 elif _lower.startswith("f") or _lower.startswith("n") or _lower.strip()=="0":
565 newtext = 0
566 else:
567 self.reporter.reportError("Invalid entry for a boolean variable: '%s'" % newtext)
568 return
569 _val = bool(newtext);
570 if _val == _instance.getValue():
571 self.reporter.reportNote("Boolean atom '%s' was not altered" % _instance.getName())
572 return
573 _instance.setBoolValue(_val)
574
575 elif _instance.isInt():
576 _val = int(newtext)
577 if _val == _instance.getValue():
578 self.reporter.reportNote("Integer atom '%s' was not altered" % _instance.getName())
579 return
580 _instance.setIntValue(_val)
581 else:
582 self.reporter.reportError("Attempt to set a non-real, non-boolean, non-integer value!")
583 return
584
585 # now that the variable is set, update the GUI and re-solve if desired
586 _iter = self.treestore.get_iter(path)
587 self.treestore.set_value(_iter,2,_instance.getValue())
588
589 if _instance.getType().isRefinedSolverVar():
590 self.treestore.set_value(_iter,3,"#008800") # set the row green as fixed
591
592 if self.autotoggle.get_active():
593 self.sim.check()
594 self.do_solve()
595 #self.reporter.reportError("SOLVER completed")
596
597
598 def make_children(self, value, piter ):
599 if value.isCompound():
600 children=value.getChildren();
601 for child in children:
602 _name = child.getName();
603 _piter = self.make_row(piter,_name,child)
604 _path = self.treestore.get_path(_piter)
605 self.otank[_path]=(_name,child)
606 #self.reporter.reportError("2 Added %s at path %s" % (_name,repr(_path)))
607
608 def make(self, name=None, value=None, path=None, depth=1):
609 if path is None:
610 # make root node
611 piter = self.make_row( None, name, value )
612 path = self.treestore.get_path( piter )
613 self.otank[ path ] = (name, value)
614 #self.reporter.reportError("4 Added %s at path %s" % (name, path))
615 else:
616 name, value = self.otank[ path ]
617
618 piter = self.treestore.get_iter( path )
619 if not self.treestore.iter_has_child( piter ):
620 self.make_children(value,piter)
621
622 if depth:
623 for i in range( self.treestore.iter_n_children( piter ) ):
624 self.make( path = path+(i,), depth = depth - 1 )
625 else:
626 self.treeview.expand_row("0",False)
627
628 def row_expanded( self, treeview, piter, path ):
629 self.make( path = path )
630
631 # ----------------------------------
632 # ERROR PANEL
633
634 def error_callback(self,sev,filename,line,msg):
635 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
636 path = self.errorstore.get_path(pos)
637 col = self.errorview.get_column(3)
638 self.errorview.scroll_to_cell(path,col)
639
640 return 0;
641
642 # --------------------------------
643 # BUTTON METHODS
644
645 def open_click(self,*args):
646 dialog = gtk.FileChooserDialog("Open file...",
647 None,
648 gtk.FILE_CHOOSER_ACTION_OPEN,
649 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
650 gtk.STOCK_OPEN, gtk.RESPONSE_OK))
651 dialog.set_default_response(gtk.RESPONSE_OK)
652
653 filter = gtk.FileFilter()
654 filter.set_name("*.a4c, *.a4l")
655 filter.add_pattern("*.[Aa]4[Cc]")
656 filter.add_pattern("*.[Aa]4[Ll]")
657 dialog.add_filter(filter)
658
659 filter = gtk.FileFilter()
660 filter.set_name("All files")
661 filter.add_pattern("*")
662 dialog.add_filter(filter)
663
664 response = dialog.run()
665 _filename = dialog.get_filename()
666 dialog.destroy()
667
668 if response == gtk.RESPONSE_OK:
669 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
670 self.do_open( _filename)
671
672
673 def reload_click(self,*args):
674 _type = None
675 if(self.sim):
676 _type = self.sim.getType().getName().toString();
677
678 self.do_open(self.filename)
679
680 if _type:
681 _t = self.library.findType(_type)
682 self.do_sim(_t)
683
684 def solve_click(self,*args):
685 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
686 self.do_solve()
687
688 def check_click(self,*args):
689 self.do_check()
690 #self.reporter.reportError("CHECK clicked")
691
692 def methodrun_click(self,*args):
693 _sel = self.methodsel.get_active_text()
694 if _sel:
695 _method = None
696 _methods = self.sim.getType().getMethods()
697 for _m in _methods:
698 if _m.getName()==_sel:
699 _method = _m
700 if not _method:
701 self.reporter.reportError("Method is not valid")
702 return
703 self.do_method(_method)
704 else:
705 self.reporter.reportError("No method selected")
706
707 def auto_toggle(self,button,*args):
708 if button.get_active():
709 self.reporter.reportSuccess("Auto mode is now ON")
710 else:
711 self.reporter.reportSuccess("Auto mode is now OFF")
712
713 # ------------------------------
714 # CONTEXT MENU
715
716 def tree_click(self,widget,event):
717 # which button was clicked?
718 if event.button == 3:
719 _x = int(event.x)
720 _y = int(event.y)
721 _time = event.time
722 _pthinfo = self.treeview.get_path_at_pos(_x, _y)
723 if _pthinfo != None:
724 _canpop = False;
725 _path, _col, _cellx, _celly = _pthinfo
726 # self.reporter.reportError("Right click on %s" % self.otank[_path][0])
727 _instance = self.otank[_path][1]
728 if _instance.getType().isRefinedSolverVar():
729 _canpop = True;
730 if _instance.isFixed():
731 self.fixmenuitem.hide()
732 self.freemenuitem.show()
733 else:
734 self.fixmenuitem.show()
735 self.freemenuitem.hide()
736 else:
737 self.fixmenuitem.hide()
738 self.freemenuitem.hide()
739
740 if _instance.isPlottable():
741 self.reporter.reportNote("Instance IS plottable");
742 self.plotmenuitem.show()
743 _canpop = True;
744 else:
745 self.reporter.reportNote("Instance is not plottable");
746 try:
747 self.library.findType('plt_plot_integer')
748 self.reporter.reportNote("Located plt_plot_integer via Library::findType")
749 except RuntimeError, e:
750 self.reporter.reportNote("In right-click... "+str(e))
751 print "Library contains %d modules." % len(self.library.getModules())
752 for _m in self.library.getModules():
753 print "Module %s:", _m.getName()
754 for _t in self.library.getModuleTypes(_m):
755 print " %s", _t.getName()
756
757 self.plotmenuitem.hide()
758
759 if _canpop:
760 self.treeview.grab_focus()
761 self.treeview.set_cursor( _path, _col, 0)
762 self.treecontext.popup( None, None, None, event.button, _time)
763 return 1
764 else:
765 self.reporter.reportNote("No right-click options available here");
766 else:
767 self.reporter.reportError("Invalid selection for right-click")
768
769 def fix_activate(self,widget):
770 _path,_col = self.treeview.get_cursor()
771 _name, _instance = self.otank[_path]
772 _instance.setFixed(True)
773 self.reporter.reportNote("Fixed variable %s" % _instance.getName().toString())
774 if self.autotoggle.get_active():
775 self.sim.check()
776 self.do_solve()
777 else:
778 self.refreshtree()
779 return 1
780
781 def free_activate(self,widget):
782 _path,_col = self.treeview.get_cursor()
783 _instance = self.otank[_path][1]
784 _instance.setFixed(False)
785 self.reporter.reportNote("Freed variable %s" % _instance.getName().toString())
786 if self.autotoggle.get_active():
787 self.sim.check()
788 self.do_solve()
789 else:
790 self.refreshtree()
791 return 1
792
793 def plot_activate(self,widget):
794 self.reporter.reportNote("plot_activate...");
795 _path,_col = self.treeview.get_cursor()
796 _instance = self.otank[_path][1]
797 if not _instance.isPlottable():
798 self.reporter.reportError("Can't plot instance %s" % _instance.getName().toString())
799 return
800 else:
801 self.reporter.reportNote("Instance %s about to be plotted..." % _instance.getName().toString())
802
803 print("Plotting instance '%s'..." % _instance.getName().toString())
804
805 _plot = _instance.getPlot()
806
807 print "Title: ", _plot.getTitle()
808 _plot.show()
809
810 return 1
811
812
813
814 # ---------------------------------
815 # WINDOW-LEVEL ACTIONS
816
817 def delete_event(self, widget, event, data=None):
818 self.reporter.clearPythonErrorCallback()
819 _w,_h = self.window.get_size()
820 _t,_l = self.window.get_position()
821 _display = self.window.get_screen().get_display().get_name()
822 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
823
824 _p = self.browserpaned.get_position()
825 self.prefs.setGeometryValue(_display,"browserpaned",_p);
826
827 # causes prefs to be saved unless they are still being used elsewher
828 del(self.prefs)
829
830 gtk.main_quit()
831 print "GTK QUIT"
832 return False
833
834 def test():
835 import ascend
836 b = Browser();
837 b.run()
838
839 if __name__ == "__main__":
840 test()

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22