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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 177 - (hide annotations) (download) (as text)
Tue Jan 10 06:57:34 2006 UTC (13 years, 10 months ago) by johnpye
File MIME type: text/x-python
File size: 24924 byte(s)
Removing some debug output, attempting to stop closing the figure from closing ASCEND
1 johnpye 132 #!/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 johnpye 160 parser.add_option("-m", "--model"
40     ,action="store", type="string", dest="model"
41     ,help="specify the model to instantiate upon loading modules")
42 johnpye 132 (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 johnpye 172
67 johnpye 173 _display = self.window.get_screen().get_display().get_name();
68     _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
69 johnpye 172 if _geom:
70     self.window.resize(_geom[0],_geom[1]);
71     self.window.move(_geom[2],_geom[3]);
72 johnpye 173
73 johnpye 132 self.window.connect("delete_event", self.delete_event)
74    
75 johnpye 173 self.browserpaned=glade.get_widget("browserpaned");
76     _geom2=self.prefs.getGeometryValue(_display,"browserpaned");
77     if _geom2:
78     self.browserpaned.set_position(_geom2);
79    
80 johnpye 132 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 johnpye 164 self.statusbar = glade.get_widget("statusbar")
103    
104 johnpye 132 #-------------------
105 johnpye 164 # 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 johnpye 132 # 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 johnpye 172 self.plotmenuitem = gtk.MenuItem("Plot");
132 johnpye 132 self.fixmenuitem.show()
133     self.freemenuitem.show()
134 johnpye 172 self.plotmenuitem.show()
135 johnpye 132 self.treecontext.append(self.fixmenuitem);
136     self.treecontext.append(self.freemenuitem);
137 johnpye 172 self.treecontext.append(self.plotmenuitem);
138 johnpye 132 self.fixmenuitem.connect("activate",self.fix_activate)
139     self.freemenuitem.connect("activate",self.free_activate)
140 johnpye 175 self.plotmenuitem.connect("activate",self.plot_activate)
141 johnpye 132 if not self.treecontext:
142     raise RuntimeError("Couldn't create browsercontext")
143     #--------------------
144     # set up the error view
145    
146 johnpye 168 self.errorview = glade.get_widget("errorview")
147 johnpye 132 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 johnpye 164 _context = self.statusbar.get_context_id("do_open")
268    
269 johnpye 132 self.errorstore.clear()
270    
271     self.treestore.clear()
272     self.otank = {}
273    
274 johnpye 175 # self.library.clear()
275 johnpye 164
276     self.statusbar.push(_context,"Loading '"+filename+"'")
277 johnpye 132 self.library.load(filename)
278 johnpye 164 self.statusbar.pop(_context)
279 johnpye 132
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 johnpye 164
303 johnpye 168 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
304     # for details on how the 'wait cursor' is done.
305 johnpye 164 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 johnpye 132
315 johnpye 164 def stop_waiting(self):
316     if self.waitwin:
317     self.statusbar.pop(self.waitcontext)
318     self.waitwin.hide()
319    
320 johnpye 132 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 johnpye 164 self.start_waiting("Compiling...")
326    
327 johnpye 132 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim")
328     print "...DONE 'getSimulation'"
329 johnpye 164 self.stop_waiting()
330 johnpye 132
331 johnpye 164 self.start_waiting("Building simulation...")
332 johnpye 132 print "BUILDING SIMULATION"
333 johnpye 164 self.sim.build()
334 johnpye 132 print "DONE BUILDING"
335 johnpye 164 self.stop_waiting()
336 johnpye 132
337     # empty things out first
338     self.methodstore.clear()
339     self.treestore.clear()
340    
341     # methods
342     _methods = self.sim.getType().getMethods()
343 johnpye 160 _activemethod = None;
344 johnpye 132 for _m in _methods:
345 johnpye 160 _i = self.methodstore.append([_m.getName()])
346     if _m.getName()=="default_self":
347     self.methodsel.set_active_iter(_i)
348 johnpye 132
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 johnpye 171 return;
358 johnpye 132
359 johnpye 168 self.start_waiting("Solving...")
360 johnpye 164
361 johnpye 154 self.sim.solve(ascend.Solver("QRSlv"))
362 johnpye 164
363 johnpye 168 self.stop_waiting()
364 johnpye 132 self.refreshtree()
365    
366     def do_check(self):
367     if not self.sim:
368     self.reporter.reportError("No model selected yet")
369    
370 johnpye 171 self.start_waiting("Checking system...")
371    
372 johnpye 132 if self.sim.check():
373     self.reporter.reportNote("System check OK")
374 johnpye 171
375 johnpye 132 self.sim.checkDoF()
376    
377 johnpye 171 self.stop_waiting()
378    
379 johnpye 132 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 johnpye 160 else:
626     self.treeview.expand_row("0",False)
627 johnpye 132
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 johnpye 160 None,
648     gtk.FILE_CHOOSER_ACTION_OPEN,
649     (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
650     gtk.STOCK_OPEN, gtk.RESPONSE_OK))
651 johnpye 132 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 johnpye 168 self.reporter.reportSuccess("Auto mode is now ON")
710 johnpye 132 else:
711 johnpye 168 self.reporter.reportSuccess("Auto mode is now OFF")
712 johnpye 132
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 johnpye 172 _canpop = False;
725 johnpye 132 _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 johnpye 172 _canpop = True;
730 johnpye 132 if _instance.isFixed():
731     self.fixmenuitem.hide()
732     self.freemenuitem.show()
733     else:
734     self.fixmenuitem.show()
735     self.freemenuitem.hide()
736 johnpye 175 else:
737     self.fixmenuitem.hide()
738     self.freemenuitem.hide()
739 johnpye 172
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 johnpye 175 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 johnpye 172 self.plotmenuitem.hide()
758    
759     if _canpop:
760     self.treeview.grab_focus()
761     self.treeview.set_cursor( _path, _col, 0)
762 johnpye 132 self.treecontext.popup( None, None, None, event.button, _time)
763     return 1
764 johnpye 172 else:
765     self.reporter.reportNote("No right-click options available here");
766 johnpye 132 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 johnpye 172 def plot_activate(self,widget):
794 johnpye 175 self.reporter.reportNote("plot_activate...");
795 johnpye 172 _path,_col = self.treeview.get_cursor()
796     _instance = self.otank[_path][1]
797     if not _instance.isPlottable():
798 johnpye 175 self.reporter.reportError("Can't plot instance %s" % _instance.getName().toString())
799 johnpye 172 return
800 johnpye 175 else:
801     self.reporter.reportNote("Instance %s about to be plotted..." % _instance.getName().toString())
802 johnpye 172
803 johnpye 175 print("Plotting instance '%s'..." % _instance.getName().toString())
804    
805 johnpye 176 _plot = _instance.getPlot()
806 johnpye 175
807 johnpye 176 print "Title: ", _plot.getTitle()
808 johnpye 177 _plot.show(False)
809 johnpye 176
810 johnpye 172 return 1
811    
812    
813    
814 johnpye 132 # ---------------------------------
815     # WINDOW-LEVEL ACTIONS
816    
817     def delete_event(self, widget, event, data=None):
818     self.reporter.clearPythonErrorCallback()
819 johnpye 172 _w,_h = self.window.get_size()
820     _t,_l = self.window.get_position()
821 johnpye 173 _display = self.window.get_screen().get_display().get_name()
822     self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
823 johnpye 132
824 johnpye 173 _p = self.browserpaned.get_position()
825     self.prefs.setGeometryValue(_display,"browserpaned",_p);
826    
827 johnpye 132 # 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