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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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