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

Annotation of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 849 - (hide annotations) (download) (as text)
Mon Sep 18 15:10:48 2006 UTC (14 years 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 johnpye 132 #!/usr/bin/env python
2    
3 johnpye 361 import sys
4 johnpye 478 def print_loading_status(status,msg=None):
5     sys.stderr.write("\r \r")
6     if msg!=None:
7     sys.stderr.write(msg+"\n")
8 johnpye 803 sys.stderr.write(status+"...\r")
9 johnpye 478 sys.stderr.flush()
10 johnpye 361
11 johnpye 627 try:
12     print_loading_status("Loading PSYCO")
13 johnpye 478
14 johnpye 627 #try:
15     # import psyco
16     # psyco.full()
17     # print "Running with PSYCO optimisation..."
18     #except ImportError:
19     # pass
20 johnpye 279
21 johnpye 463
22 johnpye 627 print_loading_status("Loading python standard libraries")
23 johnpye 478
24 johnpye 627 import re
25     import urlparse
26     import optparse
27     import platform
28     import sys
29     import os.path
30 johnpye 132
31 johnpye 627 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 johnpye 499
37 johnpye 627 print_loading_status("Loading LIBASCEND/ascpy")
38     import ascpy
39 johnpye 478
40 johnpye 627 print_loading_status("Loading PyGTK, glade, pango")
41 johnpye 478
42 johnpye 627 import pygtk
43     pygtk.require('2.0')
44     import gtk
45     import gtk.glade
46     import pango
47 johnpye 478
48 johnpye 627 print_loading_status("Loading python matplotlib")
49 johnpye 507 try:
50 johnpye 627 import matplotlib
51 johnpye 632 matplotlib.use('GTKAgg')
52 johnpye 627
53 johnpye 507 try:
54 johnpye 746 print_loading_status("Trying python numarray")
55     import numarray
56     matplotlib.rcParams['numerix'] = 'numarray'
57     print_loading_status("","Using python module numarray")
58 johnpye 507 except ImportError:
59     try:
60 johnpye 746 print_loading_status("Trying python numpy")
61     import numpy
62     matplotlib.rcParams['numerix'] = 'numpy'
63     print_loading_status("","Using python module numpy")
64 johnpye 507 except ImportError:
65 johnpye 627 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 johnpye 507
73 johnpye 627 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 johnpye 507
77 johnpye 669 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 johnpye 627 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 johnpye 732 from integrator import * # integrator dialog
94     from infodialog import * # general-purpose textual information dialog
95 johnpye 627 import config
96 johnpye 669
97 johnpye 627 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 johnpye 311
106 johnpye 627 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 johnpye 478 print_loading_status("Starting GUI")
121    
122 johnpye 132 # This is my first ever GUI code so please be nice :)
123 johnpye 361 # 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 johnpye 132
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 johnpye 227 ESCAPE_KEY = 65307
133    
134 johnpye 230 HELP_ROOT = None
135    
136 johnpye 223 #======================================
137     # Browser is the main ASCEND library/model browser window
138    
139 johnpye 132 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 johnpye 478 print_loading_status("Parsing options")
149    
150 johnpye 132 parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
151     # add options here if we want
152    
153 johnpye 160 parser.add_option("-m", "--model"
154 johnpye 341 ,action="store", type="string", dest="model"
155 johnpye 160 ,help="specify the model to instantiate upon loading modules")
156 johnpye 436
157     parser.add_option("--pygtk-assets"
158 johnpye 455 ,action="store", type="string", dest="assets_dir"
159 johnpye 436 ,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 johnpye 459 parser.add_option("--library"
165     ,action="store", type="string", dest="library_path"
166 johnpye 723 ,help="override the configuration value for the library path"
167 johnpye 482 ,default=None
168 johnpye 459 )
169    
170 johnpye 723 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 johnpye 533 (self.options, args) = parser.parse_args()
177 johnpye 132
178 johnpye 533 #print "OPTIONS_______________:",self.options
179 johnpye 482
180 johnpye 533 self.assets_dir = self.options.assets_dir
181 johnpye 132
182 johnpye 246 self.observers = []
183 johnpye 251 self.clip = None
184 johnpye 246
185 johnpye 132 #--------
186     # load up the preferences ini file
187    
188 johnpye 478 print_loading_status("Loading preferences")
189    
190 johnpye 479 self.prefs = Preferences()
191 johnpye 132
192 johnpye 482 _prefpath = self.prefs.getStringPref("Directories","librarypath",None)
193 johnpye 500 _preffileopenpath = self.prefs.getStringPref("Directories","fileopenpath",None)
194 johnpye 482
195 johnpye 132 #--------
196 johnpye 482 # set up library path and the path to use for File->Open dialogs
197 johnpye 455
198 johnpye 533 if self.options.library_path != None:
199     _path = os.path.abspath(self.options.library_path)
200 johnpye 482 _pathsrc = "commandline"
201     # when a special path is specified, use that as the file-open location
202 johnpye 507 self.fileopenpath = _path
203 johnpye 356 else:
204 johnpye 482 if _prefpath:
205     _path = _prefpath
206     _pathsrc = "user preferences"
207     else:
208     _path = config.LIBRARY_PATH
209 johnpye 479 _pathsrc = "default (config.py)"
210 johnpye 482
211     if _preffileopenpath:
212     self.fileopenpath = _preffileopenpath
213 johnpye 479 else:
214 johnpye 482 self.fileopenpath = _path
215    
216     #--------
217     # Create the ASCXX 'Library' object
218    
219 johnpye 507 print_loading_status("Creating ASCEND 'Library' object","PATH = "+_path+" FROM "+_pathsrc)
220 johnpye 482 self.library = ascpy.Library(_path)
221 johnpye 479
222 johnpye 132 self.sim = None
223 johnpye 351
224 johnpye 132 #-------------------
225     # Set up the window and main widget actions
226    
227 johnpye 806 self.glade_file = self.assets_dir+config.GLADE_FILE
228 johnpye 709
229 johnpye 806 print_loading_status("Setting up windows","GLADE_FILE = %s" % self.glade_file)
230    
231 johnpye 436 glade = gtk.glade.XML(self.glade_file,"browserwin")
232 johnpye 132
233     self.window = glade.get_widget("browserwin")
234 johnpye 208
235 johnpye 709
236 johnpye 132 if not self.window:
237     raise RuntimeError("Couldn't load window from glade file")
238 johnpye 172
239 johnpye 294 _display = self.window.get_screen().get_display().get_name()
240 johnpye 173 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
241 johnpye 172 if _geom:
242 johnpye 294 self.window.resize(_geom[0],_geom[1])
243     self.window.move(_geom[2],_geom[3])
244 johnpye 173
245 johnpye 132 self.window.connect("delete_event", self.delete_event)
246    
247 johnpye 294 self.browserpaned=glade.get_widget("browserpaned")
248     _geom2=self.prefs.getGeometryValue(_display,"browserpaned")
249 johnpye 173 if _geom2:
250 johnpye 294 self.browserpaned.set_position(_geom2)
251 johnpye 173
252 johnpye 132 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 johnpye 669 self.integratebutton=glade.get_widget("integratebutton")
262     self.integratebutton.connect("clicked",self.integrate_click)
263    
264 johnpye 132 self.checkbutton=glade.get_widget("checkbutton")
265     self.checkbutton.connect("clicked",self.check_click)
266    
267     self.autotoggle=glade.get_widget("autotoggle")
268 johnpye 688 self.automenu = glade.get_widget("automenu")
269 johnpye 132 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 johnpye 164 self.statusbar = glade.get_widget("statusbar")
279    
280 johnpye 208 self.menu = glade.get_widget("browsermenu")
281    
282 johnpye 321 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 johnpye 785 self.solver_engine=glade.get_widget("solver_engine")
289 johnpye 164
290 johnpye 770 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 johnpye 688 glade.signal_autoconnect(self)
294    
295 johnpye 533 #-------
296     # Status icons
297 johnpye 164
298 johnpye 268 self.fixedimg = gtk.Image()
299 johnpye 533 self.fixedimg.set_from_file(self.options.assets_dir+'locked.png')
300 johnpye 268
301 johnpye 258 self.iconstatusunknown = None
302 johnpye 268 self.iconfixed = self.fixedimg.get_pixbuf()
303 johnpye 255 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
304 johnpye 258 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
305 johnpye 255 self.iconunsolved = None
306    
307     self.statusicons={
308 johnpye 463 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 johnpye 255 }
314 johnpye 533
315    
316 johnpye 273 self.statusmessages={
317 johnpye 463 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 johnpye 533 }
323 johnpye 255
324 johnpye 533 #-------------------
325     # waitwin
326 johnpye 132
327 johnpye 533 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 johnpye 226
334 johnpye 533 _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
335     self.waitwin.set_cursor(_cursor)
336 johnpye 181
337 johnpye 533 #-------------------
338     # pixbufs to be used in the error listing
339 johnpye 181
340 johnpye 533 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 johnpye 181
345 johnpye 533 #--------------------
346     # pixbufs for solver_var status
347 johnpye 181
348 johnpye 132 #--------------------
349     # set up the error view
350    
351 johnpye 168 self.errorview = glade.get_widget("errorview")
352 johnpye 132 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 johnpye 463 self.reporter = ascpy.getReporter()
381 johnpye 132 self.reporter.setPythonErrorCallback(self.error_callback)
382    
383 johnpye 785
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 johnpye 803 _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 johnpye 785
407 johnpye 709 #--------
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 johnpye 132 #-------------------
426     # set up the module view
427    
428     self.modtank = {}
429     self.moduleview = glade.get_widget("moduleview")
430 johnpye 355 modulestorecoltypes = [str, str, int] # bool=can-be-instantiated
431 johnpye 132 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 johnpye 355 modcol.add_attribute(_renderer,'weight',2)
443 johnpye 132 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 johnpye 533 self.modelview = ModelView(self, glade)
459 johnpye 255
460 johnpye 533 #--------
461 johnpye 688 # 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 johnpye 533 # options
469 johnpye 132
470     if(len(args)==1):
471     self.do_open(args[0])
472    
473 johnpye 723 print "Options: ",self.options
474 johnpye 132
475 johnpye 723 _model = None
476 johnpye 533 if self.options.model:
477 johnpye 723 _model = self.options.model
478     print "MODEL: '%s'" % _model
479     elif self.options.auto_sim:
480 johnpye 728 _head, _tail = os.path.split(args[0])
481     if(_tail):
482     _model, _ext = os.path.splitext(_tail)
483 johnpye 723
484     if _model:
485 johnpye 132 try:
486 johnpye 723 _t=self.library.findType(_model)
487     try:
488     self.do_sim(_t)
489 johnpye 725 if not self.options.model:
490     self.reporter.reportNote("Instantiating self-titled model '%s'" %_model)
491 johnpye 723 except RuntimeError, e:
492     self.reporter.reportError("Failed to create instance of '%s': %s"
493     %(_model, str(e))
494     );
495 johnpye 132 except RuntimeError, e:
496 johnpye 723 if self.options.model:
497     self.reporter.reportError("Unknown model type '%s': %s"
498     %(_model, str(e))
499     );
500 johnpye 223
501 johnpye 132 def run(self):
502     self.window.show()
503 johnpye 500 print_loading_status("ASCEND is now running")
504 johnpye 132 gtk.main()
505    
506 johnpye 785 # ------------------
507     # SOLVER LIST
508    
509     def set_solver(self,solvername):
510     self.solver = ascpy.Solver(solvername)
511 johnpye 803 self.prefs.setStringPref("Solver","engine",solvername)
512 johnpye 785 self.reporter.reportNote("Set solver engine to '%s'" % solvername)
513    
514 johnpye 132 # --------------------------------------------
515     # MAJOR GUI COMMANDS
516    
517 johnpye 533 def on_fix_variable_activate(self,*args):
518     self.modelview.on_fix_variable_activate(*args)
519 johnpye 132
520 johnpye 533 def on_free_variable_activate(self,*args):
521     self.modelview.on_free_variable_activate(*args)
522    
523 johnpye 785 def on_select_solver_toggled(self,widget,solvername):
524     if widget.get_active():
525     self.set_solver(solvername)
526    
527 johnpye 132 def do_open(self,filename):
528     # TODO does the user want to lose their work?
529     # TODO do we need to chdir?
530    
531 johnpye 164 _context = self.statusbar.get_context_id("do_open")
532    
533 johnpye 132 self.errorstore.clear()
534    
535 johnpye 533 self.modelview.clear()
536 johnpye 132
537 johnpye 175 # self.library.clear()
538 johnpye 164
539     self.statusbar.push(_context,"Loading '"+filename+"'")
540 johnpye 132 self.library.load(filename)
541 johnpye 164 self.statusbar.pop(_context)
542 johnpye 132
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 johnpye 338 self.library.listModules()
550     try:
551     _lll=len(modules)
552     except:
553     _msg = "UNABLE TO ACCESS MODULES LIST. This is bad.\n"+\
554 johnpye 669 "Check your SWIG configuration (check for warnings during build)."
555 johnpye 338
556     self.reporter.reportError(_msg)
557     raise RuntimeError(_msg)
558    
559 johnpye 132 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 johnpye 355 _r = self.modulestore.append(None, [ _n, _f, pango.WEIGHT_NORMAL ])
564 johnpye 132 for t in self.library.getModuleTypes(m):
565     _n = t.getName()
566 johnpye 355 _hasparams = t.hasParameters()
567     if _hasparams:
568     _w = pango.WEIGHT_NORMAL
569     else:
570     _w = pango.WEIGHT_BOLD
571    
572 johnpye 132 #print "ADDING TYPE %s" % _n
573 johnpye 355 _piter = self.modulestore.append(_r , [ _n, "", _w ])
574 johnpye 132 _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 johnpye 164
582 johnpye 168 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
583     # for details on how the 'wait cursor' is done.
584 johnpye 164 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 johnpye 132
594 johnpye 164 def stop_waiting(self):
595     if self.waitwin:
596     self.statusbar.pop(self.waitcontext)
597     self.waitwin.hide()
598    
599 johnpye 132 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 johnpye 164 self.start_waiting("Compiling...")
605    
606 johnpye 277 try:
607 johnpye 770 _v = self.prefs.getBoolPref("Compiler","use_relation_sharing",True)
608     ascpy.getCompiler().setUseRelationSharing(_v)
609    
610 johnpye 277 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 johnpye 132 print "...DONE 'getSimulation'"
617 johnpye 164 self.stop_waiting()
618 johnpye 132
619 johnpye 164 self.start_waiting("Building simulation...")
620 johnpye 132 print "BUILDING SIMULATION"
621 johnpye 277
622     try:
623     self.sim.build()
624     except RuntimeError, e:
625     self.stop_waiting()
626     self.reporter.reportError(str(e))
627     return;
628    
629 johnpye 132 print "DONE BUILDING"
630 johnpye 164 self.stop_waiting()
631 johnpye 132
632 johnpye 785 self.sim.setSolver(self.solver)
633 johnpye 223
634 johnpye 533 # methods
635 johnpye 132 self.methodstore.clear()
636     _methods = self.sim.getType().getMethods()
637 johnpye 160 _activemethod = None;
638 johnpye 132 for _m in _methods:
639 johnpye 160 _i = self.methodstore.append([_m.getName()])
640 johnpye 669 if _m.getName()=="on_load":
641 johnpye 160 self.methodsel.set_active_iter(_i)
642 johnpye 132
643 johnpye 533 self.modelview.setSimulation(self.sim)
644 johnpye 249
645     def do_solve_if_auto(self):
646     if self.is_auto:
647 johnpye 775 self.sim.checkInstance()
648 johnpye 249 self.do_solve()
649     else:
650 johnpye 255 self.sim.processVarStatus()
651 johnpye 533 self.modelview.refreshtree()
652 johnpye 249
653     self.sync_observers()
654 johnpye 132
655     def do_solve(self):
656     if not self.sim:
657     self.reporter.reportError("No model selected yet")
658 johnpye 669 return
659 johnpye 132
660 johnpye 786 self.start_waiting("Solving with %s..." % self.solver.getName())
661 johnpye 164
662 johnpye 321 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
663 johnpye 351 reporter = PopupSolverReporter(self,self.sim.getNumVars())
664 johnpye 321 else:
665     reporter = SimpleSolverReporter(self)
666    
667 johnpye 785 self.sim.solve(self.solver,reporter)
668 johnpye 164
669 johnpye 168 self.stop_waiting()
670 johnpye 255
671     self.sim.processVarStatus()
672 johnpye 533 self.modelview.refreshtree()
673 johnpye 132
674 johnpye 669 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 johnpye 132 def do_check(self):
687     if not self.sim:
688 johnpye 775 self.reporter.reportError("No simulation yet")
689 johnpye 669 return
690 johnpye 132
691 johnpye 171 self.start_waiting("Checking system...")
692    
693 johnpye 278 try:
694 johnpye 775 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 johnpye 772
699 johnpye 775 status = self.sim.checkDoF()
700     if status==ascpy.ASCXX_DOF_UNDERSPECIFIED:
701 johnpye 776 self.on_show_fixable_variables_activate(None)
702 johnpye 775 elif status==ascpy.ASCXX_DOF_OVERSPECIFIED:
703 johnpye 776 self.on_show_freeable_variables_activate(None)
704 johnpye 775 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 johnpye 772
724 johnpye 775 _dialog = InfoDialog(self,self.window,text,title)
725     _dialog.run()
726    
727     self.reporter.reportNote("System DoF check OK")
728    
729 johnpye 278 except RuntimeError, e:
730     self.stop_waiting()
731     self.reporter.reportError(str(e))
732     return
733 johnpye 171
734     self.stop_waiting()
735    
736 johnpye 533 self.modelview.refreshtree()
737 johnpye 132
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 johnpye 533 self.modelview.refreshtree()
744 johnpye 132
745 johnpye 230 def do_quit(self):
746 johnpye 482 print_loading_status("Saving window location")
747 johnpye 230 self.reporter.clearPythonErrorCallback()
748 johnpye 482
749 johnpye 230 _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 johnpye 482 print_loading_status("Saving current directory")
758     self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
759    
760 johnpye 682 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
761    
762 johnpye 482 print_loading_status("Saving preferences")
763 johnpye 230 # causes prefs to be saved unless they are still being used elsewher
764     del(self.prefs)
765    
766 johnpye 482 print_loading_status("Closing down GTK")
767 johnpye 230 gtk.main_quit()
768 johnpye 482
769     print_loading_status("Clearing error callback")
770     self.reporter.clearPythonErrorCallback()
771    
772     print_loading_status("Quitting")
773 johnpye 230 return False
774    
775 johnpye 231 def on_tools_sparsity_click(self,*args):
776 johnpye 237
777     self.reporter.reportNote("Preparing incidence matrix...")
778 johnpye 233 _im = self.sim.getIncidenceMatrix();
779 johnpye 231
780 johnpye 237 self.reporter.reportNote("Plotting incidence matrix...")
781 johnpye 234
782 johnpye 237 _sp = IncidenceMatrixWindow(_im);
783     _sp.run();
784    
785 johnpye 280 def on_diagnose_blocks_click(self,*args):
786 johnpye 285 try:
787     _bl = self.sim.getActiveBlock()
788     except RuntimeError, e:
789     self.reporter.reportError(str(e))
790     return
791 johnpye 351 _db = DiagnoseWindow(self,_bl)
792 johnpye 280 _db.run();
793    
794 johnpye 245 def on_add_observer_click(self,*args):
795 johnpye 361 if len(self.observers) > 0:
796 johnpye 246 self.reporter.reportError("Not supported: multiple observers")
797     return
798 johnpye 361 self.create_observer()
799 johnpye 245
800 johnpye 250 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 johnpye 251 if self.clip == None:
811     self.clip = gtk.Clipboard()
812    
813 johnpye 250 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 johnpye 251 self.observers[0].copy_to_clipboard(self.clip)
820 johnpye 270
821 johnpye 770 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 johnpye 321 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 johnpye 328 def on_show_variables_near_bounds_activate(self,*args):
840     _epsilon = 1e-4;
841 johnpye 732 text = "Variables New Bounds"
842     title=text;
843     text += "\n"
844 johnpye 328 _vars = self.sim.getVariablesNearBounds(_epsilon)
845 johnpye 732 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 johnpye 328
853 johnpye 132 # --------------------------------------------
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 johnpye 255 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 johnpye 132 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 johnpye 669 #print_loading_status("CURRENT FILEOPENPATH is",self.fileopenpath)
921 johnpye 482 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 johnpye 132 dialog.set_default_response(gtk.RESPONSE_OK)
928 johnpye 329 dialog.set_transient_for(self.window)
929     dialog.set_modal(True)
930 johnpye 132
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 johnpye 669 print "\nFILENAME SELECTED:",_filename
945 johnpye 482
946     _path = dialog.get_current_folder()
947     if _path:
948     self.fileopenpath = _path
949    
950 johnpye 329 dialog.hide()
951 johnpye 132
952     if response == gtk.RESPONSE_OK:
953     self.reporter.reportNote("File %s selected." % dialog.get_filename() )
954 johnpye 185 self.library.clear()
955 johnpye 329 self.do_open( _filename)
956 johnpye 132
957     def reload_click(self,*args):
958     _type = None
959     if(self.sim):
960     _type = self.sim.getType().getName().toString();
961    
962 johnpye 185 self.library.clear()
963 johnpye 132 self.do_open(self.filename)
964    
965     if _type:
966     _t = self.library.findType(_type)
967     self.do_sim(_t)
968    
969 johnpye 533 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 johnpye 132 def solve_click(self,*args):
976     #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
977     self.do_solve()
978 johnpye 669
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 johnpye 132
988     def check_click(self,*args):
989     self.do_check()
990     #self.reporter.reportError("CHECK clicked")
991    
992 johnpye 208 def preferences_click(self,*args):
993     if not self.sim:
994     self.reporter.reportError("No simulation created yet!");
995    
996 johnpye 351 _paramswin = SolverParametersWindow(self)
997 johnpye 223 _paramswin.show()
998 johnpye 221
999 johnpye 132 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 johnpye 230 self.is_auto = button.get_active()
1016 johnpye 688 if hasattr(self,'automenu'):
1017     self.automenu.set_active(self.is_auto)
1018 johnpye 132 else:
1019 johnpye 688 raise RuntimeError("no automenu")
1020 johnpye 132
1021 johnpye 688 #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 johnpye 230 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 johnpye 436 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1035 johnpye 307 _about = _xml.get_widget("aboutdialog")
1036 johnpye 328 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1037     _about.set_transient_for(self.window);
1038 johnpye 478 _about.set_version(config.VERSION)
1039 johnpye 307 _about.run()
1040     _about.destroy()
1041 johnpye 230
1042     def on_help_contents_click(self,*args):
1043     _help = Help(HELP_ROOT)
1044     _help.run()
1045    
1046 johnpye 775 def on_show_fixable_variables_activate(self,*args):
1047 johnpye 290 v = self.sim.getFixableVariables()
1048 johnpye 732 text = "Fixable Variables"
1049 johnpye 750 title = text
1050 johnpye 732 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 johnpye 290
1059 johnpye 775 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 johnpye 750 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 johnpye 245 def create_observer(self,name=None):
1091 johnpye 436 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1092 johnpye 245 _label = gtk.Label();
1093 johnpye 252 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1094 johnpye 849 _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 johnpye 249
1099     def sync_observers(self):
1100     for _o in self.observers:
1101     _o.sync()
1102 johnpye 533
1103     def delete_event(self, widget, event):
1104     self.do_quit()
1105     return False
1106 johnpye 249
1107 johnpye 533 def observe(self,instance):
1108 johnpye 246 if len(self.observers) > 1:
1109 johnpye 361 self.reporter.reportError("Not implemented: multiple observers (currently %d observers)" %
1110     len(self.observers) )
1111 johnpye 246 return
1112     if len(self.observers) ==0:
1113     self.create_observer()
1114     _observer = self.observers[0]
1115 johnpye 533 _observer.add_instance(instance)
1116 johnpye 132
1117 johnpye 478 if __name__ == "__main__":
1118 johnpye 132 b = Browser();
1119     b.run()

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