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

Annotation of /trunk/pygtk/interface/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 479 - (hide annotations) (download) (as text)
Mon Apr 17 08:49:14 2006 UTC (14 years, 6 months ago) by johnpye
File MIME type: text/x-python
File size: 35006 byte(s)
More small tweaks to help debug loading of PyGTK GUI
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     sys.stderr.write(status+"...")
9     sys.stderr.flush()
10 johnpye 361
11 johnpye 478 print_loading_status("Loading PSYCO")
12    
13 johnpye 279 try:
14     import psyco
15     psyco.full()
16 johnpye 361 print "Running with PSYCO optimisation..."
17 johnpye 279 except ImportError:
18     pass
19    
20 johnpye 463
21 johnpye 478 print_loading_status("Loading python standard libraries")
22    
23 johnpye 132 import re
24     import urlparse
25     import optparse
26 johnpye 478 import platform
27     import sys
28 johnpye 132
29 johnpye 478 if platform.system() != "Windows":
30     import dl
31     # This sets the flags for dlopen used by python so that the symbols in the
32     # ascend library are made available to libraries dlopened within ASCEND:
33     sys.setdlopenflags(dl.RTLD_GLOBAL|dl.RTLD_NOW)
34    
35     print_loading_status("Loading PyGTK, glade, pango")
36    
37     import pygtk
38     pygtk.require('2.0')
39     import gtk
40     import gtk.glade
41     import pango
42    
43     print_loading_status("Loading ASCEND python modules...")
44    
45 johnpye 479 from preferences import * # loading/saving of .ini options
46 johnpye 230 from solverparameters import * # 'solver parameters' window
47 johnpye 268 from help import * # viewing help files
48     from incidencematrix import * # incidence/sparsity matrix matplotlib window
49     from observer import * # observer tab support
50     from properties import * # solver_var properties dialog
51     from varentry import * # for inputting of variables with units
52 johnpye 280 from diagnose import * # for diagnosing block non-convergence
53 johnpye 311 from solverreporter import * # solver status reporting
54 johnpye 338 import config
55 johnpye 311
56 johnpye 478 print_loading_status("Loading LIBASCEND/ascpy")
57 johnpye 463 import ascpy
58 johnpye 132
59 johnpye 478 print_loading_status("Starting GUI")
60    
61 johnpye 132 # This is my first ever GUI code so please be nice :)
62 johnpye 361 # But I *have* at least read
63     # http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html
64     # and leafed through
65     # http://developer.gnome.org/projects/gup/hig/
66 johnpye 132
67     # The fancy tree-view gizmo is the GtkTreeView object. See the article
68     # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/300304
69     # for the original source code on which my implementation was based.
70    
71 johnpye 227 ESCAPE_KEY = 65307
72    
73 johnpye 230 HELP_ROOT = None
74    
75 johnpye 255 BROWSER_FIXED_COLOR = "#008800"
76     BROWSER_FREE_COLOR = "#000088"
77 johnpye 223 #======================================
78     # Browser is the main ASCEND library/model browser window
79    
80 johnpye 132 class Browser:
81    
82     # ---------------------------------
83     # SETUP
84    
85     def __init__(self):
86     #--------
87     # load the file referenced in the command line, if any
88    
89 johnpye 478 print_loading_status("Parsing options")
90    
91 johnpye 132 parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
92     # add options here if we want
93    
94 johnpye 160 parser.add_option("-m", "--model"
95 johnpye 341 ,action="store", type="string", dest="model"
96 johnpye 160 ,help="specify the model to instantiate upon loading modules")
97 johnpye 436
98     parser.add_option("--pygtk-assets"
99 johnpye 455 ,action="store", type="string", dest="assets_dir"
100 johnpye 436 ,help="override the configuration value for the location of assets"\
101     +" required by PyGTK for the ASCEND GUI, optional"
102     ,default=config.PYGTK_ASSETS
103     )
104    
105 johnpye 459 parser.add_option("--library"
106     ,action="store", type="string", dest="library_path"
107     ,help="overried the configuration value for the library path"
108     ,default=config.LIBRARY_PATH
109     )
110    
111 johnpye 132 (options, args) = parser.parse_args()
112    
113     #print "OPTIONS_______________:",options
114    
115 johnpye 246 self.observers = []
116 johnpye 251 self.clip = None
117 johnpye 246
118 johnpye 132 #--------
119     # load up the preferences ini file
120    
121 johnpye 478 print_loading_status("Loading preferences")
122    
123 johnpye 479 self.prefs = Preferences()
124 johnpye 132
125     #--------
126     # initialise ASCEND
127    
128 johnpye 455 self.assets_dir = options.assets_dir
129    
130 johnpye 356 _prefpath = self.prefs.getStringPref("Directories","librarypath",None)
131    
132     if _prefpath:
133     _path = _prefpath
134 johnpye 479 _pathsrc = "user preferences"
135 johnpye 356 else:
136 johnpye 479 _path = options.library_path
137     if options.library_path==config.LIBRARY_PATH:
138     _pathsrc = "default (config.py)"
139     else:
140     _pathsrc = "commandline"
141    
142     print_loading_status("Creating ASCEND 'Library' object",
143     "From %s, using ASCENDLIBRARY = %s" % (_pathsrc,_path)
144 johnpye 132
145 johnpye 479 )
146     self.library = ascpy.Library(_path)
147    
148 johnpye 132 self.sim = None
149    
150 johnpye 351 #--------
151     # Prepare the ASCEND icon
152    
153 johnpye 478 print_loading_status("Setting up windows")
154    
155 johnpye 455 if config.ICON_EXTENSION:
156 johnpye 351 _icon = gtk.Image()
157 johnpye 455 _iconpath = self.assets_dir+'ascend'+config.ICON_EXTENSION
158     _icon.set_from_file(_iconpath)
159 johnpye 351 self.icon = _icon.get_pixbuf()
160    
161 johnpye 132 #-------------------
162     # Set up the window and main widget actions
163    
164 johnpye 455 self.glade_file = self.assets_dir+config.GLADE_FILE
165 johnpye 436 glade = gtk.glade.XML(self.glade_file,"browserwin")
166 johnpye 132
167     self.window = glade.get_widget("browserwin")
168 johnpye 351 if self.icon:
169     self.window.set_icon(self.icon)
170 johnpye 208
171 johnpye 132 if not self.window:
172     raise RuntimeError("Couldn't load window from glade file")
173 johnpye 172
174 johnpye 294 _display = self.window.get_screen().get_display().get_name()
175 johnpye 173 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
176 johnpye 172 if _geom:
177 johnpye 294 self.window.resize(_geom[0],_geom[1])
178     self.window.move(_geom[2],_geom[3])
179 johnpye 173
180 johnpye 132 self.window.connect("delete_event", self.delete_event)
181    
182 johnpye 294 self.browserpaned=glade.get_widget("browserpaned")
183     _geom2=self.prefs.getGeometryValue(_display,"browserpaned")
184 johnpye 173 if _geom2:
185 johnpye 294 self.browserpaned.set_position(_geom2)
186 johnpye 173
187 johnpye 132 self.openbutton=glade.get_widget("openbutton")
188     self.openbutton.connect("clicked",self.open_click)
189    
190     self.reloadbutton=glade.get_widget("reloadbutton")
191     self.reloadbutton.connect("clicked",self.reload_click)
192    
193     self.solvebutton=glade.get_widget("solvebutton")
194     self.solvebutton.connect("clicked",self.solve_click)
195    
196     self.checkbutton=glade.get_widget("checkbutton")
197     self.checkbutton.connect("clicked",self.check_click)
198    
199     self.autotoggle=glade.get_widget("autotoggle")
200     self.autotoggle.connect("toggled",self.auto_toggle)
201    
202 johnpye 230 self.is_auto = self.autotoggle.get_active()
203    
204 johnpye 132 self.methodrunbutton=glade.get_widget("methodrunbutton")
205     self.methodrunbutton.connect("clicked",self.methodrun_click)
206    
207     self.methodsel=glade.get_widget("methodsel")
208    
209     self.maintabs = glade.get_widget("maintabs")
210    
211 johnpye 164 self.statusbar = glade.get_widget("statusbar")
212    
213 johnpye 208 self.menu = glade.get_widget("browsermenu")
214     glade.signal_autoconnect(self)
215    
216 johnpye 230 self.automenu = glade.get_widget("automenu")
217     self.automenu.set_active(self.is_auto)
218     if self.automenu == None:
219     print "NO AUTOMENU FOUND"
220    
221 johnpye 321 self.show_solving_popup=glade.get_widget("show_solving_popup")
222     self.show_solving_popup.set_active(self.prefs.getBoolPref("SolverReporter","show_popup",True))
223     self.close_on_converged=glade.get_widget("close_on_converged")
224     self.close_on_converged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_converged",True))
225     self.close_on_nonconverged=glade.get_widget("close_on_nonconverged")
226     self.close_on_nonconverged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_nonconverged",True))
227 johnpye 132 #-------------------
228 johnpye 164 # waitwin
229    
230     self.waitwin = gtk.gdk.Window(self.window.window,
231     gtk.gdk.screen_width(),
232     gtk.gdk.screen_height(),
233     gtk.gdk.WINDOW_CHILD,
234     0,
235     gtk.gdk.INPUT_ONLY)
236    
237     _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
238     self.waitwin.set_cursor(_cursor)
239    
240     #-------------------
241 johnpye 132 # pixbufs to be used in the error listing
242    
243     self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
244     self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
245     self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
246     self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
247    
248     #--------------------
249 johnpye 255 # pixbufs for solver_var status
250    
251 johnpye 268 self.fixedimg = gtk.Image()
252 johnpye 455 self.fixedimg.set_from_file(options.assets_dir+'locked.png')
253 johnpye 268
254 johnpye 258 self.iconstatusunknown = None
255 johnpye 268 self.iconfixed = self.fixedimg.get_pixbuf()
256 johnpye 255 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
257 johnpye 258 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
258 johnpye 255 self.iconunsolved = None
259    
260     self.statusicons={
261 johnpye 463 ascpy.ASCXX_VAR_STATUS_UNKNOWN: self.iconstatusunknown
262     ,ascpy.ASCXX_VAR_FIXED: self.iconfixed
263     ,ascpy.ASCXX_VAR_SOLVED: self.iconsolved
264     ,ascpy.ASCXX_VAR_ACTIVE: self.iconactive
265     ,ascpy.ASCXX_VAR_UNSOLVED: self.iconunsolved
266 johnpye 255 }
267 johnpye 273 self.statusmessages={
268 johnpye 463 ascpy.ASCXX_VAR_STATUS_UNKNOWN: "Status unknown"
269     ,ascpy.ASCXX_VAR_FIXED: "Fixed"
270     ,ascpy.ASCXX_VAR_SOLVED: "Converged"
271     ,ascpy.ASCXX_VAR_ACTIVE: "Active (unconverged)"
272     ,ascpy.ASCXX_VAR_UNSOLVED: "Not yet visited"
273 johnpye 273 }
274 johnpye 255
275     #--------------------
276 johnpye 132 # set up the context menu for fixing/freeing vars
277    
278 johnpye 226 # TODO import this menu from Glade (this code is a PITA)
279    
280 johnpye 132 self.treecontext = gtk.Menu();
281 johnpye 181 self.fixmenuitem = gtk.ImageMenuItem("_Fix",True);
282 johnpye 268 self.fixmenuitem.set_image(self.fixedimg)
283 johnpye 181
284     self.freemenuitem = gtk.ImageMenuItem("F_ree",True);
285     _img = gtk.Image()
286 johnpye 455 _img.set_from_file(options.assets_dir+'unlocked.png')
287 johnpye 181 self.freemenuitem.set_image(_img)
288    
289     self.plotmenuitem = gtk.ImageMenuItem("P_lot",True);
290     _img = gtk.Image()
291 johnpye 455 _img.set_from_file(options.assets_dir+'plot.png')
292 johnpye 181 self.plotmenuitem.set_image(_img)
293    
294     self.propsmenuitem = gtk.ImageMenuItem("_Properties",True);
295     _img = gtk.Image()
296 johnpye 455 _img.set_from_file(options.assets_dir+'properties.png')
297 johnpye 181 self.propsmenuitem.set_image(_img)
298    
299 johnpye 246 self.observemenuitem = gtk.ImageMenuItem("_Observe",True);
300     _img = gtk.Image()
301 johnpye 455 _img.set_from_file(options.assets_dir+'observe.png')
302 johnpye 246 self.observemenuitem.set_image(_img)
303    
304 johnpye 207 self.fixmenuitem.show(); self.fixmenuitem.set_sensitive(False)
305     self.freemenuitem.show(); self.freemenuitem.set_sensitive(False)
306     self.plotmenuitem.show(); self.plotmenuitem.set_sensitive(False)
307 johnpye 246 self.observemenuitem.show(); self.observemenuitem.set_sensitive(False)
308 johnpye 181 self.propsmenuitem.show()
309 johnpye 246 self.treecontext.append(self.fixmenuitem)
310     self.treecontext.append(self.freemenuitem)
311 johnpye 181 _sep = gtk.SeparatorMenuItem(); _sep.show()
312     self.treecontext.append(_sep);
313 johnpye 246 self.treecontext.append(self.plotmenuitem)
314     self.treecontext.append(self.observemenuitem)
315 johnpye 181 _sep = gtk.SeparatorMenuItem(); _sep.show()
316 johnpye 246 self.treecontext.append(_sep)
317     self.treecontext.append(self.propsmenuitem)
318 johnpye 132 self.fixmenuitem.connect("activate",self.fix_activate)
319     self.freemenuitem.connect("activate",self.free_activate)
320 johnpye 175 self.plotmenuitem.connect("activate",self.plot_activate)
321 johnpye 181 self.propsmenuitem.connect("activate",self.props_activate)
322 johnpye 246 self.observemenuitem.connect("activate",self.observe_activate)
323    
324 johnpye 132 if not self.treecontext:
325     raise RuntimeError("Couldn't create browsercontext")
326     #--------------------
327     # set up the error view
328    
329 johnpye 168 self.errorview = glade.get_widget("errorview")
330 johnpye 132 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
331     self.errorstore = gtk.TreeStore(*errstorecolstypes)
332     errtitles = ["","Location","Message"];
333     self.errorview.set_model(self.errorstore)
334     self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
335    
336     i = 0
337     for tvcolumn in self.errcols[:len(errtitles)]:
338     tvcolumn.set_title(errtitles[i])
339     self.errorview.append_column(tvcolumn)
340    
341     if i>0:
342     _renderer = gtk.CellRendererText()
343     tvcolumn.pack_start(_renderer, True)
344     tvcolumn.add_attribute(_renderer, 'text', i)
345     if(i==2):
346     tvcolumn.add_attribute(_renderer, 'foreground', 3)
347     tvcolumn.add_attribute(_renderer, 'weight', 4)
348     else:
349     _renderer1 = gtk.CellRendererPixbuf()
350     tvcolumn.pack_start(_renderer1, False)
351     tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
352    
353     i = i + 1
354    
355    
356     #--------------------
357     # set up the error reporter callback
358 johnpye 463 self.reporter = ascpy.getReporter()
359 johnpye 132 self.reporter.setPythonErrorCallback(self.error_callback)
360    
361     #-------------------
362     # set up the module view
363    
364     self.modtank = {}
365     self.moduleview = glade.get_widget("moduleview")
366 johnpye 355 modulestorecoltypes = [str, str, int] # bool=can-be-instantiated
367 johnpye 132 self.modulestore = gtk.TreeStore(*modulestorecoltypes)
368     moduleviewtitles = ["Module name", "Filename"]
369     self.moduleview.set_model(self.modulestore)
370     self.modcols = [ gtk.TreeViewColumn() for _type in modulestorecoltypes]
371     i = 0
372     for modcol in self.modcols[:len(moduleviewtitles)]:
373     modcol.set_title(moduleviewtitles[i])
374     self.moduleview.append_column(modcol)
375     _renderer = gtk.CellRendererText()
376     modcol.pack_start(_renderer, True)
377     modcol.add_attribute(_renderer, 'text', i)
378 johnpye 355 modcol.add_attribute(_renderer,'weight',2)
379 johnpye 132 i = i + 1
380     self.moduleview.connect("row-activated", self.module_activated )
381    
382     #--------------------
383     # set up the methods combobox
384    
385     self.methodstore = gtk.ListStore(str)
386     self.methodsel.set_model(self.methodstore)
387     _methodrenderer = gtk.CellRendererText()
388     self.methodsel.pack_start(_methodrenderer, True)
389     self.methodsel.add_attribute(_methodrenderer, 'text',0)
390    
391     #--------
392     # set up the instance browser view
393    
394     self.otank = {}
395     self.treeview = glade.get_widget("browserview")
396 johnpye 255
397     # name, type, value, foreground, weight, editable, status-icon
398     columns = [str,str,str,str,int,bool,gtk.gdk.Pixbuf]
399 johnpye 132 self.treestore = gtk.TreeStore(*columns)
400     titles = ["Name","Type","Value"];
401     self.treeview.set_model(self.treestore)
402     self.tvcolumns = [ gtk.TreeViewColumn() for _type in columns[:len(titles)] ]
403    
404     self.treeview.connect("row-expanded", self.row_expanded )
405 johnpye 270 self.treeview.connect("button-press-event", self.on_treeview_event )
406     self.treeview.connect("key-press-event",self.on_treeview_event )
407 johnpye 132
408     # data columns are: name type value colour weight editable
409    
410     i = 0
411     for tvcolumn in self.tvcolumns[:len(titles)]:
412     tvcolumn.set_title(titles[i])
413     self.treeview.append_column(tvcolumn)
414    
415 johnpye 255 if(i==2):
416     # add status icon
417     renderer1 = gtk.CellRendererPixbuf()
418 johnpye 258 tvcolumn.pack_start(renderer1, False)
419 johnpye 255 tvcolumn.add_attribute(renderer1, 'pixbuf', 6)
420    
421 johnpye 132 renderer = gtk.CellRendererText()
422     tvcolumn.pack_start(renderer, True)
423     tvcolumn.add_attribute(renderer, 'text', i)
424     tvcolumn.add_attribute(renderer, 'foreground', 3)
425     tvcolumn.add_attribute(renderer, 'weight', 4)
426     if(i==2):
427     tvcolumn.add_attribute(renderer, 'editable', 5)
428     renderer.connect('edited',self.cell_edited_callback)
429     i = i + 1
430    
431    
432     if(len(args)==1):
433     self.do_open(args[0])
434    
435     print "Options: ",options
436    
437     if options.model:
438     try:
439     _t =self.library.findType(options.model);
440     self.do_sim(_t);
441     except RuntimeError, e:
442     self.reporter.reportError("Failed to create instance of '%s': %s" %(options.model, str(e)));
443    
444 johnpye 223
445 johnpye 132 def run(self):
446     self.window.show()
447     gtk.main()
448    
449     # --------------------------------------------
450     # MAJOR GUI COMMANDS
451    
452    
453     def do_open(self,filename):
454     # TODO does the user want to lose their work?
455     # TODO do we need to chdir?
456    
457 johnpye 164 _context = self.statusbar.get_context_id("do_open")
458    
459 johnpye 132 self.errorstore.clear()
460    
461     self.treestore.clear()
462     self.otank = {}
463    
464 johnpye 175 # self.library.clear()
465 johnpye 164
466     self.statusbar.push(_context,"Loading '"+filename+"'")
467 johnpye 132 self.library.load(filename)
468 johnpye 164 self.statusbar.pop(_context)
469 johnpye 132
470     self.filename = filename
471    
472     # Load the current list of modules into self.modules
473     self.modtank = {}
474     self.modulestore.clear()
475     modules = self.library.getModules()
476 johnpye 338 self.library.listModules()
477     try:
478     _lll=len(modules)
479     except:
480     _msg = "UNABLE TO ACCESS MODULES LIST. This is bad.\n"+\
481     "Check your SWIG configuration (check for warnings during build)."+\
482     "\nThis is a known problem with the MinGW build at present."
483    
484     self.reporter.reportError(_msg)
485     raise RuntimeError(_msg)
486    
487 johnpye 132 for m in reversed(modules):
488     _n = str( m.getName() )
489     _f = str( m.getFilename() )
490     #print "ADDING ROW name %s, file = %s" % (_n, _f)
491 johnpye 355 _r = self.modulestore.append(None, [ _n, _f, pango.WEIGHT_NORMAL ])
492 johnpye 132 for t in self.library.getModuleTypes(m):
493     _n = t.getName()
494 johnpye 355 _hasparams = t.hasParameters()
495     if _hasparams:
496     _w = pango.WEIGHT_NORMAL
497     else:
498     _w = pango.WEIGHT_BOLD
499    
500 johnpye 132 #print "ADDING TYPE %s" % _n
501 johnpye 355 _piter = self.modulestore.append(_r , [ _n, "", _w ])
502 johnpye 132 _path = self.modulestore.get_path(_piter)
503     self.modtank[_path]=t
504    
505     #print "DONE ADDING MODULES"
506    
507     self.sim = None;
508     self.maintabs.set_current_page(0);
509 johnpye 164
510 johnpye 168 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
511     # for details on how the 'wait cursor' is done.
512 johnpye 164 def start_waiting(self, message):
513     self.waitcontext = self.statusbar.get_context_id("waiting")
514     self.statusbar.push(self.waitcontext,message)
515    
516     if self.waitwin:
517     self.waitwin.show()
518    
519     while gtk.events_pending():
520     gtk.main_iteration()
521 johnpye 132
522 johnpye 164 def stop_waiting(self):
523     if self.waitwin:
524     self.statusbar.pop(self.waitcontext)
525     self.waitwin.hide()
526    
527 johnpye 132 def do_sim(self, type_object):
528     self.sim = None;
529     # TODO: clear out old simulation first!
530    
531     print "DO_SIM(%s)" % str(type_object.getName())
532 johnpye 164 self.start_waiting("Compiling...")
533    
534 johnpye 277 try:
535     self.sim = type_object.getSimulation(str(type_object.getName())+"_sim")
536     except RuntimeError, e:
537     self.stop_waiting()
538     self.reporter.reportError(str(e))
539     return
540    
541 johnpye 132 print "...DONE 'getSimulation'"
542 johnpye 164 self.stop_waiting()
543 johnpye 132
544 johnpye 164 self.start_waiting("Building simulation...")
545 johnpye 132 print "BUILDING SIMULATION"
546 johnpye 277
547     try:
548     self.sim.build()
549     except RuntimeError, e:
550     self.stop_waiting()
551     self.reporter.reportError(str(e))
552     return;
553    
554 johnpye 132 print "DONE BUILDING"
555 johnpye 164 self.stop_waiting()
556 johnpye 132
557 johnpye 463 self.sim.setSolver(ascpy.Solver("QRSlv"))
558 johnpye 223
559 johnpye 132 # empty things out first
560     self.methodstore.clear()
561     self.treestore.clear()
562    
563     # methods
564     _methods = self.sim.getType().getMethods()
565 johnpye 160 _activemethod = None;
566 johnpye 132 for _m in _methods:
567 johnpye 160 _i = self.methodstore.append([_m.getName()])
568     if _m.getName()=="default_self":
569     self.methodsel.set_active_iter(_i)
570 johnpye 132
571     # instance hierarchy
572     self.otank = {} # map path -> (name,value)
573     self.make( self.sim.getName(),self.sim.getModel() )
574     self.maintabs.set_current_page(1);
575 johnpye 249
576     def do_solve_if_auto(self):
577     if self.is_auto:
578     self.sim.check()
579     self.do_solve()
580     else:
581 johnpye 255 self.sim.processVarStatus()
582 johnpye 249 self.refreshtree()
583    
584     self.sync_observers()
585 johnpye 132
586     def do_solve(self):
587     if not self.sim:
588     self.reporter.reportError("No model selected yet")
589 johnpye 171 return;
590 johnpye 132
591 johnpye 168 self.start_waiting("Solving...")
592 johnpye 164
593 johnpye 321 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
594 johnpye 351 reporter = PopupSolverReporter(self,self.sim.getNumVars())
595 johnpye 321 else:
596     reporter = SimpleSolverReporter(self)
597    
598 johnpye 463 self.sim.solve(ascpy.Solver("QRSlv"),reporter)
599 johnpye 164
600 johnpye 168 self.stop_waiting()
601 johnpye 255
602     self.sim.processVarStatus()
603 johnpye 132 self.refreshtree()
604    
605     def do_check(self):
606     if not self.sim:
607     self.reporter.reportError("No model selected yet")
608    
609 johnpye 171 self.start_waiting("Checking system...")
610    
611 johnpye 278 try:
612     if self.sim.check():
613     self.reporter.reportNote("System check OK")
614     self.sim.checkDoF()
615     except RuntimeError, e:
616     self.stop_waiting()
617     self.reporter.reportError(str(e))
618     return
619 johnpye 171
620     self.stop_waiting()
621    
622 johnpye 132 self.refreshtree()
623    
624     def do_method(self,method):
625     if not self.sim:
626     self.reporter.reportError("No model selected yet")
627    
628     self.sim.run(method)
629     self.refreshtree()
630    
631 johnpye 230 def do_quit(self):
632     self.reporter.clearPythonErrorCallback()
633     _w,_h = self.window.get_size()
634     _t,_l = self.window.get_position()
635     _display = self.window.get_screen().get_display().get_name()
636     self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
637    
638     _p = self.browserpaned.get_position()
639     self.prefs.setGeometryValue(_display,"browserpaned",_p);
640    
641     # causes prefs to be saved unless they are still being used elsewher
642     del(self.prefs)
643    
644     gtk.main_quit()
645     print "GTK QUIT"
646     return False
647    
648 johnpye 231 def on_tools_sparsity_click(self,*args):
649 johnpye 237
650     self.reporter.reportNote("Preparing incidence matrix...")
651 johnpye 233 _im = self.sim.getIncidenceMatrix();
652 johnpye 231
653 johnpye 237 self.reporter.reportNote("Plotting incidence matrix...")
654 johnpye 234
655 johnpye 237 _sp = IncidenceMatrixWindow(_im);
656     _sp.run();
657    
658 johnpye 280 def on_diagnose_blocks_click(self,*args):
659 johnpye 285 try:
660     _bl = self.sim.getActiveBlock()
661     except RuntimeError, e:
662     self.reporter.reportError(str(e))
663     return
664 johnpye 351 _db = DiagnoseWindow(self,_bl)
665 johnpye 280 _db.run();
666    
667 johnpye 245 def on_add_observer_click(self,*args):
668 johnpye 361 if len(self.observers) > 0:
669 johnpye 246 self.reporter.reportError("Not supported: multiple observers")
670     return
671 johnpye 361 self.create_observer()
672 johnpye 245
673 johnpye 250 def on_keep_observed_click(self,*args):
674     if len(self.observers) > 1:
675     self.reporter.reportError("Not supported: multiple observers")
676     return
677     if len(self.observers) <= 0:
678     self.reporter.reportError("No observer defined!")
679     return
680     self.observers[0].do_add_row()
681    
682     def on_copy_observer_matrix_click(self,*args):
683 johnpye 251 if self.clip == None:
684     self.clip = gtk.Clipboard()
685    
686 johnpye 250 if len(self.observers) > 1:
687     self.reporter.reportError("Not supported: multiple observers")
688     return
689     if len(self.observers) <= 0:
690     self.reporter.reportError("No observer defined!")
691     return
692 johnpye 251 self.observers[0].copy_to_clipboard(self.clip)
693 johnpye 270
694 johnpye 299 def on_fix_variable_activate(self,*args):
695     _path,_col = self.treeview.get_cursor()
696     _instance = self.otank[_path][1]
697     self.set_fixed(_instance,True)
698    
699     def on_free_variable_activate(self,*args):
700     _path,_col = self.treeview.get_cursor()
701     _instance = self.otank[_path][1]
702     self.set_fixed(_instance,False)
703    
704     def set_fixed(self,instance,val):
705     if instance.getType().isRefinedSolverVar():
706     f = instance.isFixed();
707     if (f and not val) or (not f and val):
708     instance.setFixed(val)
709 johnpye 321 self.do_solve_if_auto()
710 johnpye 299
711 johnpye 321 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
712     _v = checkmenuitem.get_active()
713     self.prefs.setBoolPref("SolverReporter","show_popup",_v)
714     print "SET TO",_v
715    
716     def on_close_on_converged_toggle(self,checkmenuitem,*args):
717     _v = checkmenuitem.get_active()
718     self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
719    
720     def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
721     _v = checkmenuitem.get_active()
722     self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
723    
724 johnpye 328 def on_show_variables_near_bounds_activate(self,*args):
725     _epsilon = 1e-4;
726     _vars = self.sim.getVariablesNearBounds(_epsilon)
727     print "VARIABLES NEAR BOUNDS"
728     for _v in _vars:
729     print _v.getName();
730    
731 johnpye 132 # --------------------------------------------
732     # MODULE LIST
733    
734     def module_activated(self, treeview, path, column, *args):
735     modules = self.library.getModules()
736     print "PATH",path
737     if len(path)==1:
738     self.reporter.reportNote("Launching of external editor not yet implemented")
739     elif len(path)==2:
740     if(self.modtank.has_key(path)):
741     _type = self.modtank[path];
742     self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
743     self.do_sim(_type)
744     else:
745     self.reporter.reportError("Didn't find type corresponding to row")
746    
747     # --------------------------------------------
748     # INSTANCE TREE
749    
750 johnpye 255 def get_tree_row_data(self,instance): # for instance browser
751 johnpye 132 _value = str(instance.getValue())
752     _type = str(instance.getType())
753     _name = str(instance.getName())
754     _fgcolor = "black"
755     _fontweight = pango.WEIGHT_NORMAL
756     _editable = False
757 johnpye 273 _statusicon = None
758 johnpye 132 if instance.getType().isRefinedSolverVar():
759     _editable = True
760 johnpye 255 _fontweight = pango.WEIGHT_BOLD
761 johnpye 132 if instance.isFixed():
762 johnpye 255 _fgcolor = BROWSER_FIXED_COLOR
763 johnpye 132 else:
764 johnpye 255 _fgcolor = BROWSER_FREE_COLOR
765 johnpye 132 _fontweight = pango.WEIGHT_BOLD
766 johnpye 273 _status = instance.getVarStatus();
767     _statusicon = self.statusicons[_status]
768    
769 johnpye 132 elif instance.isBool() or instance.isReal() or instance.isInt():
770     # TODO can't edit constants that have already been refined
771     _editable = True
772    
773     #if(len(_value) > 80):
774     # _value = _value[:80] + "..."
775    
776 johnpye 255 return [_name, _type, _value, _fgcolor, _fontweight, _editable, _statusicon]
777 johnpye 132
778 johnpye 255 def make_row( self, piter, name, value ): # for instance browser
779 johnpye 132
780     _piter = self.treestore.append( piter, self.get_tree_row_data(value) )
781     return _piter
782    
783     def refreshtree(self):
784     # @TODO FIXME use a better system than colour literals!
785     for _path in self.otank: # { path : (name,value) }
786     _iter = self.treestore.get_iter(_path)
787     _name, _instance = self.otank[_path]
788     self.treestore.set_value(_iter, 2, _instance.getValue())
789     if _instance.getType().isRefinedSolverVar():
790 johnpye 255 if _instance.isFixed() and self.treestore.get_value(_iter,3)==BROWSER_FREE_COLOR:
791     self.treestore.set_value(_iter,3,BROWSER_FIXED_COLOR)
792     elif not _instance.isFixed() and self.treestore.get_value(_iter,3)==BROWSER_FIXED_COLOR:
793     self.treestore.set_value(_iter,3,BROWSER_FREE_COLOR)
794 johnpye 273 self.treestore.set_value(_iter, 6, self.statusicons[_instance.getVarStatus()])
795 johnpye 132
796     def cell_edited_callback(self, renderer, path, newtext, **kwargs):
797     # get back the Instance object we just edited (having to use this seems like a bug)
798     path = tuple( map(int,path.split(":")) )
799    
800     if not self.otank.has_key(path):
801     raise RuntimeError("cell_edited_callback: invalid path '%s'" % path)
802     return
803    
804     _name, _instance = self.otank[path]
805    
806     if _instance.isReal():
807     # only real-valued things can have units
808    
809 johnpye 268 _e = RealAtomEntry(_instance,newtext);
810 johnpye 132 try:
811 johnpye 268 _e.checkEntry()
812     _e.setValue()
813     _e.exportPreferredUnits(self.prefs)
814     except InputError, e:
815     self.reporter.reportError(str(e))
816     return;
817 johnpye 132
818     else:
819     if _instance.isBool():
820     _lower = newtext.lower();
821     if _lower.startswith("t") or _lower.startswith("y") or _lower.strip()=="1":
822     newtext = 1
823     elif _lower.startswith("f") or _lower.startswith("n") or _lower.strip()=="0":
824     newtext = 0
825     else:
826     self.reporter.reportError("Invalid entry for a boolean variable: '%s'" % newtext)
827     return
828     _val = bool(newtext);
829     if _val == _instance.getValue():
830     self.reporter.reportNote("Boolean atom '%s' was not altered" % _instance.getName())
831     return
832     _instance.setBoolValue(_val)
833    
834     elif _instance.isInt():
835     _val = int(newtext)
836     if _val == _instance.getValue():
837     self.reporter.reportNote("Integer atom '%s' was not altered" % _instance.getName())
838     return
839     _instance.setIntValue(_val)
840     else:
841     self.reporter.reportError("Attempt to set a non-real, non-boolean, non-integer value!")
842     return
843    
844     # now that the variable is set, update the GUI and re-solve if desired
845     _iter = self.treestore.get_iter(path)
846     self.treestore.set_value(_iter,2,_instance.getValue())
847    
848     if _instance.getType().isRefinedSolverVar():
849 johnpye 255 self.treestore.set_value(_iter,3,BROWSER_FIXED_COLOR) # set the row green as fixed
850 johnpye 132
851 johnpye 249 self.do_solve_if_auto()
852 johnpye 132
853     def make_children(self, value, piter ):
854     if value.isCompound():
855     children=value.getChildren();
856     for child in children:
857     _name = child.getName();
858     _piter = self.make_row(piter,_name,child)
859     _path = self.treestore.get_path(_piter)
860     self.otank[_path]=(_name,child)
861     #self.reporter.reportError("2 Added %s at path %s" % (_name,repr(_path)))
862    
863     def make(self, name=None, value=None, path=None, depth=1):
864     if path is None:
865     # make root node
866     piter = self.make_row( None, name, value )
867     path = self.treestore.get_path( piter )
868     self.otank[ path ] = (name, value)
869     #self.reporter.reportError("4 Added %s at path %s" % (name, path))
870     else:
871     name, value = self.otank[ path ]
872    
873     piter = self.treestore.get_iter( path )
874     if not self.treestore.iter_has_child( piter ):
875     self.make_children(value,piter)
876    
877     if depth:
878     for i in range( self.treestore.iter_n_children( piter ) ):
879     self.make( path = path+(i,), depth = depth - 1 )
880 johnpye 160 else:
881     self.treeview.expand_row("0",False)
882 johnpye 132
883     def row_expanded( self, treeview, piter, path ):
884     self.make( path = path )
885    
886     # ----------------------------------
887     # ERROR PANEL
888    
889 johnpye 255 def get_error_row_data(self,sev,filename,line,msg):
890     _sevicon = {
891     0: self.iconok
892     ,1: self.iconinfo
893     ,2: self.iconwarning
894     ,3: self.iconerror
895     ,4: self.iconinfo
896     ,5: self.iconwarning
897     ,6: self.iconerror
898     }[sev]
899    
900     _fontweight = pango.WEIGHT_NORMAL
901     if sev==6:
902     _fontweight = pango.WEIGHT_BOLD
903    
904     _fgcolor = "black"
905     if sev==4:
906     _fgcolor = "#888800"
907     elif sev==5:
908     _fgcolor = "#884400"
909     elif sev==6:
910     _fgcolor = "#880000"
911     elif sev==0:
912     _fgcolor = BROWSER_FIXED_COLOR
913    
914     if not filename and not line:
915     _fileline = ""
916     else:
917     if(len(filename) > 25):
918     filename = "..."+filename[-22:]
919     _fileline = filename + ":" + str(line)
920    
921     _res = [_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight]
922     #print _res
923     return _res
924    
925 johnpye 132 def error_callback(self,sev,filename,line,msg):
926     pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
927     path = self.errorstore.get_path(pos)
928     col = self.errorview.get_column(3)
929     self.errorview.scroll_to_cell(path,col)
930    
931     return 0;
932    
933     # --------------------------------
934     # BUTTON METHODS
935    
936     def open_click(self,*args):
937     dialog = gtk.FileChooserDialog("Open file...",
938 johnpye 160 None,
939     gtk.FILE_CHOOSER_ACTION_OPEN,
940     (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
941     gtk.STOCK_OPEN, gtk.RESPONSE_OK))
942 johnpye 132 dialog.set_default_response(gtk.RESPONSE_OK)
943 johnpye 329 dialog.set_transient_for(self.window)
944     dialog.set_modal(True)
945 johnpye 132
946     filter = gtk.FileFilter()
947     filter.set_name("*.a4c, *.a4l")
948     filter.add_pattern("*.[Aa]4[Cc]")
949     filter.add_pattern("*.[Aa]4[Ll]")
950     dialog.add_filter(filter)
951    
952     filter = gtk.FileFilter()
953     filter.set_name("All files")
954     filter.add_pattern("*")
955     dialog.add_filter(filter)
956    
957     response = dialog.run()
958     _filename = dialog.get_filename()
959 johnpye 329 print "FILENAME SELECTED:",_filename
960     dialog.hide()
961 johnpye 132
962     if response == gtk.RESPONSE_OK:
963     self.reporter.reportNote("File %s selected." % dialog.get_filename() )
964 johnpye 185 self.library.clear()
965 johnpye 329 self.do_open( _filename)
966 johnpye 132
967     def reload_click(self,*args):
968     _type = None
969     if(self.sim):
970     _type = self.sim.getType().getName().toString();
971    
972 johnpye 185 self.library.clear()
973 johnpye 132 self.do_open(self.filename)
974    
975     if _type:
976     _t = self.library.findType(_type)
977     self.do_sim(_t)
978    
979     def solve_click(self,*args):
980     #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
981     self.do_solve()
982    
983     def check_click(self,*args):
984     self.do_check()
985     #self.reporter.reportError("CHECK clicked")
986    
987 johnpye 208 def preferences_click(self,*args):
988     if not self.sim:
989     self.reporter.reportError("No simulation created yet!");
990    
991 johnpye 351 _paramswin = SolverParametersWindow(self)
992 johnpye 223 _paramswin.show()
993 johnpye 221
994 johnpye 132 def methodrun_click(self,*args):
995     _sel = self.methodsel.get_active_text()
996     if _sel:
997     _method = None
998     _methods = self.sim.getType().getMethods()
999     for _m in _methods:
1000     if _m.getName()==_sel:
1001     _method = _m
1002     if not _method:
1003     self.reporter.reportError("Method is not valid")
1004     return
1005     self.do_method(_method)
1006     else:
1007     self.reporter.reportError("No method selected")
1008    
1009     def auto_toggle(self,button,*args):
1010 johnpye 230 self.is_auto = button.get_active()
1011     self.automenu.set_active(self.is_auto)
1012    
1013     if self.is_auto:
1014 johnpye 168 self.reporter.reportSuccess("Auto mode is now ON")
1015 johnpye 132 else:
1016 johnpye 168 self.reporter.reportSuccess("Auto mode is now OFF")
1017 johnpye 132
1018 johnpye 230 def on_file_quit_click(self,*args):
1019     self.do_quit()
1020    
1021     def on_tools_auto_toggle(self,checkmenuitem,*args):
1022     self.is_auto = checkmenuitem.get_active()
1023     self.autotoggle.set_active(self.is_auto)
1024    
1025     def on_help_about_click(self,*args):
1026 johnpye 436 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1027 johnpye 307 _about = _xml.get_widget("aboutdialog")
1028 johnpye 328 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1029     _about.set_transient_for(self.window);
1030 johnpye 478 _about.set_version(config.VERSION)
1031 johnpye 307 _about.run()
1032     _about.destroy()
1033 johnpye 230
1034     def on_help_contents_click(self,*args):
1035     _help = Help(HELP_ROOT)
1036     _help.run()
1037    
1038 johnpye 290 def on_find_fixable_variables_activate(self,*args):
1039     v = self.sim.getFixableVariables()
1040     for var in v:
1041     print "FIXABLE:",var
1042    
1043 johnpye 245 def create_observer(self,name=None):
1044     if name==None:
1045     name="New Observer"
1046    
1047 johnpye 436 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1048 johnpye 245 _label = gtk.Label();
1049     _label.set_text(name)
1050 johnpye 252 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1051     self.observers.append(ObserverTab(_xml, name, self, _tab))
1052 johnpye 249
1053     def sync_observers(self):
1054     for _o in self.observers:
1055     _o.sync()
1056    
1057 johnpye 132 # ------------------------------
1058     # CONTEXT MENU
1059    
1060 johnpye 270 def on_treeview_event(self,widget,event):
1061     _contextmenu = False;
1062 johnpye 271 if event.type==gtk.gdk.KEY_PRESS and gtk.gdk.keyval_name(event.keyval)=='Menu':
1063     _contextmenu = True
1064     _path, _col = self.treeview.get_cursor()
1065     _button = 3;
1066 johnpye 270 elif event.type==gtk.gdk.BUTTON_PRESS:
1067     if event.button == 3:
1068     _contextmenu = True
1069     _x = int(event.x)
1070     _y = int(event.y)
1071     _button = event.button
1072     _pthinfo = self.treeview.get_path_at_pos(_x, _y)
1073     if _pthinfo == None:
1074     return
1075     _path, _col, _cellx, _celly = _pthinfo
1076    
1077 johnpye 132 # which button was clicked?
1078 johnpye 270 if not _contextmenu:
1079     return
1080 johnpye 172
1081 johnpye 270 _canpop = False;
1082     # self.reporter.reportError("Right click on %s" % self.otank[_path][0])
1083     _instance = self.otank[_path][1]
1084     if _instance.getType().isRefinedSolverVar():
1085     _canpop = True;
1086     self.observemenuitem.set_sensitive(True)
1087     if _instance.isFixed():
1088     self.fixmenuitem.set_sensitive(False)
1089     self.freemenuitem.set_sensitive(True)
1090     else:
1091     self.fixmenuitem.set_sensitive(True)
1092     self.freemenuitem.set_sensitive(False)
1093     elif _instance.isRelation():
1094     _canpop = True;
1095     self.propsmenuitem.set_sensitive(True)
1096 johnpye 172
1097 johnpye 270 if _instance.isPlottable():
1098     self.plotmenuitem.set_sensitive(True)
1099     _canpop = True;
1100     else:
1101     self.plotmenuitem.set_sensitive(False)
1102 johnpye 132
1103 johnpye 270 if not _canpop:
1104     return
1105    
1106     self.treeview.grab_focus()
1107     self.treeview.set_cursor( _path, _col, 0)
1108     self.treecontext.popup( None, None, None, _button, event.time)
1109     return 1
1110    
1111 johnpye 132 def fix_activate(self,widget):
1112     _path,_col = self.treeview.get_cursor()
1113     _name, _instance = self.otank[_path]
1114 johnpye 299 self.set_fixed(_instance,True);
1115 johnpye 132 _instance.setFixed(True)
1116     return 1
1117    
1118     def free_activate(self,widget):
1119     _path,_col = self.treeview.get_cursor()
1120     _instance = self.otank[_path][1]
1121 johnpye 299 self.set_fixed(_instance,False)
1122 johnpye 132 return 1
1123    
1124 johnpye 172 def plot_activate(self,widget):
1125 johnpye 175 self.reporter.reportNote("plot_activate...");
1126 johnpye 172 _path,_col = self.treeview.get_cursor()
1127     _instance = self.otank[_path][1]
1128     if not _instance.isPlottable():
1129 johnpye 175 self.reporter.reportError("Can't plot instance %s" % _instance.getName().toString())
1130 johnpye 172 return
1131 johnpye 175 else:
1132     self.reporter.reportNote("Instance %s about to be plotted..." % _instance.getName().toString())
1133 johnpye 172
1134 johnpye 175 print("Plotting instance '%s'..." % _instance.getName().toString())
1135    
1136 johnpye 176 _plot = _instance.getPlot()
1137 johnpye 175
1138 johnpye 176 print "Title: ", _plot.getTitle()
1139 johnpye 180 _plot.show(True)
1140 johnpye 176
1141 johnpye 172 return 1
1142    
1143 johnpye 181 def props_activate(self,widget):
1144 johnpye 207 _path,_col = self.treeview.get_cursor()
1145     _instance = self.otank[_path][1]
1146     if _instance.isRelation():
1147 johnpye 215 print "Relation '"+_instance.getName().toString()+"':", \
1148     _instance.getRelationAsString(self.sim.getModel())
1149 johnpye 351 _dia = RelPropsWin(self,_instance);
1150 johnpye 273 _dia.run();
1151 johnpye 268 elif _instance.getType().isRefinedSolverVar():
1152 johnpye 351 _dia = VarPropsWin(self,_instance);
1153 johnpye 268 _dia.run();
1154 johnpye 207 else:
1155 johnpye 271 self.reporter.reportWarning("Select a variable first...")
1156 johnpye 172
1157 johnpye 246 def observe_activate(self,widget):
1158     _path,_col = self.treeview.get_cursor()
1159     _instance = self.otank[_path][1]
1160     if _instance.getType().isRefinedSolverVar():
1161     print "OBSERVING",_instance.getName().toString()
1162     if len(self.observers) > 1:
1163 johnpye 361 self.reporter.reportError("Not implemented: multiple observers (currently %d observers)" %
1164     len(self.observers) )
1165 johnpye 246 return
1166     if len(self.observers) ==0:
1167     self.create_observer()
1168     _observer = self.observers[0]
1169     _observer.add_instance(_instance)
1170 johnpye 270
1171     def delete_event(self, widget, event):
1172 johnpye 230 self.do_quit()
1173 johnpye 132 return False
1174    
1175 johnpye 478 if __name__ == "__main__":
1176 johnpye 132 b = Browser();
1177     b.run()

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