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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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