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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


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

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