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

Annotation of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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