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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1147 - (show annotations) (download) (as text)
Mon Jan 15 14:37:48 2007 UTC (13 years ago) by johnpye
File MIME type: text/x-python
File size: 37261 byte(s)
Fixed far_from_nominals pref
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 def on_show_vars_far_from_nominals_activate(self,*args):
918 _bignum = self.prefs.getRealPref("Browser","far_from_nominals",10);
919 text = "Variables Far from Nominals"
920 title=text;
921 text += "\n"
922 _vars = self.sim.getVariablesFarFromNominals(_bignum)
923 if len(_vars):
924 for _v in _vars:
925 text += "\n%s"%_v.getName()
926 else:
927 text +="\nnone"
928
929 text+="\n\nAbove calculated using a relative error of %f" % float(_bignum)
930 text+="\nModify this value in .ascend.ini, section '[Browswer]', key 'far_from_nominals'."
931 _dialog = InfoDialog(self,self.window,text,title)
932 _dialog.run()
933
934 # --------------------------------------------
935 # MODULE LIST
936
937 def module_activated(self, treeview, path, column, *args):
938 modules = self.library.getModules()
939 print "PATH",path
940 if len(path)==1:
941 self.reporter.reportNote("Launching of external editor not yet implemented")
942 elif len(path)==2:
943 if(self.modtank.has_key(path)):
944 _type = self.modtank[path];
945 self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
946 self.do_sim(_type)
947 else:
948 self.reporter.reportError("Didn't find type corresponding to row")
949
950 # ----------------------------------
951 # ERROR PANEL
952
953 def get_error_row_data(self,sev,filename,line,msg):
954 try:
955 _sevicon = {
956 0 : self.iconok
957 ,1 : self.iconinfo
958 ,2 : self.iconwarning
959 ,4 : self.iconerror
960 ,8 : self.iconinfo
961 ,16 : self.iconwarning
962 ,32 : self.iconerror
963 ,64 : self.iconerror
964 }[sev]
965 except KeyError:
966 _sevicon = self.iconerror
967
968 _fontweight = pango.WEIGHT_NORMAL
969 if sev==32 or sev==64:
970 _fontweight = pango.WEIGHT_BOLD
971
972 _fgcolor = "black"
973 if sev==8:
974 _fgcolor = "#888800"
975 elif sev==16:
976 _fgcolor = "#884400"
977 elif sev==32 or sev==64:
978 _fgcolor = "#880000"
979 elif sev==0:
980 _fgcolor = BROWSER_FIXED_COLOR
981
982 if not filename and not line:
983 _fileline = ""
984 else:
985 if(len(filename) > 25):
986 filename = "..."+filename[-22:]
987 _fileline = filename + ":" + str(line)
988
989 _res = (_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight)
990 #print _res
991 return _res
992
993 def error_callback(self,sev,filename,line,msg):
994 #print "SEV =",sev
995 #print "FILENAME =",filename
996 #print "LINE =",line
997 #print "MSG =",msg
998 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
999 path = self.errorstore.get_path(pos)
1000 col = self.errorview.get_column(3)
1001 self.errorview.scroll_to_cell(path,col)
1002 return 0;
1003
1004 # --------------------------------
1005 # BUTTON METHODS
1006
1007 def open_click(self,*args):
1008 #print_loading_status("CURRENT FILEOPENPATH is",self.fileopenpath)
1009 dialog = gtk.FileChooserDialog("Open ASCEND model...",
1010 self.window,
1011 gtk.FILE_CHOOSER_ACTION_OPEN,
1012 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
1013 )
1014 dialog.set_current_folder(self.fileopenpath)
1015 dialog.set_default_response(gtk.RESPONSE_OK)
1016 dialog.set_transient_for(self.window)
1017 dialog.set_modal(True)
1018
1019 filter = gtk.FileFilter()
1020 filter.set_name("*.a4c, *.a4l")
1021 filter.add_pattern("*.[Aa]4[Cc]")
1022 filter.add_pattern("*.[Aa]4[Ll]")
1023 dialog.add_filter(filter)
1024
1025 filter = gtk.FileFilter()
1026 filter.set_name("All files")
1027 filter.add_pattern("*")
1028 dialog.add_filter(filter)
1029
1030 response = dialog.run()
1031 _filename = dialog.get_filename()
1032 print "\nFILENAME SELECTED:",_filename
1033
1034 _path = dialog.get_current_folder()
1035 if _path:
1036 self.fileopenpath = _path
1037
1038 dialog.hide()
1039
1040 if response == gtk.RESPONSE_OK:
1041 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
1042 self.library.clear()
1043 self.do_open( _filename)
1044
1045 def reload_click(self,*args):
1046 _type = None
1047 if(self.sim):
1048 _type = self.sim.getType().getName().toString();
1049
1050 self.library.clear()
1051
1052 try:
1053 self.do_open(self.filename)
1054 if _type:
1055 _t = self.library.findType(_type)
1056 self.do_sim(_t)
1057 except RuntimeError,e:
1058 self.reporter.reportError(str(e))
1059
1060 def props_activate(self,widget,*args):
1061 return self.modelview.props_activate(self,widget,*args)
1062
1063 def observe_activate(self,widget,*args):
1064 return self.modelview.observe_activate(self,widget,*args)
1065
1066 def solve_click(self,*args):
1067 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
1068 self.do_solve()
1069
1070 def console_click(self,*args):
1071 try:
1072 console.start(self)
1073 except RuntimeError,e:
1074 self.reporter.reportError("Unable to start console: "+str(e));
1075
1076 def integrate_click(self,*args):
1077 self.do_integrate()
1078
1079 def check_click(self,*args):
1080 self.do_check()
1081 #self.reporter.reportError("CHECK clicked")
1082
1083 def preferences_click(self,*args):
1084 if not self.sim:
1085 self.reporter.reportError("No simulation created yet!");
1086 self.sim.setSolver(self.solver)
1087 _params = self.sim.getParameters()
1088 _paramswin = SolverParametersWindow(
1089 browser=self
1090 ,params=_params
1091 ,name=self.solver.getName()
1092 )
1093 if _paramswin.run() == gtk.RESPONSE_OK:
1094 print "PARAMS UPDATED"
1095 self.sim.setParameters(_paramswin.params)
1096 else:
1097 print "PARAMS NOT UPDATED"
1098
1099 def methodrun_click(self,*args):
1100 _sel = self.methodsel.get_active_text()
1101 if _sel:
1102 _method = None
1103 _methods = self.sim.getType().getMethods()
1104 for _m in _methods:
1105 if _m.getName()==_sel:
1106 _method = _m
1107 if not _method:
1108 self.reporter.reportError("Method is not valid")
1109 return
1110 self.do_method(_method)
1111 else:
1112 self.reporter.reportError("No method selected")
1113
1114 def auto_toggle(self,button,*args):
1115 self.is_auto = button.get_active()
1116 if hasattr(self,'automenu'):
1117 self.automenu.set_active(self.is_auto)
1118 else:
1119 raise RuntimeError("no automenu")
1120
1121 #if self.is_auto:
1122 # self.reporter.reportSuccess("Auto mode is now ON")
1123 #else:
1124 # self.reporter.reportSuccess("Auto mode is now OFF")
1125
1126 def on_file_quit_click(self,*args):
1127 self.do_quit()
1128
1129 def on_tools_auto_toggle(self,checkmenuitem,*args):
1130 self.is_auto = checkmenuitem.get_active()
1131 self.autotoggle.set_active(self.is_auto)
1132
1133 def on_help_about_click(self,*args):
1134 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1135 _about = _xml.get_widget("aboutdialog")
1136 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1137 _about.set_transient_for(self.window);
1138 _about.set_version(config.VERSION)
1139 _about.run()
1140 _about.destroy()
1141
1142 def on_help_contents_click(self,*args):
1143 _help = Help(HELP_ROOT)
1144 _help.run()
1145
1146 def on_help_check_for_updates_click(self,*args):
1147 v = VersionCheck()
1148 title = "Check for updates"
1149 text = "Your version is %s\n" % config.VERSION
1150 try:
1151 v.check()
1152 if config.VERSION==v.latest:
1153 text += "You are running the latest released version"
1154 else:
1155 text += "Latest version is %s\n" % v.latest
1156 if v.info:
1157 text += "Get more info at %s\n" % v.info
1158 if v.download:
1159 text += "Download from %s\n" % v.download
1160 except Exception, e:
1161 text += "\nUnable to check version\n"
1162 text += str(e)
1163
1164 _dialog = InfoDialog(self,self.window,text,title)
1165 _dialog.run()
1166
1167 def on_show_fixable_variables_activate(self,*args):
1168 try:
1169 v = self.sim.getFixableVariables()
1170 except RuntimeError,e:
1171 self.reporter.reportError(str(e))
1172 text = "Fixable Variables"
1173 title = text
1174 text += "\n"
1175 if len(v):
1176 for var in v:
1177 text += "\n%s"%var
1178 else:
1179 text += "\nnone"
1180 _dialog = InfoDialog(self,self.window,text,title)
1181 _dialog.run()
1182
1183 def on_show_fixed_vars_activate(self,*args):
1184 try:
1185 v = self.sim.getFixedVariables()
1186 except RuntimeError,e:
1187 self.reporter.reportError(str(e))
1188 text = "Fixed Variables"
1189 title = text
1190 text += "\n"
1191 if len(v):
1192 for var in v:
1193 text += "\n%s"%var
1194 else:
1195 text += "\nnone"
1196 _dialog = InfoDialog(self,self.window,text,title)
1197 _dialog.run()
1198
1199
1200 def on_show_freeable_variables_activate(self,*args):
1201 try:
1202 v = self.sim.getFreeableVariables()
1203 except RuntimeError,e:
1204 self.reporter.reportError(str(e))
1205
1206 text = "Freeable Variables"
1207 title = text
1208 text += "\n"
1209 if len(v):
1210 for var in v:
1211 text += "\n%s" % var
1212 else:
1213 text += "\nnone"
1214 _dialog = InfoDialog(self,self.window,text,title)
1215 _dialog.run()
1216
1217 def on_show_external_functions_activate(self,*args):
1218 v = self.library.getExtMethods()
1219 text = "External Functions"
1220 title = text
1221 text +="\nHere is the list of external functions currently present in"
1222 text +=" the Library:"
1223
1224 if len(v):
1225 for ext in v:
1226 text += "\n\n%s (%d inputs, %d outputs):" % \
1227 (ext.getName(), ext.getNumInputs(), ext.getNumOutputs())
1228 text += "\n%s" % ext.getHelp()
1229 else:
1230 text +="\n\nNone"
1231 _dialog = InfoDialog(self,self.window,text,title)
1232 _dialog.run()
1233
1234 def on_maintabs_switch_page(self,notebook,page,pagenum):
1235 print("Page switched to %d" % pagenum)
1236 if pagenum in self.tabs.keys():
1237 self.currentobservertab = pagenum
1238
1239 def create_observer(self,name=None):
1240 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1241 _label = gtk.Label();
1242 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1243 _obs = ObserverTab(xml=_xml, name=name, browser=self, tab=_tab)
1244 _label.set_text(_obs.name)
1245 self.observers.append(_obs)
1246 self.tabs[_tab] = _obs
1247 self.currentobservertab = _tab
1248 return _obs
1249
1250 def sync_observers(self):
1251 for _o in self.observers:
1252 _o.sync()
1253
1254 def delete_event(self, widget, event):
1255 self.do_quit()
1256 return False
1257
1258 def observe(self,instance):
1259 if len(self.observers) ==0:
1260 self.create_observer()
1261 _observer = self.tabs[self.currentobservertab]
1262 _observer.add_instance(instance)
1263
1264 if __name__ == "__main__":
1265 b = Browser();
1266 b.run()

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