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

Annotation of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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