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

Annotation of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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