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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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