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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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