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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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