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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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