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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1117 - (show annotations) (download) (as text)
Thu Jan 11 10:57:24 2007 UTC (17 years, 6 months ago) by johnpye
File MIME type: text/x-python
File size: 36440 byte(s)
Added ability to show all fixed variables in a model using PyGTK interface.
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 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.iconstatusunknown = None
313 self.iconfixed = self.fixedimg.get_pixbuf()
314 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
315 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
316 self.iconunsolved = None
317
318 self.statusicons={
319 ascpy.ASCXX_VAR_STATUS_UNKNOWN: self.iconstatusunknown
320 ,ascpy.ASCXX_VAR_FIXED: self.iconfixed
321 ,ascpy.ASCXX_VAR_SOLVED: self.iconsolved
322 ,ascpy.ASCXX_VAR_ACTIVE: self.iconactive
323 ,ascpy.ASCXX_VAR_UNSOLVED: self.iconunsolved
324 }
325
326
327 self.statusmessages={
328 ascpy.ASCXX_VAR_STATUS_UNKNOWN: "Status unknown"
329 ,ascpy.ASCXX_VAR_FIXED: "Fixed"
330 ,ascpy.ASCXX_VAR_SOLVED: "Converged"
331 ,ascpy.ASCXX_VAR_ACTIVE: "Active (unconverged)"
332 ,ascpy.ASCXX_VAR_UNSOLVED: "Not yet visited"
333 }
334
335 #-------------------
336 # waitwin
337
338 self.waitwin = gtk.gdk.Window(self.window.window,
339 gtk.gdk.screen_width(),
340 gtk.gdk.screen_height(),
341 gtk.gdk.WINDOW_CHILD,
342 0,
343 gtk.gdk.INPUT_ONLY)
344
345 _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
346 self.waitwin.set_cursor(_cursor)
347
348 #-------------------
349 # pixbufs to be used in the error listing
350
351 self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
352 self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
353 self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
354 self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
355
356 #--------------------
357 # pixbufs for solver_var status
358
359 #--------------------
360 # set up the error view
361
362 self.errorview = glade.get_widget("errorview")
363 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
364 self.errorstore = gtk.TreeStore(*errstorecolstypes)
365 errtitles = ["","Location","Message"];
366 self.errorview.set_model(self.errorstore)
367 self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
368
369 i = 0
370 for tvcolumn in self.errcols[:len(errtitles)]:
371 tvcolumn.set_title(errtitles[i])
372 self.errorview.append_column(tvcolumn)
373
374 if i>0:
375 _renderer = gtk.CellRendererText()
376 tvcolumn.pack_start(_renderer, True)
377 tvcolumn.add_attribute(_renderer, 'text', i)
378 if(i==2):
379 tvcolumn.add_attribute(_renderer, 'foreground', 3)
380 tvcolumn.add_attribute(_renderer, 'weight', 4)
381 else:
382 _renderer1 = gtk.CellRendererPixbuf()
383 tvcolumn.pack_start(_renderer1, False)
384 tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
385
386 i = i + 1
387
388
389 #--------------------
390 # set up the error reporter callback
391 self.reporter = ascpy.getReporter()
392 self.reporter.setPythonErrorCallback(self.error_callback)
393
394
395 #-------
396 # Solver engine list
397
398 _slvlist = ascpy.getSolvers()
399 self.solver_engine_menu = gtk.Menu()
400 self.solver_engine_menu.show()
401 self.solver_engine.set_submenu(self.solver_engine_menu)
402 self.solver_engine_menu_dict = {}
403 _fmi = None
404 for _s in _slvlist:
405 _mi = gtk.RadioMenuItem(_fmi,_s.getName(),False)
406 if _fmi==None:
407 _fmi = _mi
408 _mi.show()
409 _mi.connect('toggled',self.on_select_solver_toggled,_s.getName())
410 self.solver_engine_menu.append(_mi)
411 self.solver_engine_menu_dict[_s.getName()]=_mi
412
413 _pref_solver = self.prefs.getStringPref("Solver","engine","QRSlv")
414 _mi = self.solver_engine_menu_dict.get(_pref_solver)
415 if _mi:
416 _mi.set_active(1)
417
418 #--------
419 # Assign an icon to the main window
420
421 self.icon = None
422 if config.ICON_EXTENSION:
423 _iconpath = ""
424 try:
425 _icon = gtk.Image()
426 _iconpath = os.path.join(self.assets_dir,'ascend'+config.ICON_EXTENSION)
427 _icon.set_from_file(_iconpath)
428 _iconpbuf = _icon.get_pixbuf()
429 self.window.set_icon(_iconpbuf)
430 self.icon = _iconpbuf
431 except Exception, e:
432 print "FAILED TO SET APPLICATION ICON PATH '%s': %s" % (_iconpath,str(e))
433 self.reporter.reportError("FAILED to set application icon '%s': %s"
434 % (_iconpath,str(e))
435 )
436
437 #-------------------
438 # set up the module view
439
440 self.modtank = {}
441 self.moduleview = glade.get_widget("moduleview")
442 modulestorecoltypes = [str, str, int] # bool=can-be-instantiated
443 self.modulestore = gtk.TreeStore(*modulestorecoltypes)
444 moduleviewtitles = ["Module name", "Filename"]
445 self.moduleview.set_model(self.modulestore)
446 self.modcols = [ gtk.TreeViewColumn() for _type in modulestorecoltypes]
447 i = 0
448 for modcol in self.modcols[:len(moduleviewtitles)]:
449 modcol.set_title(moduleviewtitles[i])
450 self.moduleview.append_column(modcol)
451 _renderer = gtk.CellRendererText()
452 modcol.pack_start(_renderer, True)
453 modcol.add_attribute(_renderer, 'text', i)
454 modcol.add_attribute(_renderer,'weight',2)
455 i = i + 1
456 self.moduleview.connect("row-activated", self.module_activated )
457
458 #--------------------
459 # set up the methods combobox
460
461 self.methodstore = gtk.ListStore(str)
462 self.methodsel.set_model(self.methodstore)
463 _methodrenderer = gtk.CellRendererText()
464 self.methodsel.pack_start(_methodrenderer, True)
465 self.methodsel.add_attribute(_methodrenderer, 'text',0)
466
467 #--------
468 # set up the instance browser view
469
470 self.modelview = ModelView(self, glade)
471
472 #--------
473 # set up the tabs
474 self.tabs = {}
475 self.activetab = None # most recent observer tab
476
477 #--------
478 # set the state of the 'auto' toggle
479
480 self.is_auto = self.prefs.getBoolPref("Browser","auto_solve",True)
481 self.autotoggle.set_active(self.is_auto)
482 self.automenu.set_active(self.is_auto)
483
484 #--------
485 # tell libascend about this 'browser' object
486
487 print dir(ascpy.Registry())
488 ascpy.Registry().set("browser",self)
489
490 #--------
491 # options
492
493 if(len(args)==1):
494 try:
495 self.do_open(args[0])
496 except RuntimeError,e:
497 self.reporter.reportError(str(e))
498 return
499
500 print "Options: ",self.options
501
502 _model = None
503 if self.options.model:
504 _model = self.options.model
505 print "MODEL: '%s'" % _model
506 elif self.options.auto_sim:
507 _head, _tail = os.path.split(args[0])
508 if(_tail):
509 _model, _ext = os.path.splitext(_tail)
510
511 if _model:
512 try:
513 _t=self.library.findType(_model)
514 try:
515 self.do_sim(_t)
516 if not self.options.model:
517 self.reporter.reportNote("Instantiated self-titled model '%s'" %_model)
518 except RuntimeError, e:
519 self.reporter.reportError("Failed to create instance of '%s': %s"
520 %(_model, str(e))
521 );
522 except RuntimeError, e:
523 if self.options.model:
524 self.reporter.reportError("Unknown model type '%s': %s"
525 %(_model, str(e))
526 );
527
528 def run(self):
529 self.window.show()
530 print_loading_status("ASCEND is now running")
531 gtk.main()
532
533 # ------------------
534 # SOLVER LIST
535
536 def set_solver(self,solvername):
537 """ this sets the active solver in the GUI, which is the default applied to newly instantiated models """
538 self.solver = ascpy.Solver(solvername)
539 self.prefs.setStringPref("Solver","engine",solvername)
540 self.reporter.reportNote("Set solver engine to '%s'" % solvername)
541
542 # --------------------------------------------
543 # MAJOR GUI COMMANDS
544
545 def on_fix_variable_activate(self,*args):
546 self.modelview.on_fix_variable_activate(*args)
547
548 def on_free_variable_activate(self,*args):
549 self.modelview.on_free_variable_activate(*args)
550
551 def on_select_solver_toggled(self,widget,solvername):
552 if widget.get_active():
553 self.set_solver(solvername)
554
555 def do_open(self,filename):
556 # TODO does the user want to lose their work?
557 # TODO do we need to chdir?
558
559 _context = self.statusbar.get_context_id("do_open")
560
561 self.errorstore.clear()
562 self.modelview.clear()
563
564 # self.library.clear()
565
566 print "Filename =",filename
567 self.statusbar.push(_context,"Loading '"+filename+"'")
568 try:
569 self.filename = filename
570 self.library.load(filename)
571 except RuntimeError,e:
572 self.statusbar.pop(_context)
573 raise
574
575 print "Statusbar =",self.statusbar
576 try:
577 self.statusbar.pop(_context)
578 except TypeError,e:
579 print "For some reason, a type error (context=%s,filename=%s): %s" % (_context,filename,e)
580
581 # Load the current list of modules into self.modules
582 self.modtank = {}
583 self.modulestore.clear()
584 modules = self.library.getModules()
585 #self.library.listModules()
586 try:
587 _lll=len(modules)
588 except:
589 _msg = "UNABLE TO ACCESS MODULES LIST. This is bad.\n"+\
590 "Check your SWIG configuration (check for warnings during build)."
591
592 self.reporter.reportError(_msg)
593 raise RuntimeError(_msg)
594
595 for m in reversed(modules):
596 _n = str( m.getName() )
597 _f = str( m.getFilename() )
598 #print "ADDING ROW name %s, file = %s" % (_n, _f)
599 _r = self.modulestore.append(None, [ _n, _f, pango.WEIGHT_NORMAL ])
600 for t in self.library.getModuleTypes(m):
601 _n = t.getName()
602 _hasparams = t.hasParameters()
603 if _hasparams:
604 _w = pango.WEIGHT_NORMAL
605 else:
606 _w = pango.WEIGHT_BOLD
607
608 #print "ADDING TYPE %s" % _n
609 _piter = self.modulestore.append(_r , [ _n, "", _w ])
610 _path = self.modulestore.get_path(_piter)
611 self.modtank[_path]=t
612
613 #print "DONE ADDING MODULES"
614
615 self.sim = None;
616 self.maintabs.set_current_page(0);
617
618 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
619 # for details on how the 'wait cursor' is done.
620 def start_waiting(self, message):
621 self.waitcontext = self.statusbar.get_context_id("waiting")
622 self.statusbar.push(self.waitcontext,message)
623
624 if self.waitwin:
625 self.waitwin.show()
626
627 while gtk.events_pending():
628 gtk.main_iteration()
629
630 def stop_waiting(self):
631 if self.waitwin:
632 self.statusbar.pop(self.waitcontext)
633 self.waitwin.hide()
634
635 def do_sim(self, type_object):
636 self.sim = None;
637 # TODO: clear out old simulation first!
638
639 print "DO_SIM(%s)" % str(type_object.getName())
640 self.start_waiting("Compiling...")
641
642 try:
643 _v = self.prefs.getBoolPref("Compiler","use_relation_sharing",True)
644 ascpy.getCompiler().setUseRelationSharing(_v)
645
646 _v = self.prefs.getBoolPref("Compiler","use_binary_compilation",True)
647 ascpy.getCompiler().setBinaryCompilation(True)
648
649 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim",False)
650
651 self.reporter.reportNote("SIMULATION ASSIGNED")
652 except RuntimeError, e:
653 self.stop_waiting()
654 self.reporter.reportError(str(e))
655 return
656
657 print "...DONE 'getSimulation'"
658 self.stop_waiting()
659
660 # get method names and load them into the GUI
661 self.methodstore.clear()
662 _methods = self.sim.getType().getMethods()
663 _activemethod = None;
664 for _m in _methods:
665 _i = self.methodstore.append([_m.getName()])
666 if _m.getName()=="on_load":
667 self.methodsel.set_active_iter(_i)
668
669 self.modelview.setSimulation(self.sim)
670
671 # run the 'on_load' method
672 self.start_waiting("Running default method...")
673 try:
674 self.reporter.reportNote("SIMULATION CREATED, RUNNING DEFAULT METHOD NOW...")
675 self.sim.runDefaultMethod()
676 except RuntimeError, e:
677 self.stop_waiting()
678 self.reporter.reportError(str(e))
679 return
680 self.stop_waiting()
681
682 self.modelview.refreshtree()
683
684 def do_solve_if_auto(self):
685 if self.is_auto:
686 self.sim.checkInstance()
687 self.do_solve()
688 else:
689 self.sim.processVarStatus()
690 self.modelview.refreshtree()
691
692 self.sync_observers()
693
694 def do_solve(self):
695 if not self.sim:
696 self.reporter.reportError("No model selected yet")
697 return
698
699 try:
700 self.sim.build()
701 except RuntimeError,e:
702 self.reporter.reportError("Couldn't build system: %s",str(e));
703 return
704
705 self.start_waiting("Solving with %s..." % self.solver.getName())
706
707 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
708 reporter = PopupSolverReporter(self,self.sim.getNumVars())
709 else:
710 reporter = SimpleSolverReporter(self)
711
712 try:
713 self.sim.solve(self.solver,reporter)
714 except RuntimeError,e:
715 self.reporter.reportError(str(e))
716
717 self.stop_waiting()
718
719 self.modelview.refreshtree()
720
721 def do_integrate(self):
722 if not self.sim:
723 self.reporter.reportError("No model selected yet")
724 return
725
726 try:
727 self.sim.build()
728 except RuntimeError,e:
729 self.reporter.reportError("Couldn't build system: %s",str(e))
730 return
731
732 integwin = IntegratorWindow(self,self.sim)
733 _integratorreporter = integwin.run()
734 if _integratorreporter!=None:
735 _integratorreporter.run()
736 self.sim.processVarStatus()
737 self.modelview.refreshtree()
738
739
740 def do_check(self):
741 if not self.sim:
742 self.reporter.reportError("No simulation yet")
743 return
744
745 self.start_waiting("Checking system...")
746
747 try:
748 self.sim.checkInstance()
749 self.reporter.reportWarning("System instance check run, check above for error (if any).")
750 # the above gives output but doesn't throw errors or return a status.
751 # ... this is a problem (at the C level)
752
753 status = self.sim.checkDoF()
754 if status==ascpy.ASCXX_DOF_UNDERSPECIFIED:
755 self.on_show_fixable_variables_activate(None)
756 elif status==ascpy.ASCXX_DOF_OVERSPECIFIED:
757 self.on_show_freeable_variables_activate(None)
758 elif status==ascpy.ASCXX_DOF_STRUCT_SINGULAR:
759 if not self.sim.checkStructuralSingularity():
760 sing = self.sim.getSingularityInfo()
761 title = "Structural singularity"
762 text = title
763 text += "\n\nThe singularity can be reduced by freeing the following variables:"
764 msgs = {
765 "The singularity can be reduced by freeing the following variables" : sing.freeablevars
766 ,"Relations involved in the structural singularity" : sing.rels
767 ,"Variables involved in the structural singularity" : sing.vars
768 }
769 for k,v in msgs.iteritems():
770 text+="\n\n%s:" % k
771 if len(v):
772 _l = [j.getName() for j in v]
773 _l.sort()
774 text+= "\n\t" + "\n\t".join(_l)
775 else:
776 text += "\nnone"
777
778 _dialog = InfoDialog(self,self.window,text,title)
779 _dialog.run()
780 else:
781 self.reporter.reportNote("System DoF check OK")
782
783 except RuntimeError, e:
784 self.stop_waiting()
785 self.reporter.reportError(str(e))
786 return
787
788 self.stop_waiting()
789 self.modelview.refreshtree()
790
791 def do_method(self,method):
792 if not self.sim:
793 self.reporter.reportError("No model selected yet")
794
795 try:
796 self.sim.run(method)
797 except RuntimeError,e:
798 self.reporter.reportError(str(e))
799
800 self.sim.processVarStatus()
801 self.modelview.refreshtree()
802
803 def do_quit(self):
804 print_loading_status("Saving window location")
805 self.reporter.clearPythonErrorCallback()
806
807 _w,_h = self.window.get_size()
808 _t,_l = self.window.get_position()
809 _display = self.window.get_screen().get_display().get_name()
810 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
811
812 _p = self.browserpaned.get_position()
813 self.prefs.setGeometryValue(_display,"browserpaned",_p);
814
815 print_loading_status("Saving current directory")
816 self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
817
818 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
819
820 print_loading_status("Saving preferences")
821 # causes prefs to be saved unless they are still being used elsewher
822 del(self.prefs)
823
824 print_loading_status("Clearing error callback")
825 self.reporter.clearPythonErrorCallback()
826
827 print_loading_status("Closing down GTK")
828 gtk.main_quit()
829
830 print_loading_status("Clearing library")
831 self.library.clear()
832
833 print_loading_status("Quitting")
834
835 return False
836
837 def on_tools_sparsity_click(self,*args):
838
839 self.reporter.reportNote("Preparing incidence matrix...")
840 _im = self.sim.getIncidenceMatrix();
841
842 self.reporter.reportNote("Plotting incidence matrix...")
843
844 _sp = IncidenceMatrixWindow(_im);
845 _sp.run();
846
847 def on_tools_repaint_tree_activate(self,*args):
848 self.reporter.reportNote("Repainting model view...")
849 self.modelview.refreshtree()
850
851 def on_diagnose_blocks_click(self,*args):
852 try:
853 _bl = self.sim.getActiveBlock()
854 except RuntimeError, e:
855 self.reporter.reportError(str(e))
856 return
857 _db = DiagnoseWindow(self,_bl)
858 _db.run();
859
860 def on_add_observer_click(self,*args):
861 self.create_observer()
862
863 def on_keep_observed_click(self,*args):
864 print "KEEPING..."
865 if len(self.observers) <= 0:
866 self.reporter.reportError("No observer defined!")
867 return
868 self.tabs[self.currentobservertab].do_add_row()
869
870 def on_copy_observer_matrix_click(self,*args):
871 if self.clip == None:
872 self.clip = gtk.Clipboard()
873
874 if len(self.observers) <= 0:
875 self.reporter.reportError("No observer defined!")
876 return
877 self.tabs[self.currentobservertab].copy_to_clipboard(self.clip)
878
879 def on_use_relation_sharing_toggle(self,checkmenuitem,*args):
880 _v = checkmenuitem.get_active()
881 self.prefs.setBoolPref("Compiler","use_relation_sharing",_v)
882 self.reporter.reportNote("Relation sharing set to "+str(_v))
883 self.use_binary_compilation.set_sensitive(_v);
884
885 def on_use_binary_compilation_toggle(self,checkmenuitem,*args):
886 _v = checkmenuitem.get_active()
887 self.prefs.setBoolPref("Compiler","use_binary_compilation",_v)
888 self.reporter.reportNote("Binary compilation set to "+str(_v))
889
890 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
891 _v = checkmenuitem.get_active()
892 self.prefs.setBoolPref("SolverReporter","show_popup",_v)
893 print "SET TO",_v
894
895 def on_close_on_converged_toggle(self,checkmenuitem,*args):
896 _v = checkmenuitem.get_active()
897 self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
898
899 def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
900 _v = checkmenuitem.get_active()
901 self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
902
903 def on_show_variables_near_bounds_activate(self,*args):
904 _epsilon = 1e-4;
905 text = "Variables Near Bounds"
906 title=text;
907 text += "\n"
908 _vars = self.sim.getVariablesNearBounds(_epsilon)
909 if len(_vars):
910 for _v in _vars:
911 text += "\n%s"%_v.getName()
912 else:
913 text +="\nnone"
914 _dialog = InfoDialog(self,self.window,text,title)
915 _dialog.run()
916
917 # --------------------------------------------
918 # MODULE LIST
919
920 def module_activated(self, treeview, path, column, *args):
921 modules = self.library.getModules()
922 print "PATH",path
923 if len(path)==1:
924 self.reporter.reportNote("Launching of external editor not yet implemented")
925 elif len(path)==2:
926 if(self.modtank.has_key(path)):
927 _type = self.modtank[path];
928 self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
929 self.do_sim(_type)
930 else:
931 self.reporter.reportError("Didn't find type corresponding to row")
932
933 # ----------------------------------
934 # ERROR PANEL
935
936 def get_error_row_data(self,sev,filename,line,msg):
937 try:
938 _sevicon = {
939 0 : self.iconok
940 ,1 : self.iconinfo
941 ,2 : self.iconwarning
942 ,4 : self.iconerror
943 ,8 : self.iconinfo
944 ,16 : self.iconwarning
945 ,32 : self.iconerror
946 ,64 : self.iconerror
947 }[sev]
948 except KeyError:
949 _sevicon = self.iconerror
950
951 _fontweight = pango.WEIGHT_NORMAL
952 if sev==32 or sev==64:
953 _fontweight = pango.WEIGHT_BOLD
954
955 _fgcolor = "black"
956 if sev==8:
957 _fgcolor = "#888800"
958 elif sev==16:
959 _fgcolor = "#884400"
960 elif sev==32 or sev==64:
961 _fgcolor = "#880000"
962 elif sev==0:
963 _fgcolor = BROWSER_FIXED_COLOR
964
965 if not filename and not line:
966 _fileline = ""
967 else:
968 if(len(filename) > 25):
969 filename = "..."+filename[-22:]
970 _fileline = filename + ":" + str(line)
971
972 _res = (_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight)
973 #print _res
974 return _res
975
976 def error_callback(self,sev,filename,line,msg):
977 #print "SEV =",sev
978 #print "FILENAME =",filename
979 #print "LINE =",line
980 #print "MSG =",msg
981 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
982 path = self.errorstore.get_path(pos)
983 col = self.errorview.get_column(3)
984 self.errorview.scroll_to_cell(path,col)
985 return 0;
986
987 # --------------------------------
988 # BUTTON METHODS
989
990 def open_click(self,*args):
991 #print_loading_status("CURRENT FILEOPENPATH is",self.fileopenpath)
992 dialog = gtk.FileChooserDialog("Open ASCEND model...",
993 self.window,
994 gtk.FILE_CHOOSER_ACTION_OPEN,
995 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
996 )
997 dialog.set_current_folder(self.fileopenpath)
998 dialog.set_default_response(gtk.RESPONSE_OK)
999 dialog.set_transient_for(self.window)
1000 dialog.set_modal(True)
1001
1002 filter = gtk.FileFilter()
1003 filter.set_name("*.a4c, *.a4l")
1004 filter.add_pattern("*.[Aa]4[Cc]")
1005 filter.add_pattern("*.[Aa]4[Ll]")
1006 dialog.add_filter(filter)
1007
1008 filter = gtk.FileFilter()
1009 filter.set_name("All files")
1010 filter.add_pattern("*")
1011 dialog.add_filter(filter)
1012
1013 response = dialog.run()
1014 _filename = dialog.get_filename()
1015 print "\nFILENAME SELECTED:",_filename
1016
1017 _path = dialog.get_current_folder()
1018 if _path:
1019 self.fileopenpath = _path
1020
1021 dialog.hide()
1022
1023 if response == gtk.RESPONSE_OK:
1024 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
1025 self.library.clear()
1026 self.do_open( _filename)
1027
1028 def reload_click(self,*args):
1029 _type = None
1030 if(self.sim):
1031 _type = self.sim.getType().getName().toString();
1032
1033 self.library.clear()
1034
1035 try:
1036 self.do_open(self.filename)
1037 if _type:
1038 _t = self.library.findType(_type)
1039 self.do_sim(_t)
1040 except RuntimeError,e:
1041 self.reporter.reportError(str(e))
1042
1043 def props_activate(self,widget,*args):
1044 return self.modelview.props_activate(self,widget,*args)
1045
1046 def observe_activate(self,widget,*args):
1047 return self.modelview.observe_activate(self,widget,*args)
1048
1049 def solve_click(self,*args):
1050 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
1051 self.do_solve()
1052
1053 def console_click(self,*args):
1054 try:
1055 console.start(self)
1056 except RuntimeError,e:
1057 self.reporter.reportError("Unable to start console: "+str(e));
1058
1059 def integrate_click(self,*args):
1060 self.do_integrate()
1061
1062 def check_click(self,*args):
1063 self.do_check()
1064 #self.reporter.reportError("CHECK clicked")
1065
1066 def preferences_click(self,*args):
1067 if not self.sim:
1068 self.reporter.reportError("No simulation created yet!");
1069 self.sim.setSolver(self.solver)
1070 _paramswin = SolverParametersWindow(self)
1071 _paramswin.show()
1072
1073 def methodrun_click(self,*args):
1074 _sel = self.methodsel.get_active_text()
1075 if _sel:
1076 _method = None
1077 _methods = self.sim.getType().getMethods()
1078 for _m in _methods:
1079 if _m.getName()==_sel:
1080 _method = _m
1081 if not _method:
1082 self.reporter.reportError("Method is not valid")
1083 return
1084 self.do_method(_method)
1085 else:
1086 self.reporter.reportError("No method selected")
1087
1088 def auto_toggle(self,button,*args):
1089 self.is_auto = button.get_active()
1090 if hasattr(self,'automenu'):
1091 self.automenu.set_active(self.is_auto)
1092 else:
1093 raise RuntimeError("no automenu")
1094
1095 #if self.is_auto:
1096 # self.reporter.reportSuccess("Auto mode is now ON")
1097 #else:
1098 # self.reporter.reportSuccess("Auto mode is now OFF")
1099
1100 def on_file_quit_click(self,*args):
1101 self.do_quit()
1102
1103 def on_tools_auto_toggle(self,checkmenuitem,*args):
1104 self.is_auto = checkmenuitem.get_active()
1105 self.autotoggle.set_active(self.is_auto)
1106
1107 def on_help_about_click(self,*args):
1108 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1109 _about = _xml.get_widget("aboutdialog")
1110 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1111 _about.set_transient_for(self.window);
1112 _about.set_version(config.VERSION)
1113 _about.run()
1114 _about.destroy()
1115
1116 def on_help_contents_click(self,*args):
1117 _help = Help(HELP_ROOT)
1118 _help.run()
1119
1120 def on_help_check_for_updates_click(self,*args):
1121 v = VersionCheck()
1122 title = "Check for updates"
1123 text = "Your version is %s\n" % config.VERSION
1124 try:
1125 v.check()
1126 if config.VERSION==v.latest:
1127 text += "You are running the latest released version"
1128 else:
1129 text += "Latest version is %s\n" % v.latest
1130 if v.info:
1131 text += "Get more info at %s\n" % v.info
1132 if v.download:
1133 text += "Download from %s\n" % v.download
1134 except Exception, e:
1135 text += "\nUnable to check version\n"
1136 text += str(e)
1137
1138 _dialog = InfoDialog(self,self.window,text,title)
1139 _dialog.run()
1140
1141 def on_show_fixable_variables_activate(self,*args):
1142 try:
1143 v = self.sim.getFixableVariables()
1144 except RuntimeError,e:
1145 self.reporter.reportError(str(e))
1146 text = "Fixable Variables"
1147 title = text
1148 text += "\n"
1149 if len(v):
1150 for var in v:
1151 text += "\n%s"%var
1152 else:
1153 text += "\nnone"
1154 _dialog = InfoDialog(self,self.window,text,title)
1155 _dialog.run()
1156
1157 def on_show_fixed_vars_activate(self,*args):
1158 try:
1159 v = self.sim.getFixedVariables()
1160 except RuntimeError,e:
1161 self.reporter.reportError(str(e))
1162 text = "Fixed Variables"
1163 title = text
1164 text += "\n"
1165 if len(v):
1166 for var in v:
1167 text += "\n%s"%var
1168 else:
1169 text += "\nnone"
1170 _dialog = InfoDialog(self,self.window,text,title)
1171 _dialog.run()
1172
1173
1174 def on_show_freeable_variables_activate(self,*args):
1175 try:
1176 v = self.sim.getFreeableVariables()
1177 except RuntimeError,e:
1178 self.reporter.reportError(str(e))
1179
1180 text = "Freeable Variables"
1181 title = text
1182 text += "\n"
1183 if len(v):
1184 for var in v:
1185 text += "\n%s" % var
1186 else:
1187 text += "\nnone"
1188 _dialog = InfoDialog(self,self.window,text,title)
1189 _dialog.run()
1190
1191 def on_show_external_functions_activate(self,*args):
1192 v = self.library.getExtMethods()
1193 text = "External Functions"
1194 title = text
1195 text +="\nHere is the list of external functions currently present in"
1196 text +=" the Library:"
1197
1198 if len(v):
1199 for ext in v:
1200 text += "\n\n%s (%d inputs, %d outputs):" % \
1201 (ext.getName(), ext.getNumInputs(), ext.getNumOutputs())
1202 text += "\n%s" % ext.getHelp()
1203 else:
1204 text +="\n\nNone"
1205 _dialog = InfoDialog(self,self.window,text,title)
1206 _dialog.run()
1207
1208 def on_maintabs_switch_page(self,notebook,page,pagenum):
1209 print("Page switched to %d" % pagenum)
1210 if pagenum in self.tabs.keys():
1211 self.currentobservertab = pagenum
1212
1213 def create_observer(self,name=None):
1214 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1215 _label = gtk.Label();
1216 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1217 _obs = ObserverTab(xml=_xml, name=name, browser=self, tab=_tab)
1218 _label.set_text(_obs.name)
1219 self.observers.append(_obs)
1220 self.tabs[_tab] = _obs
1221 self.currentobservertab = _tab
1222 return _obs
1223
1224 def sync_observers(self):
1225 for _o in self.observers:
1226 _o.sync()
1227
1228 def delete_event(self, widget, event):
1229 self.do_quit()
1230 return False
1231
1232 def observe(self,instance):
1233 if len(self.observers) ==0:
1234 self.create_observer()
1235 _observer = self.tabs[self.currentobservertab]
1236 _observer.add_instance(instance)
1237
1238 if __name__ == "__main__":
1239 b = Browser();
1240 b.run()

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