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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1157 - (show annotations) (download) (as text)
Tue Jan 16 12:35:46 2007 UTC (13 years, 7 months ago) by johnpye
File MIME type: text/x-python
File size: 37175 byte(s)
Fixed escaped paths in SConstruct.
Added some more keywords to gedit syntax definition.

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 msgs = {
764 "The singularity can be reduced by freeing the following variables" : sing.freeablevars
765 ,"Relations involved in the structural singularity" : sing.rels
766 ,"Variables involved in the structural singularity" : sing.vars
767 }
768 for k,v in msgs.iteritems():
769 text+="\n\n%s:" % k
770 if len(v):
771 _l = [j.getName() for j in v]
772 _l.sort()
773 text+= "\n\t" + "\n\t".join(_l)
774 else:
775 text += "\nnone"
776
777 _dialog = InfoDialog(self,self.window,text,title)
778 _dialog.run()
779 else:
780 self.reporter.reportNote("System DoF check OK")
781
782 except RuntimeError, e:
783 self.stop_waiting()
784 self.reporter.reportError(str(e))
785 return
786
787 self.stop_waiting()
788 self.modelview.refreshtree()
789
790 def do_method(self,method):
791 if not self.sim:
792 self.reporter.reportError("No model selected yet")
793
794 try:
795 self.sim.run(method)
796 except RuntimeError,e:
797 self.reporter.reportError(str(e))
798
799 self.sim.processVarStatus()
800 self.modelview.refreshtree()
801
802 def do_quit(self):
803 print_loading_status("Saving window location")
804 self.reporter.clearPythonErrorCallback()
805
806 _w,_h = self.window.get_size()
807 _t,_l = self.window.get_position()
808 _display = self.window.get_screen().get_display().get_name()
809 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
810
811 _p = self.browserpaned.get_position()
812 self.prefs.setGeometryValue(_display,"browserpaned",_p);
813
814 print_loading_status("Saving current directory")
815 self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
816
817 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
818
819 print_loading_status("Saving preferences")
820 # causes prefs to be saved unless they are still being used elsewher
821 del(self.prefs)
822
823 print_loading_status("Clearing error callback")
824 self.reporter.clearPythonErrorCallback()
825
826 print_loading_status("Closing down GTK")
827 gtk.main_quit()
828
829 print_loading_status("Clearing library")
830 self.library.clear()
831
832 print_loading_status("Quitting")
833
834 return False
835
836 def on_tools_sparsity_click(self,*args):
837
838 self.reporter.reportNote("Preparing incidence matrix...")
839 _im = self.sim.getIncidenceMatrix();
840
841 self.reporter.reportNote("Plotting incidence matrix...")
842
843 _sp = IncidenceMatrixWindow(_im);
844 _sp.run();
845
846 def on_tools_repaint_tree_activate(self,*args):
847 self.reporter.reportNote("Repainting model view...")
848 self.modelview.refreshtree()
849
850 def on_diagnose_blocks_click(self,*args):
851 try:
852 _bl = self.sim.getActiveBlock()
853 except RuntimeError, e:
854 self.reporter.reportError(str(e))
855 return
856 _db = DiagnoseWindow(self,_bl)
857 _db.run();
858
859 def on_add_observer_click(self,*args):
860 self.create_observer()
861
862 def on_keep_observed_click(self,*args):
863 print "KEEPING..."
864 if len(self.observers) <= 0:
865 self.reporter.reportError("No observer defined!")
866 return
867 self.tabs[self.currentobservertab].do_add_row()
868
869 def on_copy_observer_matrix_click(self,*args):
870 if self.clip == None:
871 self.clip = gtk.Clipboard()
872
873 if len(self.observers) <= 0:
874 self.reporter.reportError("No observer defined!")
875 return
876 self.tabs[self.currentobservertab].copy_to_clipboard(self.clip)
877
878 def on_use_relation_sharing_toggle(self,checkmenuitem,*args):
879 _v = checkmenuitem.get_active()
880 self.prefs.setBoolPref("Compiler","use_relation_sharing",_v)
881 self.reporter.reportNote("Relation sharing set to "+str(_v))
882 self.use_binary_compilation.set_sensitive(_v);
883
884 def on_use_binary_compilation_toggle(self,checkmenuitem,*args):
885 _v = checkmenuitem.get_active()
886 self.prefs.setBoolPref("Compiler","use_binary_compilation",_v)
887 self.reporter.reportNote("Binary compilation set to "+str(_v))
888
889 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
890 _v = checkmenuitem.get_active()
891 self.prefs.setBoolPref("SolverReporter","show_popup",_v)
892 print "SET TO",_v
893
894 def on_close_on_converged_toggle(self,checkmenuitem,*args):
895 _v = checkmenuitem.get_active()
896 self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
897
898 def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
899 _v = checkmenuitem.get_active()
900 self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
901
902 def on_show_variables_near_bounds_activate(self,*args):
903 _epsilon = 1e-4;
904 text = "Variables Near Bounds"
905 title=text;
906 text += "\n"
907 _vars = self.sim.getVariablesNearBounds(_epsilon)
908 if len(_vars):
909 for _v in _vars:
910 text += "\n%s"%_v.getName()
911 else:
912 text +="\nnone"
913 _dialog = InfoDialog(self,self.window,text,title)
914 _dialog.run()
915
916 def on_show_vars_far_from_nominals_activate(self,*args):
917 _bignum = self.prefs.getRealPref("Browser","far_from_nominals",10);
918 text = "Variables Far from Nominals"
919 title=text;
920 text += "\n"
921 _vars = self.sim.getVariablesFarFromNominals(_bignum)
922 if len(_vars):
923 for _v in _vars:
924 text += "\n%s"%_v.getName()
925 else:
926 text +="\nnone"
927
928 text+="\n\nAbove calculated using a relative error of %f" % float(_bignum)
929 text+="\nModify this value in .ascend.ini, section '[Browswer]', key 'far_from_nominals'."
930 _dialog = InfoDialog(self,self.window,text,title)
931 _dialog.run()
932
933 # --------------------------------------------
934 # MODULE LIST
935
936 def module_activated(self, treeview, path, column, *args):
937 modules = self.library.getModules()
938 print "PATH",path
939 if len(path)==1:
940 self.reporter.reportNote("Launching of external editor not yet implemented")
941 elif len(path)==2:
942 if(self.modtank.has_key(path)):
943 _type = self.modtank[path];
944 self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
945 self.do_sim(_type)
946 else:
947 self.reporter.reportError("Didn't find type corresponding to row")
948
949 # ----------------------------------
950 # ERROR PANEL
951
952 def get_error_row_data(self,sev,filename,line,msg):
953 try:
954 _sevicon = {
955 0 : self.iconok
956 ,1 : self.iconinfo
957 ,2 : self.iconwarning
958 ,4 : self.iconerror
959 ,8 : self.iconinfo
960 ,16 : self.iconwarning
961 ,32 : self.iconerror
962 ,64 : self.iconerror
963 }[sev]
964 except KeyError:
965 _sevicon = self.iconerror
966
967 _fontweight = pango.WEIGHT_NORMAL
968 if sev==32 or sev==64:
969 _fontweight = pango.WEIGHT_BOLD
970
971 _fgcolor = "black"
972 if sev==8:
973 _fgcolor = "#888800"
974 elif sev==16:
975 _fgcolor = "#884400"
976 elif sev==32 or sev==64:
977 _fgcolor = "#880000"
978 elif sev==0:
979 _fgcolor = BROWSER_FIXED_COLOR
980
981 if not filename and not line:
982 _fileline = ""
983 else:
984 if(len(filename) > 25):
985 filename = "..."+filename[-22:]
986 _fileline = filename + ":" + str(line)
987
988 _res = (_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight)
989 #print _res
990 return _res
991
992 def error_callback(self,sev,filename,line,msg):
993 #print "SEV =",sev
994 #print "FILENAME =",filename
995 #print "LINE =",line
996 #print "MSG =",msg
997 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
998 path = self.errorstore.get_path(pos)
999 col = self.errorview.get_column(3)
1000 self.errorview.scroll_to_cell(path,col)
1001 return 0;
1002
1003 # --------------------------------
1004 # BUTTON METHODS
1005
1006 def open_click(self,*args):
1007 #print_loading_status("CURRENT FILEOPENPATH is",self.fileopenpath)
1008 dialog = gtk.FileChooserDialog("Open ASCEND model...",
1009 self.window,
1010 gtk.FILE_CHOOSER_ACTION_OPEN,
1011 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
1012 )
1013 dialog.set_current_folder(self.fileopenpath)
1014 dialog.set_default_response(gtk.RESPONSE_OK)
1015 dialog.set_transient_for(self.window)
1016 dialog.set_modal(True)
1017
1018 filter = gtk.FileFilter()
1019 filter.set_name("*.a4c, *.a4l")
1020 filter.add_pattern("*.[Aa]4[Cc]")
1021 filter.add_pattern("*.[Aa]4[Ll]")
1022 dialog.add_filter(filter)
1023
1024 filter = gtk.FileFilter()
1025 filter.set_name("All files")
1026 filter.add_pattern("*")
1027 dialog.add_filter(filter)
1028
1029 response = dialog.run()
1030 _filename = dialog.get_filename()
1031 print "\nFILENAME SELECTED:",_filename
1032
1033 _path = dialog.get_current_folder()
1034 if _path:
1035 self.fileopenpath = _path
1036
1037 dialog.hide()
1038
1039 if response == gtk.RESPONSE_OK:
1040 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
1041 self.library.clear()
1042 self.do_open( _filename)
1043
1044 def reload_click(self,*args):
1045 _type = None
1046 if(self.sim):
1047 _type = self.sim.getType().getName().toString();
1048
1049 self.library.clear()
1050
1051 try:
1052 self.do_open(self.filename)
1053 if _type:
1054 _t = self.library.findType(_type)
1055 self.do_sim(_t)
1056 except RuntimeError,e:
1057 self.reporter.reportError(str(e))
1058
1059 def props_activate(self,widget,*args):
1060 return self.modelview.props_activate(self,widget,*args)
1061
1062 def observe_activate(self,widget,*args):
1063 return self.modelview.observe_activate(self,widget,*args)
1064
1065 def solve_click(self,*args):
1066 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
1067 self.do_solve()
1068
1069 def console_click(self,*args):
1070 try:
1071 console.start(self)
1072 except RuntimeError,e:
1073 self.reporter.reportError("Unable to start console: "+str(e));
1074
1075 def integrate_click(self,*args):
1076 self.do_integrate()
1077
1078 def check_click(self,*args):
1079 self.do_check()
1080 #self.reporter.reportError("CHECK clicked")
1081
1082 def preferences_click(self,*args):
1083 if not self.sim:
1084 self.reporter.reportError("No simulation created yet!");
1085 self.sim.setSolver(self.solver)
1086 _params = self.sim.getParameters()
1087 _paramswin = SolverParametersWindow(
1088 browser=self
1089 ,params=_params
1090 ,name=self.solver.getName()
1091 )
1092 if _paramswin.run() == gtk.RESPONSE_OK:
1093 print "PARAMS UPDATED"
1094 self.sim.setParameters(_paramswin.params)
1095 else:
1096 print "PARAMS NOT UPDATED"
1097
1098 def methodrun_click(self,*args):
1099 _sel = self.methodsel.get_active_text()
1100 if _sel:
1101 _method = None
1102 _methods = self.sim.getType().getMethods()
1103 for _m in _methods:
1104 if _m.getName()==_sel:
1105 _method = _m
1106 if not _method:
1107 self.reporter.reportError("Method is not valid")
1108 return
1109 self.do_method(_method)
1110 else:
1111 self.reporter.reportError("No method selected")
1112
1113 def auto_toggle(self,button,*args):
1114 self.is_auto = button.get_active()
1115 if hasattr(self,'automenu'):
1116 self.automenu.set_active(self.is_auto)
1117 else:
1118 raise RuntimeError("no automenu")
1119
1120 #if self.is_auto:
1121 # self.reporter.reportSuccess("Auto mode is now ON")
1122 #else:
1123 # self.reporter.reportSuccess("Auto mode is now OFF")
1124
1125 def on_file_quit_click(self,*args):
1126 self.do_quit()
1127
1128 def on_tools_auto_toggle(self,checkmenuitem,*args):
1129 self.is_auto = checkmenuitem.get_active()
1130 self.autotoggle.set_active(self.is_auto)
1131
1132 def on_help_about_click(self,*args):
1133 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1134 _about = _xml.get_widget("aboutdialog")
1135 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1136 _about.set_transient_for(self.window);
1137 _about.set_version(config.VERSION)
1138 _about.run()
1139 _about.destroy()
1140
1141 def on_help_contents_click(self,*args):
1142 _help = Help(HELP_ROOT)
1143 _help.run()
1144
1145 def on_help_check_for_updates_click(self,*args):
1146 v = VersionCheck()
1147 title = "Check for updates"
1148 text = "Your version is %s\n" % config.VERSION
1149 try:
1150 v.check()
1151 if config.VERSION==v.latest:
1152 text += "You are running the latest released version"
1153 else:
1154 text += "Latest version is %s\n" % v.latest
1155 if v.info:
1156 text += "Get more info at %s\n" % v.info
1157 if v.download:
1158 text += "Download from %s\n" % v.download
1159 except Exception, e:
1160 text += "\nUnable to check version\n"
1161 text += str(e)
1162
1163 _dialog = InfoDialog(self,self.window,text,title)
1164 _dialog.run()
1165
1166 def on_show_fixable_variables_activate(self,*args):
1167 try:
1168 v = self.sim.getFixableVariables()
1169 except RuntimeError,e:
1170 self.reporter.reportError(str(e))
1171 text = "Fixable Variables"
1172 title = text
1173 text += "\n"
1174 if len(v):
1175 for var in v:
1176 text += "\n%s"%var
1177 else:
1178 text += "\nnone"
1179 _dialog = InfoDialog(self,self.window,text,title)
1180 _dialog.run()
1181
1182 def on_show_fixed_vars_activate(self,*args):
1183 try:
1184 v = self.sim.getFixedVariables()
1185 except RuntimeError,e:
1186 self.reporter.reportError(str(e))
1187 text = "Fixed Variables"
1188 title = text
1189 text += "\n"
1190 if len(v):
1191 for var in v:
1192 text += "\n%s"%var
1193 else:
1194 text += "\nnone"
1195 _dialog = InfoDialog(self,self.window,text,title)
1196 _dialog.run()
1197
1198
1199 def on_show_freeable_variables_activate(self,*args):
1200 try:
1201 v = self.sim.getFreeableVariables()
1202 except RuntimeError,e:
1203 self.reporter.reportError(str(e))
1204
1205 text = "Freeable Variables"
1206 title = text
1207 text += "\n"
1208 if len(v):
1209 for var in v:
1210 text += "\n%s" % var
1211 else:
1212 text += "\nnone"
1213 _dialog = InfoDialog(self,self.window,text,title)
1214 _dialog.run()
1215
1216 def on_show_external_functions_activate(self,*args):
1217 v = self.library.getExtMethods()
1218 text = "External Functions"
1219 title = text
1220 text +="\nHere is the list of external functions currently present in"
1221 text +=" the Library:"
1222
1223 if len(v):
1224 for ext in v:
1225 text += "\n\n%s (%d inputs, %d outputs):" % \
1226 (ext.getName(), ext.getNumInputs(), ext.getNumOutputs())
1227 text += "\n%s" % ext.getHelp()
1228 else:
1229 text +="\n\nNone"
1230 _dialog = InfoDialog(self,self.window,text,title)
1231 _dialog.run()
1232
1233 def on_maintabs_switch_page(self,notebook,page,pagenum):
1234 print("Page switched to %d" % pagenum)
1235 if pagenum in self.tabs.keys():
1236 self.currentobservertab = pagenum
1237
1238 def create_observer(self,name=None):
1239 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1240 _label = gtk.Label();
1241 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1242 _obs = ObserverTab(xml=_xml, name=name, browser=self, tab=_tab)
1243 _label.set_text(_obs.name)
1244 self.observers.append(_obs)
1245 self.tabs[_tab] = _obs
1246 self.currentobservertab = _tab
1247 return _obs
1248
1249 def sync_observers(self):
1250 for _o in self.observers:
1251 _o.sync()
1252
1253 def delete_event(self, widget, event):
1254 self.do_quit()
1255 return False
1256
1257 def observe(self,instance):
1258 if len(self.observers) ==0:
1259 self.create_observer()
1260 _observer = self.tabs[self.currentobservertab]
1261 _observer.add_instance(instance)
1262
1263 if __name__ == "__main__":
1264 b = Browser();
1265 b.run()

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