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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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