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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 459 - (hide annotations) (download) (as text)
Fri Apr 7 08:05:05 2006 UTC (16 years, 8 months ago) by johnpye
File MIME type: text/x-python
File size: 34404 byte(s)
Fixing default PackageOption values
Adding --library option to gtkbrowser for ASC_DEVELOPING override of 'models' path.
1 johnpye 132 #!/usr/bin/env python
2    
3 johnpye 361 import sys
4     sys.stderr.write("Loading...\r")
5     sys.stderr.flush()
6    
7 johnpye 279 try:
8     import psyco
9     psyco.full()
10 johnpye 361 print "Running with PSYCO optimisation..."
11 johnpye 279 except ImportError:
12     pass
13    
14 johnpye 132 import pygtk
15     pygtk.require('2.0')
16     import gtk
17     import gtk.glade
18     import pango
19     import re
20 johnpye 230 import preferences # loading/saving of .ini options
21 johnpye 132 import urlparse
22     import optparse
23    
24 johnpye 230 from solverparameters import * # 'solver parameters' window
25 johnpye 268 from help import * # viewing help files
26     from incidencematrix import * # incidence/sparsity matrix matplotlib window
27     from observer import * # observer tab support
28     from properties import * # solver_var properties dialog
29     from varentry import * # for inputting of variables with units
30 johnpye 280 from diagnose import * # for diagnosing block non-convergence
31 johnpye 311 from solverreporter import * # solver status reporting
32 johnpye 338 import config
33 johnpye 311
34 johnpye 361 import platform
35     if platform.system() != "Windows":
36     import sys, dl
37     # This sets the flags for dlopen used by python so that the symbols in the
38     # ascend library are made available to libraries dlopened within ASCEND:
39     sys.setdlopenflags(dl.RTLD_GLOBAL|dl.RTLD_NOW)
40    
41 johnpye 132 import ascend
42    
43     # This is my first ever GUI code so please be nice :)
44 johnpye 361 # But I *have* at least read
45     # http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html
46     # and leafed through
47     # http://developer.gnome.org/projects/gup/hig/
48 johnpye 132
49     # The fancy tree-view gizmo is the GtkTreeView object. See the article
50     # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/300304
51     # for the original source code on which my implementation was based.
52    
53 johnpye 307 VERSION = "0.9.6-dev"
54    
55 johnpye 227 ESCAPE_KEY = 65307
56    
57 johnpye 230 HELP_ROOT = None
58    
59 johnpye 255 BROWSER_FIXED_COLOR = "#008800"
60     BROWSER_FREE_COLOR = "#000088"
61 johnpye 223 #======================================
62     # Browser is the main ASCEND library/model browser window
63    
64 johnpye 132 class Browser:
65    
66     # ---------------------------------
67     # SETUP
68    
69     def __init__(self):
70     #--------
71     # load the file referenced in the command line, if any
72    
73     parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
74     # add options here if we want
75    
76 johnpye 160 parser.add_option("-m", "--model"
77 johnpye 341 ,action="store", type="string", dest="model"
78 johnpye 160 ,help="specify the model to instantiate upon loading modules")
79 johnpye 436
80     parser.add_option("--pygtk-assets"
81 johnpye 455 ,action="store", type="string", dest="assets_dir"
82 johnpye 436 ,help="override the configuration value for the location of assets"\
83     +" required by PyGTK for the ASCEND GUI, optional"
84     ,default=config.PYGTK_ASSETS
85     )
86    
87 johnpye 459 parser.add_option("--library"
88     ,action="store", type="string", dest="library_path"
89     ,help="overried the configuration value for the library path"
90     ,default=config.LIBRARY_PATH
91     )
92    
93 johnpye 132 (options, args) = parser.parse_args()
94    
95     #print "OPTIONS_______________:",options
96    
97 johnpye 246 self.observers = []
98 johnpye 251 self.clip = None
99 johnpye 246
100 johnpye 132 #--------
101     # load up the preferences ini file
102    
103     self.prefs = preferences.Preferences()
104    
105     #--------
106     # initialise ASCEND
107    
108 johnpye 455 self.assets_dir = options.assets_dir
109    
110 johnpye 356 _prefpath = self.prefs.getStringPref("Directories","librarypath",None)
111    
112     if _prefpath:
113     _path = _prefpath
114     print "SETTING ASCENDLIBRARY from preferences:",_path
115     self.library = ascend.Library(_prefpath)
116     else:
117 johnpye 459 options.library_path
118     print "PYTHON SAYS DEFAULT LIBRARY IS",options.library_path
119 johnpye 356 print "WE WILL LET THE ENGINE DECIDE..."
120 johnpye 459 self.library = ascend.Library(options.library_path)
121 johnpye 132
122     self.sim = None
123    
124 johnpye 351 #--------
125     # Prepare the ASCEND icon
126    
127 johnpye 455 if config.ICON_EXTENSION:
128 johnpye 351 _icon = gtk.Image()
129 johnpye 455 _iconpath = self.assets_dir+'ascend'+config.ICON_EXTENSION
130     _icon.set_from_file(_iconpath)
131 johnpye 351 self.icon = _icon.get_pixbuf()
132    
133 johnpye 132 #-------------------
134     # Set up the window and main widget actions
135    
136 johnpye 455 self.glade_file = self.assets_dir+config.GLADE_FILE
137 johnpye 436 glade = gtk.glade.XML(self.glade_file,"browserwin")
138 johnpye 132
139     self.window = glade.get_widget("browserwin")
140 johnpye 351 if self.icon:
141     self.window.set_icon(self.icon)
142 johnpye 208
143 johnpye 132 if not self.window:
144     raise RuntimeError("Couldn't load window from glade file")
145 johnpye 172
146 johnpye 294 _display = self.window.get_screen().get_display().get_name()
147 johnpye 173 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
148 johnpye 172 if _geom:
149 johnpye 294 self.window.resize(_geom[0],_geom[1])
150     self.window.move(_geom[2],_geom[3])
151 johnpye 173
152 johnpye 132 self.window.connect("delete_event", self.delete_event)
153    
154 johnpye 294 self.browserpaned=glade.get_widget("browserpaned")
155     _geom2=self.prefs.getGeometryValue(_display,"browserpaned")
156 johnpye 173 if _geom2:
157 johnpye 294 self.browserpaned.set_position(_geom2)
158 johnpye 173
159 johnpye 132 self.openbutton=glade.get_widget("openbutton")
160     self.openbutton.connect("clicked",self.open_click)
161    
162     self.reloadbutton=glade.get_widget("reloadbutton")
163     self.reloadbutton.connect("clicked",self.reload_click)
164    
165     self.solvebutton=glade.get_widget("solvebutton")
166     self.solvebutton.connect("clicked",self.solve_click)
167    
168     self.checkbutton=glade.get_widget("checkbutton")
169     self.checkbutton.connect("clicked",self.check_click)
170    
171     self.autotoggle=glade.get_widget("autotoggle")
172     self.autotoggle.connect("toggled",self.auto_toggle)
173    
174 johnpye 230 self.is_auto = self.autotoggle.get_active()
175    
176 johnpye 132 self.methodrunbutton=glade.get_widget("methodrunbutton")
177     self.methodrunbutton.connect("clicked",self.methodrun_click)
178    
179     self.methodsel=glade.get_widget("methodsel")
180    
181     self.maintabs = glade.get_widget("maintabs")
182    
183 johnpye 164 self.statusbar = glade.get_widget("statusbar")
184    
185 johnpye 208 self.menu = glade.get_widget("browsermenu")
186     glade.signal_autoconnect(self)
187    
188 johnpye 230 self.automenu = glade.get_widget("automenu")
189     self.automenu.set_active(self.is_auto)
190     if self.automenu == None:
191     print "NO AUTOMENU FOUND"
192    
193 johnpye 321 self.show_solving_popup=glade.get_widget("show_solving_popup")
194     self.show_solving_popup.set_active(self.prefs.getBoolPref("SolverReporter","show_popup",True))
195     self.close_on_converged=glade.get_widget("close_on_converged")
196     self.close_on_converged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_converged",True))
197     self.close_on_nonconverged=glade.get_widget("close_on_nonconverged")
198     self.close_on_nonconverged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_nonconverged",True))
199 johnpye 132 #-------------------
200 johnpye 164 # waitwin
201    
202     self.waitwin = gtk.gdk.Window(self.window.window,
203     gtk.gdk.screen_width(),
204     gtk.gdk.screen_height(),
205     gtk.gdk.WINDOW_CHILD,
206     0,
207     gtk.gdk.INPUT_ONLY)
208    
209     _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
210     self.waitwin.set_cursor(_cursor)
211    
212     #-------------------
213 johnpye 132 # pixbufs to be used in the error listing
214    
215     self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
216     self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
217     self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
218     self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
219    
220     #--------------------
221 johnpye 255 # pixbufs for solver_var status
222    
223 johnpye 268 self.fixedimg = gtk.Image()
224 johnpye 455 self.fixedimg.set_from_file(options.assets_dir+'locked.png')
225 johnpye 268
226 johnpye 258 self.iconstatusunknown = None
227 johnpye 268 self.iconfixed = self.fixedimg.get_pixbuf()
228 johnpye 255 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
229 johnpye 258 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
230 johnpye 255 self.iconunsolved = None
231    
232     self.statusicons={
233     ascend.ASCXX_VAR_STATUS_UNKNOWN: self.iconstatusunknown
234 johnpye 258 ,ascend.ASCXX_VAR_FIXED: self.iconfixed
235 johnpye 255 ,ascend.ASCXX_VAR_SOLVED: self.iconsolved
236     ,ascend.ASCXX_VAR_ACTIVE: self.iconactive
237     ,ascend.ASCXX_VAR_UNSOLVED: self.iconunsolved
238     }
239 johnpye 273 self.statusmessages={
240     ascend.ASCXX_VAR_STATUS_UNKNOWN: "Status unknown"
241     ,ascend.ASCXX_VAR_FIXED: "Fixed"
242     ,ascend.ASCXX_VAR_SOLVED: "Converged"
243     ,ascend.ASCXX_VAR_ACTIVE: "Active (unconverged)"
244     ,ascend.ASCXX_VAR_UNSOLVED: "Not yet visited"
245     }
246 johnpye 255
247     #--------------------
248 johnpye 132 # set up the context menu for fixing/freeing vars
249    
250 johnpye 226 # TODO import this menu from Glade (this code is a PITA)
251    
252 johnpye 132 self.treecontext = gtk.Menu();
253 johnpye 181 self.fixmenuitem = gtk.ImageMenuItem("_Fix",True);
254 johnpye 268 self.fixmenuitem.set_image(self.fixedimg)
255 johnpye 181
256     self.freemenuitem = gtk.ImageMenuItem("F_ree",True);
257     _img = gtk.Image()
258 johnpye 455 _img.set_from_file(options.assets_dir+'unlocked.png')
259 johnpye 181 self.freemenuitem.set_image(_img)
260    
261     self.plotmenuitem = gtk.ImageMenuItem("P_lot",True);
262     _img = gtk.Image()
263 johnpye 455 _img.set_from_file(options.assets_dir+'plot.png')
264 johnpye 181 self.plotmenuitem.set_image(_img)
265    
266     self.propsmenuitem = gtk.ImageMenuItem("_Properties",True);
267     _img = gtk.Image()
268 johnpye 455 _img.set_from_file(options.assets_dir+'properties.png')
269 johnpye 181 self.propsmenuitem.set_image(_img)
270    
271 johnpye 246 self.observemenuitem = gtk.ImageMenuItem("_Observe",True);
272     _img = gtk.Image()
273 johnpye 455 _img.set_from_file(options.assets_dir+'observe.png')
274 johnpye 246 self.observemenuitem.set_image(_img)
275    
276 johnpye 207 self.fixmenuitem.show(); self.fixmenuitem.set_sensitive(False)
277     self.freemenuitem.show(); self.freemenuitem.set_sensitive(False)
278     self.plotmenuitem.show(); self.plotmenuitem.set_sensitive(False)
279 johnpye 246 self.observemenuitem.show(); self.observemenuitem.set_sensitive(False)
280 johnpye 181 self.propsmenuitem.show()
281 johnpye 246 self.treecontext.append(self.fixmenuitem)
282     self.treecontext.append(self.freemenuitem)
283 johnpye 181 _sep = gtk.SeparatorMenuItem(); _sep.show()
284     self.treecontext.append(_sep);
285 johnpye 246 self.treecontext.append(self.plotmenuitem)
286     self.treecontext.append(self.observemenuitem)
287 johnpye 181 _sep = gtk.SeparatorMenuItem(); _sep.show()
288 johnpye 246 self.treecontext.append(_sep)
289     self.treecontext.append(self.propsmenuitem)
290 johnpye 132 self.fixmenuitem.connect("activate",self.fix_activate)
291     self.freemenuitem.connect("activate",self.free_activate)
292 johnpye 175 self.plotmenuitem.connect("activate",self.plot_activate)
293 johnpye 181 self.propsmenuitem.connect("activate",self.props_activate)
294 johnpye 246 self.observemenuitem.connect("activate",self.observe_activate)
295    
296 johnpye 132 if not self.treecontext:
297     raise RuntimeError("Couldn't create browsercontext")
298     #--------------------
299     # set up the error view
300    
301 johnpye 168 self.errorview = glade.get_widget("errorview")
302 johnpye 132 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
303     self.errorstore = gtk.TreeStore(*errstorecolstypes)
304     errtitles = ["","Location","Message"];
305     self.errorview.set_model(self.errorstore)
306     self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
307    
308     i = 0
309     for tvcolumn in self.errcols[:len(errtitles)]:
310     tvcolumn.set_title(errtitles[i])
311     self.errorview.append_column(tvcolumn)
312    
313     if i>0:
314     _renderer = gtk.CellRendererText()
315     tvcolumn.pack_start(_renderer, True)
316     tvcolumn.add_attribute(_renderer, 'text', i)
317     if(i==2):
318     tvcolumn.add_attribute(_renderer, 'foreground', 3)
319     tvcolumn.add_attribute(_renderer, 'weight', 4)
320     else:
321     _renderer1 = gtk.CellRendererPixbuf()
322     tvcolumn.pack_start(_renderer1, False)
323     tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
324    
325     i = i + 1
326    
327    
328     #--------------------
329     # set up the error reporter callback
330     self.reporter = ascend.getReporter()
331     self.reporter.setPythonErrorCallback(self.error_callback)
332    
333     #-------------------
334     # set up the module view
335    
336     self.modtank = {}
337     self.moduleview = glade.get_widget("moduleview")
338 johnpye 355 modulestorecoltypes = [str, str, int] # bool=can-be-instantiated
339 johnpye 132 self.modulestore = gtk.TreeStore(*modulestorecoltypes)
340     moduleviewtitles = ["Module name", "Filename"]
341     self.moduleview.set_model(self.modulestore)
342     self.modcols = [ gtk.TreeViewColumn() for _type in modulestorecoltypes]
343     i = 0
344     for modcol in self.modcols[:len(moduleviewtitles)]:
345     modcol.set_title(moduleviewtitles[i])
346     self.moduleview.append_column(modcol)
347     _renderer = gtk.CellRendererText()
348     modcol.pack_start(_renderer, True)
349     modcol.add_attribute(_renderer, 'text', i)
350 johnpye 355 modcol.add_attribute(_renderer,'weight',2)
351 johnpye 132 i = i + 1
352     self.moduleview.connect("row-activated", self.module_activated )
353    
354     #--------------------
355     # set up the methods combobox
356    
357     self.methodstore = gtk.ListStore(str)
358     self.methodsel.set_model(self.methodstore)
359     _methodrenderer = gtk.CellRendererText()
360     self.methodsel.pack_start(_methodrenderer, True)
361     self.methodsel.add_attribute(_methodrenderer, 'text',0)
362    
363     #--------
364     # set up the instance browser view
365    
366     self.otank = {}
367     self.treeview = glade.get_widget("browserview")
368 johnpye 255
369     # name, type, value, foreground, weight, editable, status-icon
370     columns = [str,str,str,str,int,bool,gtk.gdk.Pixbuf]
371 johnpye 132 self.treestore = gtk.TreeStore(*columns)
372     titles = ["Name","Type","Value"];
373     self.treeview.set_model(self.treestore)
374     self.tvcolumns = [ gtk.TreeViewColumn() for _type in columns[:len(titles)] ]
375    
376     self.treeview.connect("row-expanded", self.row_expanded )
377 johnpye 270 self.treeview.connect("button-press-event", self.on_treeview_event )
378     self.treeview.connect("key-press-event",self.on_treeview_event )
379 johnpye 132
380     # data columns are: name type value colour weight editable
381    
382     i = 0
383     for tvcolumn in self.tvcolumns[:len(titles)]:
384     tvcolumn.set_title(titles[i])
385     self.treeview.append_column(tvcolumn)
386    
387 johnpye 255 if(i==2):
388     # add status icon
389     renderer1 = gtk.CellRendererPixbuf()
390 johnpye 258 tvcolumn.pack_start(renderer1, False)
391 johnpye 255 tvcolumn.add_attribute(renderer1, 'pixbuf', 6)
392    
393 johnpye 132 renderer = gtk.CellRendererText()
394     tvcolumn.pack_start(renderer, True)
395     tvcolumn.add_attribute(renderer, 'text', i)
396     tvcolumn.add_attribute(renderer, 'foreground', 3)
397     tvcolumn.add_attribute(renderer, 'weight', 4)
398     if(i==2):
399     tvcolumn.add_attribute(renderer, 'editable', 5)
400     renderer.connect('edited',self.cell_edited_callback)
401     i = i + 1
402    
403    
404     if(len(args)==1):
405     self.do_open(args[0])
406    
407     print "Options: ",options
408    
409     if options.model:
410     try:
411     _t =self.library.findType(options.model);
412     self.do_sim(_t);
413     except RuntimeError, e:
414     self.reporter.reportError("Failed to create instance of '%s': %s" %(options.model, str(e)));
415    
416 johnpye 223
417 johnpye 132 def run(self):
418     self.window.show()
419     gtk.main()
420    
421     # --------------------------------------------
422     # MAJOR GUI COMMANDS
423    
424    
425     def do_open(self,filename):
426     # TODO does the user want to lose their work?
427     # TODO do we need to chdir?
428    
429 johnpye 164 _context = self.statusbar.get_context_id("do_open")
430    
431 johnpye 132 self.errorstore.clear()
432    
433     self.treestore.clear()
434     self.otank = {}
435    
436 johnpye 175 # self.library.clear()
437 johnpye 164
438     self.statusbar.push(_context,"Loading '"+filename+"'")
439 johnpye 132 self.library.load(filename)
440 johnpye 164 self.statusbar.pop(_context)
441 johnpye 132
442     self.filename = filename
443    
444     # Load the current list of modules into self.modules
445     self.modtank = {}
446     self.modulestore.clear()
447     modules = self.library.getModules()
448 johnpye 338 self.library.listModules()
449     try:
450     _lll=len(modules)
451     except:
452     _msg = "UNABLE TO ACCESS MODULES LIST. This is bad.\n"+\
453     "Check your SWIG configuration (check for warnings during build)."+\
454     "\nThis is a known problem with the MinGW build at present."
455    
456     self.reporter.reportError(_msg)
457     raise RuntimeError(_msg)
458    
459 johnpye 132 for m in reversed(modules):
460     _n = str( m.getName() )
461     _f = str( m.getFilename() )
462     #print "ADDING ROW name %s, file = %s" % (_n, _f)
463 johnpye 355 _r = self.modulestore.append(None, [ _n, _f, pango.WEIGHT_NORMAL ])
464 johnpye 132 for t in self.library.getModuleTypes(m):
465     _n = t.getName()
466 johnpye 355 _hasparams = t.hasParameters()
467     if _hasparams:
468     _w = pango.WEIGHT_NORMAL
469     else:
470     _w = pango.WEIGHT_BOLD
471    
472 johnpye 132 #print "ADDING TYPE %s" % _n
473 johnpye 355 _piter = self.modulestore.append(_r , [ _n, "", _w ])
474 johnpye 132 _path = self.modulestore.get_path(_piter)
475     self.modtank[_path]=t
476    
477     #print "DONE ADDING MODULES"
478    
479     self.sim = None;
480     self.maintabs.set_current_page(0);
481 johnpye 164
482 johnpye 168 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
483     # for details on how the 'wait cursor' is done.
484 johnpye 164 def start_waiting(self, message):
485     self.waitcontext = self.statusbar.get_context_id("waiting")
486     self.statusbar.push(self.waitcontext,message)
487    
488     if self.waitwin:
489     self.waitwin.show()
490    
491     while gtk.events_pending():
492     gtk.main_iteration()
493 johnpye 132
494 johnpye 164 def stop_waiting(self):
495     if self.waitwin:
496     self.statusbar.pop(self.waitcontext)
497     self.waitwin.hide()
498    
499 johnpye 132 def do_sim(self, type_object):
500     self.sim = None;
501     # TODO: clear out old simulation first!
502    
503     print "DO_SIM(%s)" % str(type_object.getName())
504 johnpye 164 self.start_waiting("Compiling...")
505    
506 johnpye 277 try:
507     self.sim = type_object.getSimulation(str(type_object.getName())+"_sim")
508     except RuntimeError, e:
509     self.stop_waiting()
510     self.reporter.reportError(str(e))
511     return
512    
513 johnpye 132 print "...DONE 'getSimulation'"
514 johnpye 164 self.stop_waiting()
515 johnpye 132
516 johnpye 164 self.start_waiting("Building simulation...")
517 johnpye 132 print "BUILDING SIMULATION"
518 johnpye 277
519     try:
520     self.sim.build()
521     except RuntimeError, e:
522     self.stop_waiting()
523     self.reporter.reportError(str(e))
524     return;
525    
526 johnpye 132 print "DONE BUILDING"
527 johnpye 164 self.stop_waiting()
528 johnpye 132
529 johnpye 223 self.sim.setSolver(ascend.Solver("QRSlv"))
530    
531 johnpye 132 # empty things out first
532     self.methodstore.clear()
533     self.treestore.clear()
534    
535     # methods
536     _methods = self.sim.getType().getMethods()
537 johnpye 160 _activemethod = None;
538 johnpye 132 for _m in _methods:
539 johnpye 160 _i = self.methodstore.append([_m.getName()])
540     if _m.getName()=="default_self":
541     self.methodsel.set_active_iter(_i)
542 johnpye 132
543     # instance hierarchy
544     self.otank = {} # map path -> (name,value)
545     self.make( self.sim.getName(),self.sim.getModel() )
546     self.maintabs.set_current_page(1);
547 johnpye 249
548     def do_solve_if_auto(self):
549     if self.is_auto:
550     self.sim.check()
551     self.do_solve()
552     else:
553 johnpye 255 self.sim.processVarStatus()
554 johnpye 249 self.refreshtree()
555    
556     self.sync_observers()
557 johnpye 132
558     def do_solve(self):
559     if not self.sim:
560     self.reporter.reportError("No model selected yet")
561 johnpye 171 return;
562 johnpye 132
563 johnpye 168 self.start_waiting("Solving...")
564 johnpye 164
565 johnpye 321 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
566 johnpye 351 reporter = PopupSolverReporter(self,self.sim.getNumVars())
567 johnpye 321 else:
568     reporter = SimpleSolverReporter(self)
569    
570 johnpye 313 self.sim.solve(ascend.Solver("QRSlv"),reporter)
571 johnpye 164
572 johnpye 168 self.stop_waiting()
573 johnpye 255
574     self.sim.processVarStatus()
575 johnpye 132 self.refreshtree()
576    
577     def do_check(self):
578     if not self.sim:
579     self.reporter.reportError("No model selected yet")
580    
581 johnpye 171 self.start_waiting("Checking system...")
582    
583 johnpye 278 try:
584     if self.sim.check():
585     self.reporter.reportNote("System check OK")
586     self.sim.checkDoF()
587     except RuntimeError, e:
588     self.stop_waiting()
589     self.reporter.reportError(str(e))
590     return
591 johnpye 171
592     self.stop_waiting()
593    
594 johnpye 132 self.refreshtree()
595    
596     def do_method(self,method):
597     if not self.sim:
598     self.reporter.reportError("No model selected yet")
599    
600     self.sim.run(method)
601     self.refreshtree()
602    
603 johnpye 230 def do_quit(self):
604     self.reporter.clearPythonErrorCallback()
605     _w,_h = self.window.get_size()
606     _t,_l = self.window.get_position()
607     _display = self.window.get_screen().get_display().get_name()
608     self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
609    
610     _p = self.browserpaned.get_position()
611     self.prefs.setGeometryValue(_display,"browserpaned",_p);
612    
613     # causes prefs to be saved unless they are still being used elsewher
614     del(self.prefs)
615    
616     gtk.main_quit()
617     print "GTK QUIT"
618     return False
619    
620 johnpye 231 def on_tools_sparsity_click(self,*args):
621 johnpye 237
622     self.reporter.reportNote("Preparing incidence matrix...")
623 johnpye 233 _im = self.sim.getIncidenceMatrix();
624 johnpye 231
625 johnpye 237 self.reporter.reportNote("Plotting incidence matrix...")
626 johnpye 234
627 johnpye 237 _sp = IncidenceMatrixWindow(_im);
628     _sp.run();
629    
630 johnpye 280 def on_diagnose_blocks_click(self,*args):
631 johnpye 285 try:
632     _bl = self.sim.getActiveBlock()
633     except RuntimeError, e:
634     self.reporter.reportError(str(e))
635     return
636 johnpye 351 _db = DiagnoseWindow(self,_bl)
637 johnpye 280 _db.run();
638    
639 johnpye 245 def on_add_observer_click(self,*args):
640 johnpye 361 if len(self.observers) > 0:
641 johnpye 246 self.reporter.reportError("Not supported: multiple observers")
642     return
643 johnpye 361 self.create_observer()
644 johnpye 245
645 johnpye 250 def on_keep_observed_click(self,*args):
646     if len(self.observers) > 1:
647     self.reporter.reportError("Not supported: multiple observers")
648     return
649     if len(self.observers) <= 0:
650     self.reporter.reportError("No observer defined!")
651     return
652     self.observers[0].do_add_row()
653    
654     def on_copy_observer_matrix_click(self,*args):
655 johnpye 251 if self.clip == None:
656     self.clip = gtk.Clipboard()
657    
658 johnpye 250 if len(self.observers) > 1:
659     self.reporter.reportError("Not supported: multiple observers")
660     return
661     if len(self.observers) <= 0:
662     self.reporter.reportError("No observer defined!")
663     return
664 johnpye 251 self.observers[0].copy_to_clipboard(self.clip)
665 johnpye 270
666 johnpye 299 def on_fix_variable_activate(self,*args):
667     _path,_col = self.treeview.get_cursor()
668     _instance = self.otank[_path][1]
669     self.set_fixed(_instance,True)
670    
671     def on_free_variable_activate(self,*args):
672     _path,_col = self.treeview.get_cursor()
673     _instance = self.otank[_path][1]
674     self.set_fixed(_instance,False)
675    
676     def set_fixed(self,instance,val):
677     if instance.getType().isRefinedSolverVar():
678     f = instance.isFixed();
679     if (f and not val) or (not f and val):
680     instance.setFixed(val)
681 johnpye 321 self.do_solve_if_auto()
682 johnpye 299
683 johnpye 321 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
684     _v = checkmenuitem.get_active()
685     self.prefs.setBoolPref("SolverReporter","show_popup",_v)
686     print "SET TO",_v
687    
688     def on_close_on_converged_toggle(self,checkmenuitem,*args):
689     _v = checkmenuitem.get_active()
690     self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
691    
692     def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
693     _v = checkmenuitem.get_active()
694     self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
695    
696 johnpye 328 def on_show_variables_near_bounds_activate(self,*args):
697     _epsilon = 1e-4;
698     _vars = self.sim.getVariablesNearBounds(_epsilon)
699     print "VARIABLES NEAR BOUNDS"
700     for _v in _vars:
701     print _v.getName();
702    
703 johnpye 132 # --------------------------------------------
704     # MODULE LIST
705    
706     def module_activated(self, treeview, path, column, *args):
707     modules = self.library.getModules()
708     print "PATH",path
709     if len(path)==1:
710     self.reporter.reportNote("Launching of external editor not yet implemented")
711     elif len(path)==2:
712     if(self.modtank.has_key(path)):
713     _type = self.modtank[path];
714     self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
715     self.do_sim(_type)
716     else:
717     self.reporter.reportError("Didn't find type corresponding to row")
718    
719     # --------------------------------------------
720     # INSTANCE TREE
721    
722 johnpye 255 def get_tree_row_data(self,instance): # for instance browser
723 johnpye 132 _value = str(instance.getValue())
724     _type = str(instance.getType())
725     _name = str(instance.getName())
726     _fgcolor = "black"
727     _fontweight = pango.WEIGHT_NORMAL
728     _editable = False
729 johnpye 273 _statusicon = None
730 johnpye 132 if instance.getType().isRefinedSolverVar():
731     _editable = True
732 johnpye 255 _fontweight = pango.WEIGHT_BOLD
733 johnpye 132 if instance.isFixed():
734 johnpye 255 _fgcolor = BROWSER_FIXED_COLOR
735 johnpye 132 else:
736 johnpye 255 _fgcolor = BROWSER_FREE_COLOR
737 johnpye 132 _fontweight = pango.WEIGHT_BOLD
738 johnpye 273 _status = instance.getVarStatus();
739     _statusicon = self.statusicons[_status]
740    
741 johnpye 132 elif instance.isBool() or instance.isReal() or instance.isInt():
742     # TODO can't edit constants that have already been refined
743     _editable = True
744    
745     #if(len(_value) > 80):
746     # _value = _value[:80] + "..."
747    
748 johnpye 255 return [_name, _type, _value, _fgcolor, _fontweight, _editable, _statusicon]
749 johnpye 132
750 johnpye 255 def make_row( self, piter, name, value ): # for instance browser
751 johnpye 132
752     _piter = self.treestore.append( piter, self.get_tree_row_data(value) )
753     return _piter
754    
755     def refreshtree(self):
756     # @TODO FIXME use a better system than colour literals!
757     for _path in self.otank: # { path : (name,value) }
758     _iter = self.treestore.get_iter(_path)
759     _name, _instance = self.otank[_path]
760     self.treestore.set_value(_iter, 2, _instance.getValue())
761     if _instance.getType().isRefinedSolverVar():
762 johnpye 255 if _instance.isFixed() and self.treestore.get_value(_iter,3)==BROWSER_FREE_COLOR:
763     self.treestore.set_value(_iter,3,BROWSER_FIXED_COLOR)
764     elif not _instance.isFixed() and self.treestore.get_value(_iter,3)==BROWSER_FIXED_COLOR:
765     self.treestore.set_value(_iter,3,BROWSER_FREE_COLOR)
766 johnpye 273 self.treestore.set_value(_iter, 6, self.statusicons[_instance.getVarStatus()])
767 johnpye 132
768     def cell_edited_callback(self, renderer, path, newtext, **kwargs):
769     # get back the Instance object we just edited (having to use this seems like a bug)
770     path = tuple( map(int,path.split(":")) )
771    
772     if not self.otank.has_key(path):
773     raise RuntimeError("cell_edited_callback: invalid path '%s'" % path)
774     return
775    
776     _name, _instance = self.otank[path]
777    
778     if _instance.isReal():
779     # only real-valued things can have units
780    
781 johnpye 268 _e = RealAtomEntry(_instance,newtext);
782 johnpye 132 try:
783 johnpye 268 _e.checkEntry()
784     _e.setValue()
785     _e.exportPreferredUnits(self.prefs)
786     except InputError, e:
787     self.reporter.reportError(str(e))
788     return;
789 johnpye 132
790     else:
791     if _instance.isBool():
792     _lower = newtext.lower();
793     if _lower.startswith("t") or _lower.startswith("y") or _lower.strip()=="1":
794     newtext = 1
795     elif _lower.startswith("f") or _lower.startswith("n") or _lower.strip()=="0":
796     newtext = 0
797     else:
798     self.reporter.reportError("Invalid entry for a boolean variable: '%s'" % newtext)
799     return
800     _val = bool(newtext);
801     if _val == _instance.getValue():
802     self.reporter.reportNote("Boolean atom '%s' was not altered" % _instance.getName())
803     return
804     _instance.setBoolValue(_val)
805    
806     elif _instance.isInt():
807     _val = int(newtext)
808     if _val == _instance.getValue():
809     self.reporter.reportNote("Integer atom '%s' was not altered" % _instance.getName())
810     return
811     _instance.setIntValue(_val)
812     else:
813     self.reporter.reportError("Attempt to set a non-real, non-boolean, non-integer value!")
814     return
815    
816     # now that the variable is set, update the GUI and re-solve if desired
817     _iter = self.treestore.get_iter(path)
818     self.treestore.set_value(_iter,2,_instance.getValue())
819    
820     if _instance.getType().isRefinedSolverVar():
821 johnpye 255 self.treestore.set_value(_iter,3,BROWSER_FIXED_COLOR) # set the row green as fixed
822 johnpye 132
823 johnpye 249 self.do_solve_if_auto()
824 johnpye 132
825     def make_children(self, value, piter ):
826     if value.isCompound():
827     children=value.getChildren();
828     for child in children:
829     _name = child.getName();
830     _piter = self.make_row(piter,_name,child)
831     _path = self.treestore.get_path(_piter)
832     self.otank[_path]=(_name,child)
833     #self.reporter.reportError("2 Added %s at path %s" % (_name,repr(_path)))
834    
835     def make(self, name=None, value=None, path=None, depth=1):
836     if path is None:
837     # make root node
838     piter = self.make_row( None, name, value )
839     path = self.treestore.get_path( piter )
840     self.otank[ path ] = (name, value)
841     #self.reporter.reportError("4 Added %s at path %s" % (name, path))
842     else:
843     name, value = self.otank[ path ]
844    
845     piter = self.treestore.get_iter( path )
846     if not self.treestore.iter_has_child( piter ):
847     self.make_children(value,piter)
848    
849     if depth:
850     for i in range( self.treestore.iter_n_children( piter ) ):
851     self.make( path = path+(i,), depth = depth - 1 )
852 johnpye 160 else:
853     self.treeview.expand_row("0",False)
854 johnpye 132
855     def row_expanded( self, treeview, piter, path ):
856     self.make( path = path )
857    
858     # ----------------------------------
859     # ERROR PANEL
860    
861 johnpye 255 def get_error_row_data(self,sev,filename,line,msg):
862     _sevicon = {
863     0: self.iconok
864     ,1: self.iconinfo
865     ,2: self.iconwarning
866     ,3: self.iconerror
867     ,4: self.iconinfo
868     ,5: self.iconwarning
869     ,6: self.iconerror
870     }[sev]
871    
872     _fontweight = pango.WEIGHT_NORMAL
873     if sev==6:
874     _fontweight = pango.WEIGHT_BOLD
875    
876     _fgcolor = "black"
877     if sev==4:
878     _fgcolor = "#888800"
879     elif sev==5:
880     _fgcolor = "#884400"
881     elif sev==6:
882     _fgcolor = "#880000"
883     elif sev==0:
884     _fgcolor = BROWSER_FIXED_COLOR
885    
886     if not filename and not line:
887     _fileline = ""
888     else:
889     if(len(filename) > 25):
890     filename = "..."+filename[-22:]
891     _fileline = filename + ":" + str(line)
892    
893     _res = [_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight]
894     #print _res
895     return _res
896    
897 johnpye 132 def error_callback(self,sev,filename,line,msg):
898     pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
899     path = self.errorstore.get_path(pos)
900     col = self.errorview.get_column(3)
901     self.errorview.scroll_to_cell(path,col)
902    
903     return 0;
904    
905     # --------------------------------
906     # BUTTON METHODS
907    
908     def open_click(self,*args):
909     dialog = gtk.FileChooserDialog("Open file...",
910 johnpye 160 None,
911     gtk.FILE_CHOOSER_ACTION_OPEN,
912     (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
913     gtk.STOCK_OPEN, gtk.RESPONSE_OK))
914 johnpye 132 dialog.set_default_response(gtk.RESPONSE_OK)
915 johnpye 329 dialog.set_transient_for(self.window)
916     dialog.set_modal(True)
917 johnpye 132
918     filter = gtk.FileFilter()
919     filter.set_name("*.a4c, *.a4l")
920     filter.add_pattern("*.[Aa]4[Cc]")
921     filter.add_pattern("*.[Aa]4[Ll]")
922     dialog.add_filter(filter)
923    
924     filter = gtk.FileFilter()
925     filter.set_name("All files")
926     filter.add_pattern("*")
927     dialog.add_filter(filter)
928    
929     response = dialog.run()
930     _filename = dialog.get_filename()
931 johnpye 329 print "FILENAME SELECTED:",_filename
932     dialog.hide()
933 johnpye 132
934     if response == gtk.RESPONSE_OK:
935     self.reporter.reportNote("File %s selected." % dialog.get_filename() )
936 johnpye 185 self.library.clear()
937 johnpye 329 self.do_open( _filename)
938 johnpye 132
939     def reload_click(self,*args):
940     _type = None
941     if(self.sim):
942     _type = self.sim.getType().getName().toString();
943    
944 johnpye 185 self.library.clear()
945 johnpye 132 self.do_open(self.filename)
946    
947     if _type:
948     _t = self.library.findType(_type)
949     self.do_sim(_t)
950    
951     def solve_click(self,*args):
952     #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
953     self.do_solve()
954    
955     def check_click(self,*args):
956     self.do_check()
957     #self.reporter.reportError("CHECK clicked")
958    
959 johnpye 208 def preferences_click(self,*args):
960     if not self.sim:
961     self.reporter.reportError("No simulation created yet!");
962    
963 johnpye 351 _paramswin = SolverParametersWindow(self)
964 johnpye 223 _paramswin.show()
965 johnpye 221
966 johnpye 132 def methodrun_click(self,*args):
967     _sel = self.methodsel.get_active_text()
968     if _sel:
969     _method = None
970     _methods = self.sim.getType().getMethods()
971     for _m in _methods:
972     if _m.getName()==_sel:
973     _method = _m
974     if not _method:
975     self.reporter.reportError("Method is not valid")
976     return
977     self.do_method(_method)
978     else:
979     self.reporter.reportError("No method selected")
980    
981     def auto_toggle(self,button,*args):
982 johnpye 230 self.is_auto = button.get_active()
983     self.automenu.set_active(self.is_auto)
984    
985     if self.is_auto:
986 johnpye 168 self.reporter.reportSuccess("Auto mode is now ON")
987 johnpye 132 else:
988 johnpye 168 self.reporter.reportSuccess("Auto mode is now OFF")
989 johnpye 132
990 johnpye 230 def on_file_quit_click(self,*args):
991     self.do_quit()
992    
993     def on_tools_auto_toggle(self,checkmenuitem,*args):
994     self.is_auto = checkmenuitem.get_active()
995     self.autotoggle.set_active(self.is_auto)
996    
997     def on_help_about_click(self,*args):
998 johnpye 436 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
999 johnpye 307 _about = _xml.get_widget("aboutdialog")
1000 johnpye 328 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1001     _about.set_transient_for(self.window);
1002 johnpye 307 _about.set_version(VERSION)
1003     _about.run()
1004     _about.destroy()
1005 johnpye 230
1006     def on_help_contents_click(self,*args):
1007     _help = Help(HELP_ROOT)
1008     _help.run()
1009    
1010 johnpye 290 def on_find_fixable_variables_activate(self,*args):
1011     v = self.sim.getFixableVariables()
1012     for var in v:
1013     print "FIXABLE:",var
1014    
1015 johnpye 245 def create_observer(self,name=None):
1016     if name==None:
1017     name="New Observer"
1018    
1019 johnpye 436 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1020 johnpye 245 _label = gtk.Label();
1021     _label.set_text(name)
1022 johnpye 252 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1023     self.observers.append(ObserverTab(_xml, name, self, _tab))
1024 johnpye 249
1025     def sync_observers(self):
1026     for _o in self.observers:
1027     _o.sync()
1028    
1029 johnpye 132 # ------------------------------
1030     # CONTEXT MENU
1031    
1032 johnpye 270 def on_treeview_event(self,widget,event):
1033     _contextmenu = False;
1034 johnpye 271 if event.type==gtk.gdk.KEY_PRESS and gtk.gdk.keyval_name(event.keyval)=='Menu':
1035     _contextmenu = True
1036     _path, _col = self.treeview.get_cursor()
1037     _button = 3;
1038 johnpye 270 elif event.type==gtk.gdk.BUTTON_PRESS:
1039     if event.button == 3:
1040     _contextmenu = True
1041     _x = int(event.x)
1042     _y = int(event.y)
1043     _button = event.button
1044     _pthinfo = self.treeview.get_path_at_pos(_x, _y)
1045     if _pthinfo == None:
1046     return
1047     _path, _col, _cellx, _celly = _pthinfo
1048    
1049 johnpye 132 # which button was clicked?
1050 johnpye 270 if not _contextmenu:
1051     return
1052 johnpye 172
1053 johnpye 270 _canpop = False;
1054     # self.reporter.reportError("Right click on %s" % self.otank[_path][0])
1055     _instance = self.otank[_path][1]
1056     if _instance.getType().isRefinedSolverVar():
1057     _canpop = True;
1058     self.observemenuitem.set_sensitive(True)
1059     if _instance.isFixed():
1060     self.fixmenuitem.set_sensitive(False)
1061     self.freemenuitem.set_sensitive(True)
1062     else:
1063     self.fixmenuitem.set_sensitive(True)
1064     self.freemenuitem.set_sensitive(False)
1065     elif _instance.isRelation():
1066     _canpop = True;
1067     self.propsmenuitem.set_sensitive(True)
1068 johnpye 172
1069 johnpye 270 if _instance.isPlottable():
1070     self.plotmenuitem.set_sensitive(True)
1071     _canpop = True;
1072     else:
1073     self.plotmenuitem.set_sensitive(False)
1074 johnpye 132
1075 johnpye 270 if not _canpop:
1076     return
1077    
1078     self.treeview.grab_focus()
1079     self.treeview.set_cursor( _path, _col, 0)
1080     self.treecontext.popup( None, None, None, _button, event.time)
1081     return 1
1082    
1083 johnpye 132 def fix_activate(self,widget):
1084     _path,_col = self.treeview.get_cursor()
1085     _name, _instance = self.otank[_path]
1086 johnpye 299 self.set_fixed(_instance,True);
1087 johnpye 132 _instance.setFixed(True)
1088     return 1
1089    
1090     def free_activate(self,widget):
1091     _path,_col = self.treeview.get_cursor()
1092     _instance = self.otank[_path][1]
1093 johnpye 299 self.set_fixed(_instance,False)
1094 johnpye 132 return 1
1095    
1096 johnpye 172 def plot_activate(self,widget):
1097 johnpye 175 self.reporter.reportNote("plot_activate...");
1098 johnpye 172 _path,_col = self.treeview.get_cursor()
1099     _instance = self.otank[_path][1]
1100     if not _instance.isPlottable():
1101 johnpye 175 self.reporter.reportError("Can't plot instance %s" % _instance.getName().toString())
1102 johnpye 172 return
1103 johnpye 175 else:
1104     self.reporter.reportNote("Instance %s about to be plotted..." % _instance.getName().toString())
1105 johnpye 172
1106 johnpye 175 print("Plotting instance '%s'..." % _instance.getName().toString())
1107    
1108 johnpye 176 _plot = _instance.getPlot()
1109 johnpye 175
1110 johnpye 176 print "Title: ", _plot.getTitle()
1111 johnpye 180 _plot.show(True)
1112 johnpye 176
1113 johnpye 172 return 1
1114    
1115 johnpye 181 def props_activate(self,widget):
1116 johnpye 207 _path,_col = self.treeview.get_cursor()
1117     _instance = self.otank[_path][1]
1118     if _instance.isRelation():
1119 johnpye 215 print "Relation '"+_instance.getName().toString()+"':", \
1120     _instance.getRelationAsString(self.sim.getModel())
1121 johnpye 351 _dia = RelPropsWin(self,_instance);
1122 johnpye 273 _dia.run();
1123 johnpye 268 elif _instance.getType().isRefinedSolverVar():
1124 johnpye 351 _dia = VarPropsWin(self,_instance);
1125 johnpye 268 _dia.run();
1126 johnpye 207 else:
1127 johnpye 271 self.reporter.reportWarning("Select a variable first...")
1128 johnpye 172
1129 johnpye 246 def observe_activate(self,widget):
1130     _path,_col = self.treeview.get_cursor()
1131     _instance = self.otank[_path][1]
1132     if _instance.getType().isRefinedSolverVar():
1133     print "OBSERVING",_instance.getName().toString()
1134     if len(self.observers) > 1:
1135 johnpye 361 self.reporter.reportError("Not implemented: multiple observers (currently %d observers)" %
1136     len(self.observers) )
1137 johnpye 246 return
1138     if len(self.observers) ==0:
1139     self.create_observer()
1140     _observer = self.observers[0]
1141     _observer.add_instance(_instance)
1142 johnpye 270
1143     def delete_event(self, widget, event):
1144 johnpye 230 self.do_quit()
1145 johnpye 132 return False
1146    
1147     def test():
1148     import ascend
1149     b = Browser();
1150     b.run()
1151    
1152     if __name__ == "__main__":
1153     test()

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