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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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