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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1387 - (show annotations) (download) (as text)
Sat Apr 7 14:43:31 2007 UTC (13 years, 9 months ago) by jpye
File MIME type: text/x-python
File size: 37066 byte(s)
Added plot support in Integrator output tabs.
Some other minor debugging for pylab integration and idaanalyse output.
1 #!/usr/bin/env python
2
3 import sys
4 def print_loading_status(status,msg=None):
5 sys.stderr.write("\r \r")
6 if msg!=None:
7 sys.stderr.write(msg+"\n")
8 sys.stderr.write(status+"...\r")
9 sys.stderr.flush()
10
11 try:
12 #print_loading_status("Loading PSYCO")
13 #try:
14 # import psyco
15 # psyco.full()
16 # print "Running with PSYCO optimisation..."
17 #except ImportError:
18 # pass
19
20
21 print_loading_status("Loading python standard libraries")
22
23 import re
24 import urlparse
25 import optparse
26 import platform
27 import sys
28 import os.path
29
30 if platform.system() != "Windows":
31 try:
32 import dl
33 _dlflags = dl.RTLD_GLOBAL|dl.RTLD_NOW
34 except:
35 # On platforms that unilaterally refuse to provide the 'dl' module
36 # we'll just set the value and see if it works.
37 print_loading_status("Setting dlopen flags","Python 'dl' module not available on this system")
38 _dlflags = 258
39 # This sets the flags for dlopen used by python so that the symbols in the
40 # ascend library are made available to libraries dlopened within ASCEND:
41 sys.setdlopenflags(_dlflags)
42
43 print_loading_status("Loading LIBASCEND/ascpy")
44 import ascpy
45
46 print_loading_status("Loading PyGTK, glade, pango")
47
48 import pygtk
49 pygtk.require('2.0')
50 import gtk
51 import gtk.glade
52 import pango
53
54 print_loading_status("Loading python matplotlib")
55 try:
56 import matplotlib
57 matplotlib.use('GTKAgg')
58
59 try:
60 print_loading_status("Trying python numpy")
61 import numpy
62 matplotlib.rcParams['numerix'] = 'numpy'
63 print_loading_status("","Using python module numpy")
64 except ImportError:
65 try:
66 print_loading_status("Trying python numarray")
67 import numarray
68 matplotlib.rcParams['numerix'] = 'numarray'
69 print_loading_status("","Using python module numarray")
70 except ImportError:
71 try:
72 print_loading_status("Trying python Numeric")
73 import Numeric
74 matplotlib.rcParams['numerix'] = 'Numeric'
75 print_loading_status("","Using python module Numeric")
76 except ImportError:
77 print_loading_status("","FAILED TO LOAD A NUMERIC MODULE FOR PYTHON")
78
79 except ImportError,e:
80 print_loading_status("","FAILED TO LOAD MATPLOTLIB")
81 raise RuntimeError("Failed to load MATPLOTLIB (is it installed?). Details:"+str(e))
82
83 print_loading_status("Loading ASCEND python modules")
84 from preferences import * # loading/saving of .ini options
85 from solverparameters import * # 'solver parameters' window
86 from help import * # viewing help files
87 from incidencematrix import * # incidence/sparsity matrix matplotlib window
88 from observer import * # observer tab support
89 from properties import * # solver_var properties dialog
90 from varentry import * # for inputting of variables with units
91 from diagnose import * # for diagnosing block non-convergence
92 from solverreporter import * # solver status reporting
93 from modelview import * # model browser
94 from integrator import * # integrator dialog
95 from infodialog import * # general-purpose textual information dialog
96 from versioncheck import * # version check (contacts ascend.cruncher2.dyndns.org)
97 import config
98
99 except RuntimeError, e:
100 print "ASCEND had problems starting up. Please report the following"
101 print "error message at http://mantis.cruncher2.dyndns.org/."
102 print "\n\nFull error message:",str(e)
103 print "\n\nPress ENTER to close this window."
104 sys.stdout.flush()
105 sys.stdin.readline();
106 sys.exit();
107
108 except ImportError, e:
109 print "\n\n------------------ ERROR ---------------------"
110 print "ASCEND had problems importing required models."
111 print "\nPlease ensure you have all the runtime prerequisites installed."
112 print "Please then report a bug if you continue to have problems."
113 print "\nFull error message:",str(e)
114 if platform.system()=="Windows":
115 print "\nYou will also need to report the contents of any popup error"
116 print "messages from Windows if any were shown."
117 print "\n\nPress ENTER to close this window."
118 sys.stdout.flush()
119 sys.stdin.readline();
120 sys.exit();
121
122 print_loading_status("Starting GUI")
123
124 # This is my first ever GUI code so please be nice :)
125 # But I *have* at least read
126 # http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html
127 # and leafed through
128 # http://developer.gnome.org/projects/gup/hig/
129
130 # The fancy tree-view gizmo is the GtkTreeView object. See the article
131 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/300304
132 # for the original source code on which my implementation was based.
133
134 ESCAPE_KEY = 65307
135
136 HELP_ROOT = None
137
138 #======================================
139 # Browser is the main ASCEND library/model browser window
140
141 class Browser:
142
143 # ---------------------------------
144 # SETUP
145
146 def __init__(self,librarypath=None,assetspath=None):
147
148 if assetspath==None:
149 assetspath=config.PYGTK_ASSETS
150
151 #--------
152 # load the file referenced in the command line, if any
153
154 print_loading_status("Parsing options","CONFIG = %s"%config.VERSION)
155
156 parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
157 # add options here if we want
158
159 parser.add_option("-m", "--model"
160 ,action="store", type="string", dest="model"
161 ,help="specify the model to instantiate upon loading modules")
162
163 parser.add_option("--pygtk-assets"
164 ,action="store", type="string", dest="assets_dir"
165 ,help="override the configuration value for the location of assets"\
166 +" required by PyGTK for the ASCEND GUI, optional"
167 ,default=assetspath
168 )
169
170 parser.add_option("--library"
171 ,action="store", type="string", dest="library_path"
172 ,help="override the configuration value for the library path"
173 ,default=librarypath
174 )
175
176 parser.add_option("--no-auto-sim"
177 ,action="store_false", dest="auto_sim"
178 ,help="disable auto-instantiation of MODEL named as the file stem"
179 ,default=True
180 )
181
182 (self.options, args) = parser.parse_args()
183
184 #print "OPTIONS_______________:",self.options
185
186 self.assets_dir = self.options.assets_dir
187
188 self.observers = []
189 self.clip = None
190
191 #--------
192 # load up the preferences ini file
193
194 print_loading_status("Loading preferences")
195
196 self.prefs = Preferences()
197
198 _prefpath = self.prefs.getStringPref("Directories","librarypath",None)
199 _preffileopenpath = self.prefs.getStringPref("Directories","fileopenpath",None)
200
201 #--------
202 # set up library path and the path to use for File->Open dialogs
203
204 if self.options.library_path != None:
205 _path = os.path.abspath(self.options.library_path)
206 _pathsrc = "command line options"
207 # when a special path is specified, use the last path component as the file-open location
208 if platform.system()=="Windows":
209 self.fileopenpath = _path.split(":").pop()
210 else:
211 self.fileopenpath = _path.split(":").pop()
212 else:
213 if _prefpath:
214 _path = _prefpath
215 _pathsrc = "user preferences"
216 else:
217 _path = config.LIBRARY_PATH
218 _pathsrc = "default (config.py)"
219
220 if _preffileopenpath:
221 self.fileopenpath = _preffileopenpath
222 else:
223 self.fileopenpath = _path
224
225 #--------
226 # Create the ASCXX 'Library' object
227
228 print_loading_status("Creating ASCEND 'Library' object","PATH = "+_path+" FROM "+_pathsrc)
229 self.library = ascpy.Library(_path)
230
231 self.sim = None
232
233 #-------------------
234 # Set up the window and main widget actions
235
236 self.glade_file = os.path.join(self.assets_dir,config.GLADE_FILE)
237
238 print_loading_status("Setting up windows") #,"GLADE_FILE = %s" % self.glade_file)
239
240 glade = gtk.glade.XML(self.glade_file,"browserwin")
241
242 self.window = glade.get_widget("browserwin")
243
244
245 if not self.window:
246 raise RuntimeError("Couldn't load window from glade file")
247
248 _display = self.window.get_screen().get_display().get_name()
249 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
250 if _geom:
251 self.window.resize(_geom[0],_geom[1])
252 self.window.move(_geom[2],_geom[3])
253
254 self.window.connect("delete_event", self.delete_event)
255
256 self.browserpaned=glade.get_widget("browserpaned")
257 _geom2=self.prefs.getGeometryValue(_display,"browserpaned")
258 if _geom2:
259 self.browserpaned.set_position(_geom2)
260
261 buttons = ["open","reload","solve","integrate","check","methodrun"]
262 for n in buttons:
263 name = "%sbutton"%n
264 setattr(self,name,glade.get_widget(name))
265 getattr(self,name).connect("clicked",getattr(self,"%s_click"%n))
266
267 widgets = ["autotoggle","automenu","methodsel","maintabs","lowertabs","consolescroll","statusbar","browsermenu"]
268 for n in widgets:
269 setattr(self,n,glade.get_widget(n))
270
271 self.autotoggle.connect("toggled",self.auto_toggle)
272
273 self.show_solving_popup=glade.get_widget("show_solving_popup")
274 self.show_solving_popup.set_active(self.prefs.getBoolPref("SolverReporter","show_popup",True))
275 self.close_on_converged=glade.get_widget("close_on_converged")
276 self.close_on_converged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_converged",True))
277 self.close_on_nonconverged=glade.get_widget("close_on_nonconverged")
278 self.close_on_nonconverged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_nonconverged",True))
279 self.solver_engine=glade.get_widget("solver_engine")
280
281 self.use_relation_sharing=glade.get_widget("use_relation_sharing")
282 self.use_relation_sharing.set_active(self.prefs.getBoolPref("Compiler","use_relation_sharing",True))
283
284 self.use_binary_compilation=glade.get_widget("use_binary_compilation")
285 self.use_binary_compilation.set_active(self.prefs.getBoolPref("Compiler","use_binary_compilation",False))
286 self.use_binary_compilation.set_sensitive(self.use_relation_sharing.get_active())
287
288 glade.signal_autoconnect(self)
289
290 #-------
291 # Status icons
292
293 self.fixedimg = gtk.Image()
294 self.fixedimg.set_from_file(os.path.join(self.options.assets_dir,'locked.png'))
295
296 self.inactiveimg = gtk.Image()
297 self.inactiveimg.set_from_file(os.path.join(self.options.assets_dir,'unattached.png'))
298
299 self.iconstatusunknown = None
300 self.iconfixed = self.fixedimg.get_pixbuf()
301 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
302 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
303 self.iconinactive = self.inactiveimg.get_pixbuf()
304 self.iconunsolved = None
305
306 self.statusicons={
307 ascpy.ASCXX_INST_STATUS_UNKNOWN: self.iconstatusunknown
308 ,ascpy.ASCXX_VAR_FIXED: self.iconfixed
309 ,ascpy.ASCXX_VAR_SOLVED: self.iconsolved
310 ,ascpy.ASCXX_VAR_ACTIVE: self.iconactive
311 ,ascpy.ASCXX_VAR_UNSOLVED: self.iconunsolved
312 ,ascpy.ASCXX_REL_INACTIVE: self.iconinactive
313 }
314
315
316 self.statusmessages={
317 ascpy.ASCXX_INST_STATUS_UNKNOWN: "Status unknown"
318 ,ascpy.ASCXX_VAR_FIXED: "Fixed"
319 ,ascpy.ASCXX_VAR_SOLVED: "Converged"
320 ,ascpy.ASCXX_VAR_ACTIVE: "Active (unconverged)"
321 ,ascpy.ASCXX_VAR_UNSOLVED: "Not yet visited"
322 ,ascpy.ASCXX_REL_INACTIVE: "Inactive"
323 }
324
325 #-------------------
326 # waitwin
327
328 self.waitwin = gtk.gdk.Window(self.window.window,
329 gtk.gdk.screen_width(),
330 gtk.gdk.screen_height(),
331 gtk.gdk.WINDOW_CHILD,
332 0,
333 gtk.gdk.INPUT_ONLY)
334
335 _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
336 self.waitwin.set_cursor(_cursor)
337
338 #-------------------
339 # pixbufs to be used in the error listing
340
341 self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
342 self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
343 self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
344 self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
345
346 #--------------------
347 # pixbufs for solver_var status
348
349 #--------------------
350 # set up the error view
351
352 self.errorview = glade.get_widget("errorview")
353 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
354 self.errorstore = gtk.TreeStore(*errstorecolstypes)
355 errtitles = ["","Location","Message"];
356 self.errorview.set_model(self.errorstore)
357 self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
358
359 i = 0
360 for tvcolumn in self.errcols[:len(errtitles)]:
361 tvcolumn.set_title(errtitles[i])
362 self.errorview.append_column(tvcolumn)
363
364 if i>0:
365 _renderer = gtk.CellRendererText()
366 tvcolumn.pack_start(_renderer, True)
367 tvcolumn.add_attribute(_renderer, 'text', i)
368 if(i==2):
369 tvcolumn.add_attribute(_renderer, 'foreground', 3)
370 tvcolumn.add_attribute(_renderer, 'weight', 4)
371 else:
372 _renderer1 = gtk.CellRendererPixbuf()
373 tvcolumn.pack_start(_renderer1, False)
374 tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
375
376 i = i + 1
377
378
379 #--------------------
380 # set up the error reporter callback
381 self.reporter = ascpy.getReporter()
382 self.reporter.setPythonErrorCallback(self.error_callback)
383
384
385 #-------
386 # Solver engine list
387
388 _slvlist = ascpy.getSolvers()
389 self.solver_engine_menu = gtk.Menu()
390 self.solver_engine_menu.show()
391 self.solver_engine.set_submenu(self.solver_engine_menu)
392 self.solver_engine_menu_dict = {}
393 _fmi = None
394 for _s in _slvlist:
395 _mi = gtk.RadioMenuItem(_fmi,_s.getName(),False)
396 if _fmi==None:
397 _fmi = _mi
398 _mi.show()
399 _mi.connect('toggled',self.on_select_solver_toggled,_s.getName())
400 self.solver_engine_menu.append(_mi)
401 self.solver_engine_menu_dict[_s.getName()]=_mi
402
403 _pref_solver = self.prefs.getStringPref("Solver","engine","QRSlv")
404 _mi = self.solver_engine_menu_dict.get(_pref_solver)
405 if _mi:
406 _mi.set_active(1)
407
408 #--------
409 # Assign an icon to the main window
410
411 self.icon = None
412 if config.ICON_EXTENSION:
413 _iconpath = ""
414 try:
415 _icon = gtk.Image()
416 _iconpath = os.path.join(self.assets_dir,'ascend'+config.ICON_EXTENSION)
417 _icon.set_from_file(_iconpath)
418 _iconpbuf = _icon.get_pixbuf()
419 self.window.set_icon(_iconpbuf)
420 self.icon = _iconpbuf
421 except Exception, e:
422 print "FAILED TO SET APPLICATION ICON PATH '%s': %s" % (_iconpath,str(e))
423 self.reporter.reportError("FAILED to set application icon '%s': %s"
424 % (_iconpath,str(e))
425 )
426
427 #-------------------
428 # set up the module view
429
430 self.modtank = {}
431 self.moduleview = glade.get_widget("moduleview")
432 modulestorecoltypes = [str, str, int] # bool=can-be-instantiated
433 self.modulestore = gtk.TreeStore(*modulestorecoltypes)
434 moduleviewtitles = ["Module name", "Filename"]
435 self.moduleview.set_model(self.modulestore)
436 self.modcols = [ gtk.TreeViewColumn() for _type in modulestorecoltypes]
437 i = 0
438 for modcol in self.modcols[:len(moduleviewtitles)]:
439 modcol.set_title(moduleviewtitles[i])
440 self.moduleview.append_column(modcol)
441 _renderer = gtk.CellRendererText()
442 modcol.pack_start(_renderer, True)
443 modcol.add_attribute(_renderer, 'text', i)
444 modcol.add_attribute(_renderer,'weight',2)
445 i = i + 1
446 self.moduleview.connect("row-activated", self.module_activated )
447
448 #--------------------
449 # set up the methods combobox
450
451 self.methodstore = gtk.ListStore(str)
452 self.methodsel.set_model(self.methodstore)
453 _methodrenderer = gtk.CellRendererText()
454 self.methodsel.pack_start(_methodrenderer, True)
455 self.methodsel.add_attribute(_methodrenderer, 'text',0)
456
457 #--------
458 # set up the instance browser view
459
460 self.modelview = ModelView(self, glade)
461
462 #--------
463 # set up the tabs
464 self.tabs = {}
465 self.activetab = None # most recent observer tab
466
467 #--------
468 # set the state of the 'auto' toggle
469
470 self.is_auto = self.prefs.getBoolPref("Browser","auto_solve",True)
471 self.autotoggle.set_active(self.is_auto)
472 self.automenu.set_active(self.is_auto)
473
474 #--------
475 # tell libascend about this 'browser' object
476
477 print dir(ascpy.Registry())
478 ascpy.Registry().set("browser",self)
479
480 #--------
481 # options
482
483 if(len(args)==1):
484 try:
485 self.do_open(args[0])
486 except RuntimeError,e:
487 self.reporter.reportError(str(e))
488 return
489
490 print "Options: ",self.options
491
492 _model = None
493 if self.options.model:
494 _model = self.options.model
495 print "MODEL: '%s'" % _model
496 elif self.options.auto_sim:
497 _head, _tail = os.path.split(args[0])
498 if(_tail):
499 _model, _ext = os.path.splitext(_tail)
500
501 if _model:
502 try:
503 _t=self.library.findType(_model)
504 try:
505 self.do_sim(_t)
506 if not self.options.model:
507 self.reporter.reportNote("Instantiated self-titled model '%s'" %_model)
508 except RuntimeError, e:
509 self.reporter.reportError("Failed to create instance of '%s': %s"
510 %(_model, str(e))
511 );
512 except RuntimeError, e:
513 if self.options.model:
514 self.reporter.reportError("Unknown model type '%s': %s"
515 %(_model, str(e))
516 );
517
518 #--------
519 # IPython console, if available
520
521 import console
522 console.create_widget(self)
523
524 def run(self):
525 self.window.show()
526 print_loading_status("ASCEND is now running")
527 gtk.main()
528
529 # ------------------
530 # SOLVER LIST
531
532 def set_solver(self,solvername):
533 """ this sets the active solver in the GUI, which is the default applied to newly instantiated models """
534 self.solver = ascpy.Solver(solvername)
535 self.prefs.setStringPref("Solver","engine",solvername)
536 self.reporter.reportNote("Set solver engine to '%s'" % solvername)
537
538 # --------------------------------------------
539 # MAJOR GUI COMMANDS
540
541 def on_fix_variable_activate(self,*args):
542 self.modelview.on_fix_variable_activate(*args)
543
544 def on_free_variable_activate(self,*args):
545 self.modelview.on_free_variable_activate(*args)
546
547 def on_select_solver_toggled(self,widget,solvername):
548 if widget.get_active():
549 self.set_solver(solvername)
550
551 def do_open(self,filename):
552 # TODO does the user want to lose their work?
553 # TODO do we need to chdir?
554
555 _context = self.statusbar.get_context_id("do_open")
556
557 self.errorstore.clear()
558 self.modelview.clear()
559
560 # self.library.clear()
561
562 print "Filename =",filename
563 self.statusbar.push(_context,"Loading '"+filename+"'")
564 try:
565 self.filename = filename
566 self.library.load(filename)
567 except RuntimeError,e:
568 self.statusbar.pop(_context)
569 raise
570
571 print "Statusbar =",self.statusbar
572 try:
573 self.statusbar.pop(_context)
574 except TypeError,e:
575 print "For some reason, a type error (context=%s,filename=%s): %s" % (_context,filename,e)
576
577 # Load the current list of modules into self.modules
578 self.modtank = {}
579 self.modulestore.clear()
580 modules = self.library.getModules()
581 #self.library.listModules()
582 try:
583 _lll=len(modules)
584 except:
585 _msg = "UNABLE TO ACCESS MODULES LIST. This is bad.\n"+\
586 "Check your SWIG configuration (check for warnings during build)."
587
588 self.reporter.reportError(_msg)
589 raise RuntimeError(_msg)
590
591 for m in reversed(modules):
592 _n = str( m.getName() )
593 _f = str( m.getFilename() )
594 #print "ADDING ROW name %s, file = %s" % (_n, _f)
595 _r = self.modulestore.append(None, [ _n, _f, pango.WEIGHT_NORMAL ])
596 for t in self.library.getModuleTypes(m):
597 _n = t.getName()
598 _hasparams = t.hasParameters()
599 if _hasparams:
600 _w = pango.WEIGHT_NORMAL
601 else:
602 _w = pango.WEIGHT_BOLD
603
604 #print "ADDING TYPE %s" % _n
605 _piter = self.modulestore.append(_r , [ _n, "", _w ])
606 _path = self.modulestore.get_path(_piter)
607 self.modtank[_path]=t
608
609 #print "DONE ADDING MODULES"
610
611 self.sim = None;
612 self.maintabs.set_current_page(0);
613
614 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
615 # for details on how the 'wait cursor' is done.
616 def start_waiting(self, message):
617 self.waitcontext = self.statusbar.get_context_id("waiting")
618 self.statusbar.push(self.waitcontext,message)
619
620 if self.waitwin:
621 self.waitwin.show()
622
623 while gtk.events_pending():
624 gtk.main_iteration()
625
626 def stop_waiting(self):
627 if self.waitwin:
628 self.statusbar.pop(self.waitcontext)
629 self.waitwin.hide()
630
631 def do_sim(self, type_object):
632 self.sim = None;
633 # TODO: clear out old simulation first!
634
635 print "DO_SIM(%s)" % str(type_object.getName())
636 self.start_waiting("Compiling...")
637
638 try:
639 _v = self.prefs.getBoolPref("Compiler","use_relation_sharing",True)
640 ascpy.getCompiler().setUseRelationSharing(_v)
641
642 _v = self.prefs.getBoolPref("Compiler","use_binary_compilation",True)
643 ascpy.getCompiler().setBinaryCompilation(True)
644
645 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim",False)
646
647 self.reporter.reportNote("SIMULATION ASSIGNED")
648 except RuntimeError, e:
649 self.stop_waiting()
650 self.reporter.reportError(str(e))
651 return
652
653 self.stop_waiting()
654
655 # get method names and load them into the GUI
656 self.methodstore.clear()
657 _methods = self.sim.getType().getMethods()
658 _activemethod = None;
659 for _m in _methods:
660 _i = self.methodstore.append([_m.getName()])
661 if _m.getName()=="on_load":
662 self.methodsel.set_active_iter(_i)
663
664 self.modelview.setSimulation(self.sim)
665
666 # run the 'on_load' method
667 self.start_waiting("Running default method...")
668 try:
669 self.reporter.reportNote("SIMULATION CREATED, RUNNING DEFAULT METHOD NOW...")
670 self.sim.runDefaultMethod()
671 except RuntimeError, e:
672 self.stop_waiting()
673 self.reporter.reportError(str(e))
674 return
675 self.stop_waiting()
676
677 self.modelview.refreshtree()
678
679 def do_solve_if_auto(self):
680 if self.is_auto:
681 self.sim.checkInstance()
682 self.do_solve()
683 else:
684 self.sim.processVarStatus()
685 self.modelview.refreshtree()
686
687 self.sync_observers()
688
689 def do_solve(self):
690 if not self.sim:
691 self.reporter.reportError("No model selected yet")
692 return
693
694 try:
695 self.sim.build()
696 except RuntimeError,e:
697 self.reporter.reportError("Couldn't build system: %s",str(e));
698 return
699
700 self.start_waiting("Solving with %s..." % self.solver.getName())
701
702 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
703 reporter = PopupSolverReporter(self,self.sim.getNumVars())
704 else:
705 reporter = SimpleSolverReporter(self)
706
707 try:
708 self.sim.solve(self.solver,reporter)
709 except RuntimeError,e:
710 self.reporter.reportError(str(e))
711
712 self.stop_waiting()
713
714 self.modelview.refreshtree()
715
716 def do_integrate(self):
717 if not self.sim:
718 self.reporter.reportError("No model selected yet")
719 return
720
721 try:
722 self.sim.build()
723 except RuntimeError,e:
724 self.reporter.reportError("Couldn't build system: %s",str(e))
725 return
726
727 integwin = IntegratorWindow(self,self.sim)
728 _integratorreporter = integwin.run()
729 if _integratorreporter!=None:
730 _integratorreporter.run()
731 self.sim.processVarStatus()
732 self.modelview.refreshtree()
733
734
735 def do_check(self):
736 try:
737 self.sim.build()
738 except RuntimeError,e:
739 self.reporter.reportError("Couldn't build system: %s",str(e));
740 return
741
742 self.start_waiting("Checking system...")
743
744 try:
745 self.sim.checkInstance()
746 self.reporter.reportWarning("System instance check run, check above for error (if any).")
747 # the above gives output but doesn't throw errors or return a status.
748 # ... this is a problem (at the C level)
749
750 status = self.sim.checkDoF()
751 if status==ascpy.ASCXX_DOF_UNDERSPECIFIED:
752 self.on_show_fixable_variables_activate(None)
753 elif status==ascpy.ASCXX_DOF_OVERSPECIFIED:
754 self.on_show_freeable_variables_activate(None)
755 elif status==ascpy.ASCXX_DOF_STRUCT_SINGULAR:
756 if not self.sim.checkStructuralSingularity():
757 sing = self.sim.getSingularityInfo()
758 title = "Structural singularity"
759 text = title
760 msgs = {
761 "The singularity can be reduced by freeing the following variables" : sing.freeablevars
762 ,"Relations involved in the structural singularity" : sing.rels
763 ,"Variables involved in the structural singularity" : sing.vars
764 }
765 for k,v in msgs.iteritems():
766 text+="\n\n%s:" % k
767 if len(v):
768 _l = [j.getName() for j in v]
769 _l.sort()
770 text+= "\n\t" + "\n\t".join(_l)
771 else:
772 text += "\nnone"
773
774 _dialog = InfoDialog(self,self.window,text,title)
775 _dialog.run()
776 else:
777 self.reporter.reportNote("System DoF check OK")
778
779 except RuntimeError, e:
780 self.stop_waiting()
781 self.reporter.reportError(str(e))
782 return
783
784 self.stop_waiting()
785 self.modelview.refreshtree()
786
787 def do_method(self,method):
788 if not self.sim:
789 self.reporter.reportError("No model selected yet")
790
791 try:
792 self.sim.run(method)
793 except RuntimeError,e:
794 self.reporter.reportError(str(e))
795
796 self.sim.processVarStatus()
797 self.modelview.refreshtree()
798
799 def do_quit(self):
800 print_loading_status("Saving window location")
801 self.reporter.clearPythonErrorCallback()
802
803 _w,_h = self.window.get_size()
804 _t,_l = self.window.get_position()
805 _display = self.window.get_screen().get_display().get_name()
806 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
807
808 _p = self.browserpaned.get_position()
809 self.prefs.setGeometryValue(_display,"browserpaned",_p);
810
811 print_loading_status("Saving current directory")
812 self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
813
814 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
815
816 print_loading_status("Saving preferences")
817 # causes prefs to be saved unless they are still being used elsewher
818 del(self.prefs)
819
820 print_loading_status("Clearing error callback")
821 self.reporter.clearPythonErrorCallback()
822
823 print_loading_status("Closing down GTK")
824 gtk.main_quit()
825
826 print_loading_status("Clearing library")
827 self.library.clear()
828
829 print_loading_status("Quitting")
830
831 return False
832
833 def on_tools_sparsity_click(self,*args):
834
835 self.reporter.reportNote("Preparing incidence matrix...")
836 _im = self.sim.getIncidenceMatrix();
837
838 self.reporter.reportNote("Plotting incidence matrix...")
839
840 _sp = IncidenceMatrixWindow(_im);
841 _sp.run();
842
843 def on_tools_repaint_tree_activate(self,*args):
844 self.reporter.reportNote("Repainting model view...")
845 self.modelview.refreshtree()
846
847 def on_diagnose_blocks_click(self,*args):
848 try:
849 _bl = self.sim.getActiveBlock()
850 except RuntimeError, e:
851 self.reporter.reportError(str(e))
852 return
853 _db = DiagnoseWindow(self,_bl)
854 _db.run();
855
856 def on_add_observer_click(self,*args):
857 self.create_observer()
858
859 def on_keep_observed_click(self,*args):
860 print "KEEPING..."
861 if len(self.observers) <= 0:
862 self.reporter.reportError("No observer defined!")
863 return
864 self.tabs[self.currentobservertab].do_add_row()
865
866 def on_copy_observer_matrix_click(self,*args):
867 if self.clip == None:
868 self.clip = gtk.Clipboard()
869
870 if len(self.observers) <= 0:
871 self.reporter.reportError("No observer defined!")
872 return
873 self.tabs[self.currentobservertab].copy_to_clipboard(self.clip)
874
875 def on_use_relation_sharing_toggle(self,checkmenuitem,*args):
876 _v = checkmenuitem.get_active()
877 self.prefs.setBoolPref("Compiler","use_relation_sharing",_v)
878 self.reporter.reportNote("Relation sharing set to "+str(_v))
879 self.use_binary_compilation.set_sensitive(_v);
880
881 def on_use_binary_compilation_toggle(self,checkmenuitem,*args):
882 _v = checkmenuitem.get_active()
883 self.prefs.setBoolPref("Compiler","use_binary_compilation",_v)
884 self.reporter.reportNote("Binary compilation set to "+str(_v))
885
886 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
887 _v = checkmenuitem.get_active()
888 self.prefs.setBoolPref("SolverReporter","show_popup",_v)
889 print "SET TO",_v
890
891 def on_close_on_converged_toggle(self,checkmenuitem,*args):
892 _v = checkmenuitem.get_active()
893 self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
894
895 def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
896 _v = checkmenuitem.get_active()
897 self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
898
899 def on_show_variables_near_bounds_activate(self,*args):
900 _epsilon = 1e-4;
901 text = "Variables Near Bounds"
902 title=text;
903 text += "\n"
904 _vars = self.sim.getVariablesNearBounds(_epsilon)
905 if len(_vars):
906 for _v in _vars:
907 text += "\n%s"%_v.getName()
908 else:
909 text +="\nnone"
910 _dialog = InfoDialog(self,self.window,text,title)
911 _dialog.run()
912
913 def on_show_vars_far_from_nominals_activate(self,*args):
914 _bignum = self.prefs.getRealPref("Browser","far_from_nominals",10);
915 text = "Variables Far from Nominals"
916 title=text;
917 text += "\n"
918 _vars = self.sim.getVariablesFarFromNominals(_bignum)
919 if len(_vars):
920 for _v in _vars:
921 text += "\n%s"%_v.getName()
922 else:
923 text +="\nnone"
924
925 text+="\n\nAbove calculated using a relative error of %f" % float(_bignum)
926 text+="\nModify this value in .ascend.ini, section '[Browser]', key 'far_from_nominals'."
927 _dialog = InfoDialog(self,self.window,text,title)
928 _dialog.run()
929
930 # --------------------------------------------
931 # MODULE LIST
932
933 def module_activated(self, treeview, path, column, *args):
934 modules = self.library.getModules()
935 print "PATH",path
936 if len(path)==1:
937 self.reporter.reportNote("Launching of external editor not yet implemented")
938 elif len(path)==2:
939 if(self.modtank.has_key(path)):
940 _type = self.modtank[path];
941 self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
942 self.do_sim(_type)
943 else:
944 self.reporter.reportError("Didn't find type corresponding to row")
945
946 # ----------------------------------
947 # ERROR PANEL
948
949 def get_error_row_data(self,sev,filename,line,msg):
950 try:
951 _sevicon = {
952 0 : self.iconok
953 ,1 : self.iconinfo
954 ,2 : self.iconwarning
955 ,4 : self.iconerror
956 ,8 : self.iconinfo
957 ,16 : self.iconwarning
958 ,32 : self.iconerror
959 ,64 : self.iconerror
960 }[sev]
961 except KeyError:
962 _sevicon = self.iconerror
963
964 _fontweight = pango.WEIGHT_NORMAL
965 if sev==32 or sev==64:
966 _fontweight = pango.WEIGHT_BOLD
967
968 _fgcolor = "black"
969 if sev==8:
970 _fgcolor = "#888800"
971 elif sev==16:
972 _fgcolor = "#884400"
973 elif sev==32 or sev==64:
974 _fgcolor = "#880000"
975 elif sev==0:
976 _fgcolor = BROWSER_FIXED_COLOR
977
978 if not filename and not line:
979 _fileline = ""
980 else:
981 if(len(filename) > 25):
982 filename = "..."+filename[-22:]
983 _fileline = filename + ":" + str(line)
984
985 _res = (_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight)
986 #print _res
987 return _res
988
989 def error_callback(self,sev,filename,line,msg):
990 #print "SEV =",sev
991 #print "FILENAME =",filename
992 #print "LINE =",line
993 #print "MSG =",msg
994 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
995 path = self.errorstore.get_path(pos)
996 col = self.errorview.get_column(3)
997 self.errorview.scroll_to_cell(path,col)
998 return 0;
999
1000 # --------------------------------
1001 # BUTTON METHODS
1002
1003 def open_click(self,*args):
1004 #print_loading_status("CURRENT FILEOPENPATH is",self.fileopenpath)
1005 dialog = gtk.FileChooserDialog("Open ASCEND model...",
1006 self.window,
1007 gtk.FILE_CHOOSER_ACTION_OPEN,
1008 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
1009 )
1010 dialog.set_current_folder(self.fileopenpath)
1011 dialog.set_default_response(gtk.RESPONSE_OK)
1012 dialog.set_transient_for(self.window)
1013 dialog.set_modal(True)
1014
1015 filter = gtk.FileFilter()
1016 filter.set_name("*.a4c, *.a4l")
1017 filter.add_pattern("*.[Aa]4[Cc]")
1018 filter.add_pattern("*.[Aa]4[Ll]")
1019 dialog.add_filter(filter)
1020
1021 filter = gtk.FileFilter()
1022 filter.set_name("All files")
1023 filter.add_pattern("*")
1024 dialog.add_filter(filter)
1025
1026 response = dialog.run()
1027 _filename = dialog.get_filename()
1028 print "\nFILENAME SELECTED:",_filename
1029
1030 _path = dialog.get_current_folder()
1031 if _path:
1032 self.fileopenpath = _path
1033
1034 dialog.hide()
1035
1036 if response == gtk.RESPONSE_OK:
1037 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
1038 self.library.clear()
1039 self.do_open( _filename)
1040
1041 def reload_click(self,*args):
1042 _type = None
1043 if(self.sim):
1044 _type = self.sim.getType().getName().toString();
1045
1046 self.library.clear()
1047
1048 try:
1049 self.do_open(self.filename)
1050 if _type:
1051 _t = self.library.findType(_type)
1052 self.do_sim(_t)
1053 except RuntimeError,e:
1054 self.reporter.reportError(str(e))
1055
1056 def props_activate(self,widget,*args):
1057 return self.modelview.props_activate(self,widget,*args)
1058
1059 def observe_activate(self,widget,*args):
1060 return self.modelview.observe_activate(self,widget,*args)
1061
1062 def solve_click(self,*args):
1063 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
1064 self.do_solve()
1065
1066 def console_click(self,*args):
1067 self.lowertabs.set_current_page(1)
1068 self.consoletext.grab_focus()
1069
1070 def integrate_click(self,*args):
1071 self.do_integrate()
1072
1073 def check_click(self,*args):
1074 self.do_check()
1075 #self.reporter.reportError("CHECK clicked")
1076
1077 def preferences_click(self,*args):
1078 if not self.sim:
1079 self.reporter.reportError("No simulation created yet!");
1080 self.sim.setSolver(self.solver)
1081 _params = self.sim.getParameters()
1082 _paramswin = SolverParametersWindow(
1083 browser=self
1084 ,params=_params
1085 ,name=self.solver.getName()
1086 )
1087 if _paramswin.run() == gtk.RESPONSE_OK:
1088 print "PARAMS UPDATED"
1089 self.sim.setParameters(_paramswin.params)
1090 else:
1091 print "PARAMS NOT UPDATED"
1092
1093 def methodrun_click(self,*args):
1094 _sel = self.methodsel.get_active_text()
1095 if _sel:
1096 _method = None
1097 _methods = self.sim.getType().getMethods()
1098 for _m in _methods:
1099 if _m.getName()==_sel:
1100 _method = _m
1101 if not _method:
1102 self.reporter.reportError("Method is not valid")
1103 return
1104 self.do_method(_method)
1105 else:
1106 self.reporter.reportError("No method selected")
1107
1108 def auto_toggle(self,button,*args):
1109 self.is_auto = button.get_active()
1110 if hasattr(self,'automenu'):
1111 self.automenu.set_active(self.is_auto)
1112 else:
1113 raise RuntimeError("no automenu")
1114
1115 #if self.is_auto:
1116 # self.reporter.reportSuccess("Auto mode is now ON")
1117 #else:
1118 # self.reporter.reportSuccess("Auto mode is now OFF")
1119
1120 def on_file_quit_click(self,*args):
1121 self.do_quit()
1122
1123 def on_tools_auto_toggle(self,checkmenuitem,*args):
1124 self.is_auto = checkmenuitem.get_active()
1125 self.autotoggle.set_active(self.is_auto)
1126
1127 def on_help_about_click(self,*args):
1128 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1129 _about = _xml.get_widget("aboutdialog")
1130 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1131 _about.set_transient_for(self.window);
1132 _about.set_version(config.VERSION)
1133 _about.run()
1134 _about.destroy()
1135
1136 def on_help_contents_click(self,*args):
1137 _help = Help(HELP_ROOT)
1138 _help.run()
1139
1140 def on_help_check_for_updates_click(self,*args):
1141 v = VersionCheck()
1142 title = "Check for updates"
1143 text = "Your version is %s\n" % config.VERSION
1144 try:
1145 v.check()
1146 if config.VERSION==v.latest:
1147 text += "You are running the latest released version"
1148 else:
1149 text += "Latest version is %s\n" % v.latest
1150 if v.info:
1151 text += "Get more info at %s\n" % v.info
1152 if v.download:
1153 text += "Download from %s\n" % v.download
1154 except Exception, e:
1155 text += "\nUnable to check version\n"
1156 text += str(e)
1157
1158 _dialog = InfoDialog(self,self.window,text,title)
1159 _dialog.run()
1160
1161 def on_show_fixable_variables_activate(self,*args):
1162 try:
1163 v = self.sim.getFixableVariables()
1164 except RuntimeError,e:
1165 self.reporter.reportError(str(e))
1166 text = "Fixable Variables"
1167 title = text
1168 text += "\n"
1169 if len(v):
1170 for var in v:
1171 text += "\n%s"%var
1172 else:
1173 text += "\nnone"
1174 _dialog = InfoDialog(self,self.window,text,title)
1175 _dialog.run()
1176
1177 def on_show_fixed_vars_activate(self,*args):
1178 try:
1179 v = self.sim.getFixedVariables()
1180 except RuntimeError,e:
1181 self.reporter.reportError(str(e))
1182 text = "Fixed Variables"
1183 title = text
1184 text += "\n"
1185 if len(v):
1186 for var in v:
1187 text += "\n%s"%var
1188 else:
1189 text += "\nnone"
1190 _dialog = InfoDialog(self,self.window,text,title)
1191 _dialog.run()
1192
1193
1194 def on_show_freeable_variables_activate(self,*args):
1195 try:
1196 v = self.sim.getFreeableVariables()
1197 except RuntimeError,e:
1198 self.reporter.reportError(str(e))
1199
1200 text = "Freeable Variables"
1201 title = text
1202 text += "\n"
1203 if len(v):
1204 for var in v:
1205 text += "\n%s" % var
1206 else:
1207 text += "\nnone"
1208 _dialog = InfoDialog(self,self.window,text,title)
1209 _dialog.run()
1210
1211 def on_show_external_functions_activate(self,*args):
1212 v = self.library.getExtMethods()
1213 text = "External Functions"
1214 title = text
1215 text +="\nHere is the list of external functions currently present in"
1216 text +=" the Library:"
1217
1218 if len(v):
1219 for ext in v:
1220 text += "\n\n%s (%d inputs, %d outputs):" % \
1221 (ext.getName(), ext.getNumInputs(), ext.getNumOutputs())
1222 text += "\n%s" % ext.getHelp()
1223 else:
1224 text +="\n\nNone"
1225 _dialog = InfoDialog(self,self.window,text,title)
1226 _dialog.run()
1227
1228 def on_maintabs_switch_page(self,notebook,page,pagenum):
1229 print("Page switched to %d" % pagenum)
1230 if pagenum in self.tabs.keys():
1231 self.currentobservertab = pagenum
1232
1233 def create_observer(self,name=None):
1234 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1235 _label = gtk.Label();
1236 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1237 _obs = ObserverTab(xml=_xml, name=name, browser=self, tab=_tab)
1238 _label.set_text(_obs.name)
1239 self.observers.append(_obs)
1240 self.tabs[_tab] = _obs
1241 self.currentobservertab = _tab
1242 return _obs
1243
1244 def sync_observers(self):
1245 for _o in self.observers:
1246 _o.sync()
1247
1248 def delete_event(self, widget, event):
1249 self.do_quit()
1250 return False
1251
1252 def observe(self,instance):
1253 if len(self.observers) ==0:
1254 self.create_observer()
1255 _observer = self.tabs[self.currentobservertab]
1256 _observer.add_instance(instance)
1257
1258 if __name__ == "__main__":
1259 b = Browser();
1260 b.run()

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