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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 725 - (show annotations) (download) (as text)
Mon Jul 3 11:52:45 2006 UTC (14 years, 2 months ago) by johnpye
File MIME type: text/x-python
File size: 28398 byte(s)
Fixed a *stupid* bug with relation.c in CreateBlackBoxRelation...
1 #!/usr/bin/env python
2
3 import sys
4 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
11 try:
12 print_loading_status("Loading PSYCO")
13
14 #try:
15 # import psyco
16 # psyco.full()
17 # print "Running with PSYCO optimisation..."
18 #except ImportError:
19 # pass
20
21
22 print_loading_status("Loading python standard libraries")
23
24 import re
25 import urlparse
26 import optparse
27 import platform
28 import sys
29 import os.path
30
31 if platform.system() != "Windows":
32 import dl
33 # This sets the flags for dlopen used by python so that the symbols in the
34 # ascend library are made available to libraries dlopened within ASCEND:
35 sys.setdlopenflags(dl.RTLD_GLOBAL|dl.RTLD_NOW)
36
37 print_loading_status("Loading LIBASCEND/ascpy")
38 import ascpy
39
40 print_loading_status("Loading PyGTK, glade, pango")
41
42 import pygtk
43 pygtk.require('2.0')
44 import gtk
45 import gtk.glade
46 import pango
47
48 print_loading_status("Loading python matplotlib")
49 try:
50 import matplotlib
51 matplotlib.use('GTKAgg')
52
53 try:
54 print_loading_status("Trying python numpy")
55 import numpy
56 matplotlib.rcParams['numerix'] = 'numpy'
57 print_loading_status("","Using python module numpy")
58 except ImportError:
59 try:
60 print_loading_status("Trying python numarray")
61 import numarray
62 matplotlib.rcParams['numerix'] = 'numarray'
63 print_loading_status("","Using python module numarray")
64 except ImportError:
65 try:
66 print_loading_status("Trying python Numeric")
67 import Numeric
68 matplotlib.rcParams['numerix'] = 'Numeric'
69 print_loading_status("","Using python module Numeric")
70 except ImportError:
71 print_loading_status("","FAILED TO LOAD A NUMERIC MODULE FOR PYTHON")
72
73 except ImportError,e:
74 print_loading_status("","FAILED TO LOAD MATPLOTLIB")
75 raise RuntimeError("Failed to load MATPLOTLIB (is it installed?). Details:"+str(e))
76
77 print_loading_status("Loading IPython")
78 import console;
79 if not console.have_ipython:
80 print_loading_status("","IPython couldn't be loaded")
81
82 print_loading_status("Loading ASCEND python modules")
83 from preferences import * # loading/saving of .ini options
84 from solverparameters import * # 'solver parameters' window
85 from help import * # viewing help files
86 from incidencematrix import * # incidence/sparsity matrix matplotlib window
87 from observer import * # observer tab support
88 from properties import * # solver_var properties dialog
89 from varentry import * # for inputting of variables with units
90 from diagnose import * # for diagnosing block non-convergence
91 from solverreporter import * # solver status reporting
92 from modelview import * # model browser
93 from integrator import * # integrator dialog
94 import config
95
96 except RuntimeError, e:
97 print "ASCEND had problems starting up. Please report the following"
98 print "error message at http://mantis.cruncher2.dyndns.org/."
99 print "\n\nFull error message:",str(e)
100 print "\n\nPress ENTER to close this window."
101 sys.stdout.flush()
102 sys.stdin.readline();
103 sys.exit();
104
105 except ImportError, e:
106 print "\n\n------------------ ERROR ---------------------"
107 print "ASCEND had problems importing required models."
108 print "\nPlease ensure you have all the runtime prerequisites installed."
109 print "Please then report a bug if you continue to have problems."
110 print "\nFull error message:",str(e)
111 if platform.system()=="Windows":
112 print "\nYou will also need to report the contents of any popup error"
113 print "messages from Windows if any were shown."
114 print "\n\nPress ENTER to close this window."
115 sys.stdout.flush()
116 sys.stdin.readline();
117 sys.exit();
118
119 print_loading_status("Starting GUI")
120
121 # This is my first ever GUI code so please be nice :)
122 # But I *have* at least read
123 # http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html
124 # and leafed through
125 # http://developer.gnome.org/projects/gup/hig/
126
127 # The fancy tree-view gizmo is the GtkTreeView object. See the article
128 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/300304
129 # for the original source code on which my implementation was based.
130
131 ESCAPE_KEY = 65307
132
133 HELP_ROOT = None
134
135 #======================================
136 # Browser is the main ASCEND library/model browser window
137
138 class Browser:
139
140 # ---------------------------------
141 # SETUP
142
143 def __init__(self):
144 #--------
145 # load the file referenced in the command line, if any
146
147 print_loading_status("Parsing options")
148
149 parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
150 # add options here if we want
151
152 parser.add_option("-m", "--model"
153 ,action="store", type="string", dest="model"
154 ,help="specify the model to instantiate upon loading modules")
155
156 parser.add_option("--pygtk-assets"
157 ,action="store", type="string", dest="assets_dir"
158 ,help="override the configuration value for the location of assets"\
159 +" required by PyGTK for the ASCEND GUI, optional"
160 ,default=config.PYGTK_ASSETS
161 )
162
163 parser.add_option("--library"
164 ,action="store", type="string", dest="library_path"
165 ,help="override the configuration value for the library path"
166 ,default=None
167 )
168
169 parser.add_option("--no-auto-sim"
170 ,action="store_false", dest="auto_sim"
171 ,help="disable auto-instantiation of MODEL named as the file stem"
172 ,default=True
173 )
174
175 (self.options, args) = parser.parse_args()
176
177 #print "OPTIONS_______________:",self.options
178
179 self.assets_dir = self.options.assets_dir
180
181 self.observers = []
182 self.clip = None
183
184 #--------
185 # load up the preferences ini file
186
187 print_loading_status("Loading preferences")
188
189 self.prefs = Preferences()
190
191 _prefpath = self.prefs.getStringPref("Directories","librarypath",None)
192 _preffileopenpath = self.prefs.getStringPref("Directories","fileopenpath",None)
193
194 #--------
195 # set up library path and the path to use for File->Open dialogs
196
197 if self.options.library_path != None:
198 _path = os.path.abspath(self.options.library_path)
199 _pathsrc = "commandline"
200 # when a special path is specified, use that as the file-open location
201 self.fileopenpath = _path
202 else:
203 if _prefpath:
204 _path = _prefpath
205 _pathsrc = "user preferences"
206 else:
207 _path = config.LIBRARY_PATH
208 _pathsrc = "default (config.py)"
209
210 if _preffileopenpath:
211 self.fileopenpath = _preffileopenpath
212 else:
213 self.fileopenpath = _path
214
215 #--------
216 # Create the ASCXX 'Library' object
217
218 print_loading_status("Creating ASCEND 'Library' object","PATH = "+_path+" FROM "+_pathsrc)
219 self.library = ascpy.Library(_path)
220
221 self.sim = None
222
223 #-------------------
224 # Set up the window and main widget actions
225
226 print_loading_status("Setting up windows")
227
228 self.glade_file = self.assets_dir+config.GLADE_FILE
229 glade = gtk.glade.XML(self.glade_file,"browserwin")
230
231 self.window = glade.get_widget("browserwin")
232
233
234 if not self.window:
235 raise RuntimeError("Couldn't load window from glade file")
236
237 _display = self.window.get_screen().get_display().get_name()
238 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
239 if _geom:
240 self.window.resize(_geom[0],_geom[1])
241 self.window.move(_geom[2],_geom[3])
242
243 self.window.connect("delete_event", self.delete_event)
244
245 self.browserpaned=glade.get_widget("browserpaned")
246 _geom2=self.prefs.getGeometryValue(_display,"browserpaned")
247 if _geom2:
248 self.browserpaned.set_position(_geom2)
249
250 self.openbutton=glade.get_widget("openbutton")
251 self.openbutton.connect("clicked",self.open_click)
252
253 self.reloadbutton=glade.get_widget("reloadbutton")
254 self.reloadbutton.connect("clicked",self.reload_click)
255
256 self.solvebutton=glade.get_widget("solvebutton")
257 self.solvebutton.connect("clicked",self.solve_click)
258
259 self.integratebutton=glade.get_widget("integratebutton")
260 self.integratebutton.connect("clicked",self.integrate_click)
261
262 self.checkbutton=glade.get_widget("checkbutton")
263 self.checkbutton.connect("clicked",self.check_click)
264
265 self.autotoggle=glade.get_widget("autotoggle")
266 self.automenu = glade.get_widget("automenu")
267 self.autotoggle.connect("toggled",self.auto_toggle)
268
269 self.methodrunbutton=glade.get_widget("methodrunbutton")
270 self.methodrunbutton.connect("clicked",self.methodrun_click)
271
272 self.methodsel=glade.get_widget("methodsel")
273
274 self.maintabs = glade.get_widget("maintabs")
275
276 self.statusbar = glade.get_widget("statusbar")
277
278 self.menu = glade.get_widget("browsermenu")
279
280 self.show_solving_popup=glade.get_widget("show_solving_popup")
281 self.show_solving_popup.set_active(self.prefs.getBoolPref("SolverReporter","show_popup",True))
282 self.close_on_converged=glade.get_widget("close_on_converged")
283 self.close_on_converged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_converged",True))
284 self.close_on_nonconverged=glade.get_widget("close_on_nonconverged")
285 self.close_on_nonconverged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_nonconverged",True))
286
287 glade.signal_autoconnect(self)
288
289 #-------
290 # Status icons
291
292 self.fixedimg = gtk.Image()
293 self.fixedimg.set_from_file(self.options.assets_dir+'locked.png')
294
295 self.iconstatusunknown = None
296 self.iconfixed = self.fixedimg.get_pixbuf()
297 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
298 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
299 self.iconunsolved = None
300
301 self.statusicons={
302 ascpy.ASCXX_VAR_STATUS_UNKNOWN: self.iconstatusunknown
303 ,ascpy.ASCXX_VAR_FIXED: self.iconfixed
304 ,ascpy.ASCXX_VAR_SOLVED: self.iconsolved
305 ,ascpy.ASCXX_VAR_ACTIVE: self.iconactive
306 ,ascpy.ASCXX_VAR_UNSOLVED: self.iconunsolved
307 }
308
309
310 self.statusmessages={
311 ascpy.ASCXX_VAR_STATUS_UNKNOWN: "Status unknown"
312 ,ascpy.ASCXX_VAR_FIXED: "Fixed"
313 ,ascpy.ASCXX_VAR_SOLVED: "Converged"
314 ,ascpy.ASCXX_VAR_ACTIVE: "Active (unconverged)"
315 ,ascpy.ASCXX_VAR_UNSOLVED: "Not yet visited"
316 }
317
318 #-------------------
319 # waitwin
320
321 self.waitwin = gtk.gdk.Window(self.window.window,
322 gtk.gdk.screen_width(),
323 gtk.gdk.screen_height(),
324 gtk.gdk.WINDOW_CHILD,
325 0,
326 gtk.gdk.INPUT_ONLY)
327
328 _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
329 self.waitwin.set_cursor(_cursor)
330
331 #-------------------
332 # pixbufs to be used in the error listing
333
334 self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
335 self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
336 self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
337 self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
338
339 #--------------------
340 # pixbufs for solver_var status
341
342 #--------------------
343 # set up the error view
344
345 self.errorview = glade.get_widget("errorview")
346 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
347 self.errorstore = gtk.TreeStore(*errstorecolstypes)
348 errtitles = ["","Location","Message"];
349 self.errorview.set_model(self.errorstore)
350 self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
351
352 i = 0
353 for tvcolumn in self.errcols[:len(errtitles)]:
354 tvcolumn.set_title(errtitles[i])
355 self.errorview.append_column(tvcolumn)
356
357 if i>0:
358 _renderer = gtk.CellRendererText()
359 tvcolumn.pack_start(_renderer, True)
360 tvcolumn.add_attribute(_renderer, 'text', i)
361 if(i==2):
362 tvcolumn.add_attribute(_renderer, 'foreground', 3)
363 tvcolumn.add_attribute(_renderer, 'weight', 4)
364 else:
365 _renderer1 = gtk.CellRendererPixbuf()
366 tvcolumn.pack_start(_renderer1, False)
367 tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
368
369 i = i + 1
370
371
372 #--------------------
373 # set up the error reporter callback
374 self.reporter = ascpy.getReporter()
375 self.reporter.setPythonErrorCallback(self.error_callback)
376
377 #--------
378 # Assign an icon to the main window
379
380 self.icon = None
381 if config.ICON_EXTENSION:
382 _iconpath = ""
383 try:
384 _icon = gtk.Image()
385 _iconpath = self.assets_dir+'ascend'+config.ICON_EXTENSION
386 _icon.set_from_file(_iconpath)
387 _iconpbuf = _icon.get_pixbuf()
388 self.window.set_icon(_iconpbuf)
389 self.icon = _iconpbuf
390 except Exception, e:
391 self.reporter.reportError("FAILED to set application icon '%s': %s"
392 % (_iconpath,str(e))
393 )
394
395 #-------------------
396 # set up the module view
397
398 self.modtank = {}
399 self.moduleview = glade.get_widget("moduleview")
400 modulestorecoltypes = [str, str, int] # bool=can-be-instantiated
401 self.modulestore = gtk.TreeStore(*modulestorecoltypes)
402 moduleviewtitles = ["Module name", "Filename"]
403 self.moduleview.set_model(self.modulestore)
404 self.modcols = [ gtk.TreeViewColumn() for _type in modulestorecoltypes]
405 i = 0
406 for modcol in self.modcols[:len(moduleviewtitles)]:
407 modcol.set_title(moduleviewtitles[i])
408 self.moduleview.append_column(modcol)
409 _renderer = gtk.CellRendererText()
410 modcol.pack_start(_renderer, True)
411 modcol.add_attribute(_renderer, 'text', i)
412 modcol.add_attribute(_renderer,'weight',2)
413 i = i + 1
414 self.moduleview.connect("row-activated", self.module_activated )
415
416 #--------------------
417 # set up the methods combobox
418
419 self.methodstore = gtk.ListStore(str)
420 self.methodsel.set_model(self.methodstore)
421 _methodrenderer = gtk.CellRendererText()
422 self.methodsel.pack_start(_methodrenderer, True)
423 self.methodsel.add_attribute(_methodrenderer, 'text',0)
424
425 #--------
426 # set up the instance browser view
427
428 self.modelview = ModelView(self, glade)
429
430 #--------
431 # set the state of the 'auto' toggle
432
433 self.is_auto = self.prefs.getBoolPref("Browser","auto_solve",True)
434 self.autotoggle.set_active(self.is_auto)
435 self.automenu.set_active(self.is_auto)
436
437 #--------
438 # options
439
440 if(len(args)==1):
441 self.do_open(args[0])
442
443 print "Options: ",self.options
444
445 _model = None
446 if self.options.model:
447 _model = self.options.model
448 print "MODEL: '%s'" % _model
449 elif self.options.auto_sim:
450 _model, _ext = os.path.splitext(args[0]);
451
452 if _model:
453 try:
454 _t=self.library.findType(_model)
455 try:
456 self.do_sim(_t)
457 if not self.options.model:
458 self.reporter.reportNote("Instantiating self-titled model '%s'" %_model)
459 except RuntimeError, e:
460 self.reporter.reportError("Failed to create instance of '%s': %s"
461 %(_model, str(e))
462 );
463 except RuntimeError, e:
464 if self.options.model:
465 self.reporter.reportError("Unknown model type '%s': %s"
466 %(_model, str(e))
467 );
468
469 def run(self):
470 self.window.show()
471 print_loading_status("ASCEND is now running")
472 gtk.main()
473
474 # --------------------------------------------
475 # MAJOR GUI COMMANDS
476
477 def on_fix_variable_activate(self,*args):
478 self.modelview.on_fix_variable_activate(*args)
479
480 def on_free_variable_activate(self,*args):
481 self.modelview.on_free_variable_activate(*args)
482
483 def do_open(self,filename):
484 # TODO does the user want to lose their work?
485 # TODO do we need to chdir?
486
487 _context = self.statusbar.get_context_id("do_open")
488
489 self.errorstore.clear()
490
491 self.modelview.clear()
492
493 # self.library.clear()
494
495 self.statusbar.push(_context,"Loading '"+filename+"'")
496 self.library.load(filename)
497 self.statusbar.pop(_context)
498
499 self.filename = filename
500
501 # Load the current list of modules into self.modules
502 self.modtank = {}
503 self.modulestore.clear()
504 modules = self.library.getModules()
505 self.library.listModules()
506 try:
507 _lll=len(modules)
508 except:
509 _msg = "UNABLE TO ACCESS MODULES LIST. This is bad.\n"+\
510 "Check your SWIG configuration (check for warnings during build)."
511
512 self.reporter.reportError(_msg)
513 raise RuntimeError(_msg)
514
515 for m in reversed(modules):
516 _n = str( m.getName() )
517 _f = str( m.getFilename() )
518 #print "ADDING ROW name %s, file = %s" % (_n, _f)
519 _r = self.modulestore.append(None, [ _n, _f, pango.WEIGHT_NORMAL ])
520 for t in self.library.getModuleTypes(m):
521 _n = t.getName()
522 _hasparams = t.hasParameters()
523 if _hasparams:
524 _w = pango.WEIGHT_NORMAL
525 else:
526 _w = pango.WEIGHT_BOLD
527
528 #print "ADDING TYPE %s" % _n
529 _piter = self.modulestore.append(_r , [ _n, "", _w ])
530 _path = self.modulestore.get_path(_piter)
531 self.modtank[_path]=t
532
533 #print "DONE ADDING MODULES"
534
535 self.sim = None;
536 self.maintabs.set_current_page(0);
537
538 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
539 # for details on how the 'wait cursor' is done.
540 def start_waiting(self, message):
541 self.waitcontext = self.statusbar.get_context_id("waiting")
542 self.statusbar.push(self.waitcontext,message)
543
544 if self.waitwin:
545 self.waitwin.show()
546
547 while gtk.events_pending():
548 gtk.main_iteration()
549
550 def stop_waiting(self):
551 if self.waitwin:
552 self.statusbar.pop(self.waitcontext)
553 self.waitwin.hide()
554
555 def do_sim(self, type_object):
556 self.sim = None;
557 # TODO: clear out old simulation first!
558
559 print "DO_SIM(%s)" % str(type_object.getName())
560 self.start_waiting("Compiling...")
561
562 try:
563 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim")
564 except RuntimeError, e:
565 self.stop_waiting()
566 self.reporter.reportError(str(e))
567 return
568
569 print "...DONE 'getSimulation'"
570 self.stop_waiting()
571
572 self.start_waiting("Building simulation...")
573 print "BUILDING SIMULATION"
574
575 try:
576 self.sim.build()
577 except RuntimeError, e:
578 self.stop_waiting()
579 self.reporter.reportError(str(e))
580 return;
581
582 print "DONE BUILDING"
583 self.stop_waiting()
584
585 self.sim.setSolver(ascpy.Solver("QRSlv"))
586
587 # methods
588 self.methodstore.clear()
589 _methods = self.sim.getType().getMethods()
590 _activemethod = None;
591 for _m in _methods:
592 _i = self.methodstore.append([_m.getName()])
593 if _m.getName()=="on_load":
594 self.methodsel.set_active_iter(_i)
595
596 self.modelview.setSimulation(self.sim)
597
598 def do_solve_if_auto(self):
599 if self.is_auto:
600 self.sim.check()
601 self.do_solve()
602 else:
603 self.sim.processVarStatus()
604 self.modelview.refreshtree()
605
606 self.sync_observers()
607
608 def do_solve(self):
609 if not self.sim:
610 self.reporter.reportError("No model selected yet")
611 return
612
613 self.start_waiting("Solving...")
614
615 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
616 reporter = PopupSolverReporter(self,self.sim.getNumVars())
617 else:
618 reporter = SimpleSolverReporter(self)
619
620 self.sim.solve(ascpy.Solver("QRSlv"),reporter)
621
622 self.stop_waiting()
623
624 self.sim.processVarStatus()
625 self.modelview.refreshtree()
626
627 def do_integrate(self):
628 if not self.sim:
629 self.reporter.reportError("No model selected yet")
630 return
631 integwin = IntegratorWindow(self,self.sim)
632 _integratorreporter = integwin.run()
633 if _integratorreporter!=None:
634 _integratorreporter.run()
635 self.sim.processVarStatus()
636 self.modelview.refreshtree()
637
638
639 def do_check(self):
640 if not self.sim:
641 self.reporter.reportError("No model selected yet")
642 return
643
644 self.start_waiting("Checking system...")
645
646 try:
647 if self.sim.check():
648 self.reporter.reportNote("System check OK")
649 self.sim.checkDoF()
650 except RuntimeError, e:
651 self.stop_waiting()
652 self.reporter.reportError(str(e))
653 return
654
655 self.stop_waiting()
656
657 self.modelview.refreshtree()
658
659 def do_method(self,method):
660 if not self.sim:
661 self.reporter.reportError("No model selected yet")
662
663 self.sim.run(method)
664 self.modelview.refreshtree()
665
666 def do_quit(self):
667 print_loading_status("Saving window location")
668 self.reporter.clearPythonErrorCallback()
669
670 _w,_h = self.window.get_size()
671 _t,_l = self.window.get_position()
672 _display = self.window.get_screen().get_display().get_name()
673 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
674
675 _p = self.browserpaned.get_position()
676 self.prefs.setGeometryValue(_display,"browserpaned",_p);
677
678 print_loading_status("Saving current directory")
679 self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
680
681 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
682
683 print_loading_status("Saving preferences")
684 # causes prefs to be saved unless they are still being used elsewher
685 del(self.prefs)
686
687 print_loading_status("Closing down GTK")
688 gtk.main_quit()
689
690 print_loading_status("Clearing error callback")
691 self.reporter.clearPythonErrorCallback()
692
693 print_loading_status("Quitting")
694 return False
695
696 def on_tools_sparsity_click(self,*args):
697
698 self.reporter.reportNote("Preparing incidence matrix...")
699 _im = self.sim.getIncidenceMatrix();
700
701 self.reporter.reportNote("Plotting incidence matrix...")
702
703 _sp = IncidenceMatrixWindow(_im);
704 _sp.run();
705
706 def on_diagnose_blocks_click(self,*args):
707 try:
708 _bl = self.sim.getActiveBlock()
709 except RuntimeError, e:
710 self.reporter.reportError(str(e))
711 return
712 _db = DiagnoseWindow(self,_bl)
713 _db.run();
714
715 def on_add_observer_click(self,*args):
716 if len(self.observers) > 0:
717 self.reporter.reportError("Not supported: multiple observers")
718 return
719 self.create_observer()
720
721 def on_keep_observed_click(self,*args):
722 if len(self.observers) > 1:
723 self.reporter.reportError("Not supported: multiple observers")
724 return
725 if len(self.observers) <= 0:
726 self.reporter.reportError("No observer defined!")
727 return
728 self.observers[0].do_add_row()
729
730 def on_copy_observer_matrix_click(self,*args):
731 if self.clip == None:
732 self.clip = gtk.Clipboard()
733
734 if len(self.observers) > 1:
735 self.reporter.reportError("Not supported: multiple observers")
736 return
737 if len(self.observers) <= 0:
738 self.reporter.reportError("No observer defined!")
739 return
740 self.observers[0].copy_to_clipboard(self.clip)
741
742 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
743 _v = checkmenuitem.get_active()
744 self.prefs.setBoolPref("SolverReporter","show_popup",_v)
745 print "SET TO",_v
746
747 def on_close_on_converged_toggle(self,checkmenuitem,*args):
748 _v = checkmenuitem.get_active()
749 self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
750
751 def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
752 _v = checkmenuitem.get_active()
753 self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
754
755 def on_show_variables_near_bounds_activate(self,*args):
756 _epsilon = 1e-4;
757 _vars = self.sim.getVariablesNearBounds(_epsilon)
758 print "VARIABLES NEAR BOUNDS"
759 for _v in _vars:
760 print _v.getName();
761
762 # --------------------------------------------
763 # MODULE LIST
764
765 def module_activated(self, treeview, path, column, *args):
766 modules = self.library.getModules()
767 print "PATH",path
768 if len(path)==1:
769 self.reporter.reportNote("Launching of external editor not yet implemented")
770 elif len(path)==2:
771 if(self.modtank.has_key(path)):
772 _type = self.modtank[path];
773 self.reporter.reportNote("Creating simulation for type %s" % str(_type.getName()) )
774 self.do_sim(_type)
775 else:
776 self.reporter.reportError("Didn't find type corresponding to row")
777
778 # ----------------------------------
779 # ERROR PANEL
780
781 def get_error_row_data(self,sev,filename,line,msg):
782 _sevicon = {
783 0: self.iconok
784 ,1: self.iconinfo
785 ,2: self.iconwarning
786 ,3: self.iconerror
787 ,4: self.iconinfo
788 ,5: self.iconwarning
789 ,6: self.iconerror
790 }[sev]
791
792 _fontweight = pango.WEIGHT_NORMAL
793 if sev==6:
794 _fontweight = pango.WEIGHT_BOLD
795
796 _fgcolor = "black"
797 if sev==4:
798 _fgcolor = "#888800"
799 elif sev==5:
800 _fgcolor = "#884400"
801 elif sev==6:
802 _fgcolor = "#880000"
803 elif sev==0:
804 _fgcolor = BROWSER_FIXED_COLOR
805
806 if not filename and not line:
807 _fileline = ""
808 else:
809 if(len(filename) > 25):
810 filename = "..."+filename[-22:]
811 _fileline = filename + ":" + str(line)
812
813 _res = [_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight]
814 #print _res
815 return _res
816
817 def error_callback(self,sev,filename,line,msg):
818 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
819 path = self.errorstore.get_path(pos)
820 col = self.errorview.get_column(3)
821 self.errorview.scroll_to_cell(path,col)
822
823 return 0;
824
825 # --------------------------------
826 # BUTTON METHODS
827
828 def open_click(self,*args):
829 #print_loading_status("CURRENT FILEOPENPATH is",self.fileopenpath)
830 dialog = gtk.FileChooserDialog("Open ASCEND model...",
831 self.window,
832 gtk.FILE_CHOOSER_ACTION_OPEN,
833 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
834 )
835 dialog.set_current_folder(self.fileopenpath)
836 dialog.set_default_response(gtk.RESPONSE_OK)
837 dialog.set_transient_for(self.window)
838 dialog.set_modal(True)
839
840 filter = gtk.FileFilter()
841 filter.set_name("*.a4c, *.a4l")
842 filter.add_pattern("*.[Aa]4[Cc]")
843 filter.add_pattern("*.[Aa]4[Ll]")
844 dialog.add_filter(filter)
845
846 filter = gtk.FileFilter()
847 filter.set_name("All files")
848 filter.add_pattern("*")
849 dialog.add_filter(filter)
850
851 response = dialog.run()
852 _filename = dialog.get_filename()
853 print "\nFILENAME SELECTED:",_filename
854
855 _path = dialog.get_current_folder()
856 if _path:
857 self.fileopenpath = _path
858
859 dialog.hide()
860
861 if response == gtk.RESPONSE_OK:
862 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
863 self.library.clear()
864 self.do_open( _filename)
865
866 def reload_click(self,*args):
867 _type = None
868 if(self.sim):
869 _type = self.sim.getType().getName().toString();
870
871 self.library.clear()
872 self.do_open(self.filename)
873
874 if _type:
875 _t = self.library.findType(_type)
876 self.do_sim(_t)
877
878 def props_activate(self,widget,*args):
879 return self.modelview.props_activate(self,widget,*args)
880
881 def observe_activate(self,widget,*args):
882 return self.modelview.observe_activate(self,widget,*args)
883
884 def solve_click(self,*args):
885 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
886 self.do_solve()
887
888 def console_click(self,*args):
889 try:
890 console.start(self)
891 except RuntimeError,e:
892 self.reporter.reportError("Unable to start console: "+str(e));
893
894 def integrate_click(self,*args):
895 self.do_integrate()
896
897 def check_click(self,*args):
898 self.do_check()
899 #self.reporter.reportError("CHECK clicked")
900
901 def preferences_click(self,*args):
902 if not self.sim:
903 self.reporter.reportError("No simulation created yet!");
904
905 _paramswin = SolverParametersWindow(self)
906 _paramswin.show()
907
908 def methodrun_click(self,*args):
909 _sel = self.methodsel.get_active_text()
910 if _sel:
911 _method = None
912 _methods = self.sim.getType().getMethods()
913 for _m in _methods:
914 if _m.getName()==_sel:
915 _method = _m
916 if not _method:
917 self.reporter.reportError("Method is not valid")
918 return
919 self.do_method(_method)
920 else:
921 self.reporter.reportError("No method selected")
922
923 def auto_toggle(self,button,*args):
924 self.is_auto = button.get_active()
925 if hasattr(self,'automenu'):
926 self.automenu.set_active(self.is_auto)
927 else:
928 raise RuntimeError("no automenu")
929
930 #if self.is_auto:
931 # self.reporter.reportSuccess("Auto mode is now ON")
932 #else:
933 # self.reporter.reportSuccess("Auto mode is now OFF")
934
935 def on_file_quit_click(self,*args):
936 self.do_quit()
937
938 def on_tools_auto_toggle(self,checkmenuitem,*args):
939 self.is_auto = checkmenuitem.get_active()
940 self.autotoggle.set_active(self.is_auto)
941
942 def on_help_about_click(self,*args):
943 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
944 _about = _xml.get_widget("aboutdialog")
945 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
946 _about.set_transient_for(self.window);
947 _about.set_version(config.VERSION)
948 _about.run()
949 _about.destroy()
950
951 def on_help_contents_click(self,*args):
952 _help = Help(HELP_ROOT)
953 _help.run()
954
955 def on_find_fixable_variables_activate(self,*args):
956 v = self.sim.getFixableVariables()
957 for var in v:
958 print "FIXABLE:",var
959
960 def create_observer(self,name=None):
961 if name==None:
962 name="New Observer"
963
964 _xml = gtk.glade.XML(self.glade_file,"observervbox");
965 _label = gtk.Label();
966 _label.set_text(name)
967 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
968 self.observers.append(ObserverTab(_xml, name, self, _tab))
969
970 def sync_observers(self):
971 for _o in self.observers:
972 _o.sync()
973
974 def delete_event(self, widget, event):
975 self.do_quit()
976 return False
977
978 def observe(self,instance):
979 if len(self.observers) > 1:
980 self.reporter.reportError("Not implemented: multiple observers (currently %d observers)" %
981 len(self.observers) )
982 return
983 if len(self.observers) ==0:
984 self.create_observer()
985 _observer = self.observers[0]
986 _observer.add_instance(instance)
987
988 if __name__ == "__main__":
989 b = Browser();
990 b.run()

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