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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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