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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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