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

Contents of /trunk/pygtk/gtkbrowser.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1761 - (show annotations) (download) (as text)
Wed Mar 5 02:23:14 2008 UTC (12 years, 4 months ago) by jpye
File MIME type: text/x-python
File size: 36353 byte(s)
Clarify that the error comes from missing *python* modules.
1 import sys
2 try:
3 import loading
4 #loading.print_status("Loading PSYCO")
5 #try:
6 # import psyco
7 # psyco.full()
8 # print "Running with PSYCO optimisation..."
9 #except ImportError:
10 # pass
11
12 loading.print_status("Loading python standard libraries")
13
14 import pygtk
15 pygtk.require('2.0')
16 import gtk
17
18 import gtkexcepthook
19
20 import re
21 import urlparse
22 import optparse
23 import platform
24 import sys
25
26 if platform.system() != "Windows":
27 try:
28 import dl
29 _dlflags = dl.RTLD_GLOBAL|dl.RTLD_NOW
30 except:
31 # On platforms that unilaterally refuse to provide the 'dl' module
32 # we'll just set the value and see if it works.
33 loading.print_status("Setting dlopen flags","Python 'dl' module not available on this system")
34 _dlflags = 258
35 # This sets the flags for dlopen used by python so that the symbols in the
36 # ascend library are made available to libraries dlopened within ASCEND:
37 sys.setdlopenflags(_dlflags)
38
39
40
41 loading.print_status("Loading LIBASCEND/ascpy")
42 import ascpy
43 import os.path
44
45 loading.print_status("Loading PyGTK, glade, pango")
46
47 import gtk.glade
48 import pango
49
50 loading.load_matplotlib()
51
52 loading.print_status("Loading ASCEND python modules")
53 from preferences import * # loading/saving of .ini options
54 from solverparameters import * # 'solver parameters' window
55 from help import * # viewing help files
56 from incidencematrix import * # incidence/sparsity matrix matplotlib window
57 from imagewindow import * # image viewer window
58 from observer import * # observer tab support
59 from properties import * # solver_var properties dialog
60 from varentry import * # for inputting of variables with units
61 from diagnose import * # for diagnosing block non-convergence
62 from solverreporter import * # solver status reporting
63 from moduleview import * # module browser
64 from modelview import * # model browser
65 from integrator import * # integrator dialog
66 from infodialog import * # general-purpose textual information dialog
67 from versioncheck import * # version check (contacts ascend.cruncher2.dyndns.org)
68 from unitsdialog import * # general-purpose textual information dialog
69 import config
70
71 #loading.complete();
72
73 except RuntimeError, e:
74 print "ASCEND had problems starting up. Please report the following"
75 print "error message at http://mantis.cruncher2.dyndns.org/."
76 print "\n\nFull error message:",str(e)
77 print "\n\nPress ENTER to close this window."
78 sys.stdout.flush()
79 sys.stdin.readline();
80 sys.exit();
81
82 except ImportError, e:
83 print "\n\n------------------ ERROR ---------------------"
84 print "ASCEND had problems importing required Python modules."
85 print "\nPlease ensure you have all the runtime prerequisites installed."
86 print "Please then report a bug if you continue to have problems."
87 print "\nFull error message:",str(e)
88 if platform.system()=="Windows":
89 print "\nYou will also need to report the contents of any popup error"
90 print "messages from Windows if any were shown."
91 print "\n\nPress ENTER to close this window."
92 sys.stdout.flush()
93 sys.stdin.readline();
94 sys.exit();
95
96 loading.print_status("Starting GUI")
97
98 # This is my first ever GUI code so please be nice :)
99 # But I *have* at least read
100 # http://www.joelonsoftware.com/uibook/chapters/fog0000000057.html
101 # and leafed through
102 # http://developer.gnome.org/projects/gup/hig/
103
104 # The fancy tree-view gizmo is the GtkTreeView object. See the article
105 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/300304
106 # for the original source code on which my implementation was based.
107
108 ESCAPE_KEY = 65307
109
110 HELP_ROOT = None
111
112 #======================================
113 # Browser is the main ASCEND library/model browser window
114
115 class Browser:
116
117 # ---------------------------------
118 # SETUP
119
120 def __init__(self,librarypath=None,assetspath=None):
121
122 if assetspath==None:
123 assetspath=config.PYGTK_ASSETS
124
125 #--------
126 # load the file referenced in the command line, if any
127
128 loading.print_status("Parsing options","CONFIG = %s"%config.VERSION)
129
130 parser = optparse.OptionParser(usage="%prog [[-m typename] file]", version="gtkbrowser $rev$" )
131 # add options here if we want
132
133 parser.add_option("-m", "--model"
134 ,action="store", type="string", dest="model"
135 ,help="specify the model to instantiate upon loading modules")
136
137 parser.add_option("--pygtk-assets"
138 ,action="store", type="string", dest="assets_dir"
139 ,help="override the configuration value for the location of assets"\
140 +" required by PyGTK for the ASCEND GUI, optional"
141 ,default=assetspath
142 )
143
144 parser.add_option("--library"
145 ,action="store", type="string", dest="library_path"
146 ,help="override the configuration value for the library path"
147 ,default=librarypath
148 )
149
150 parser.add_option("--no-auto-sim"
151 ,action="store_false", dest="auto_sim"
152 ,help="disable auto-instantiation of MODEL named as the file stem"
153 ,default=True
154 )
155
156 (self.options, args) = parser.parse_args()
157
158 #print "OPTIONS_______________:",self.options
159
160 self.assets_dir = self.options.assets_dir
161 #loading.create_window(self.assets_dir)
162
163 self.observers = []
164 self.clip = None
165
166 #--------
167 # load up the preferences ini file
168
169 loading.print_status("Loading preferences")
170
171 self.prefs = Preferences()
172
173 _prefpath = self.prefs.getStringPref("Directories","librarypath",None)
174 _preffileopenpath = self.prefs.getStringPref("Directories","fileopenpath",None)
175
176 #--------
177 # set up library path and the path to use for File->Open dialogs
178
179 if self.options.library_path != None:
180 _path = os.path.abspath(self.options.library_path)
181 _pathsrc = "command line options"
182 # when a special path is specified, use the last path component as the file-open location
183 if platform.system()=="Windows":
184 self.fileopenpath = _path.split(":").pop()
185 else:
186 self.fileopenpath = _path.split(":").pop()
187 else:
188 if _prefpath:
189 _path = _prefpath
190 _pathsrc = "user preferences"
191 else:
192 # default setting, but override with Windows registry if present
193 _path = config.LIBRARY_PATH
194 _pathsrc = "default (config.py)"
195
196 if platform.system()=="Windows":
197 # use the registry
198 try:
199 import _winreg
200 x=_winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE)
201 y= _winreg.OpenKey(x,r"SOFTWARE\ASCEND")
202 _regpath,t = _winreg.QueryValueEx(y,"ASCENDLIBRARY")
203 _winreg.CloseKey(y)
204 _winreg.CloseKey(x)
205 _path = _regpath
206 os.environ['ASCENDLIBRARY'] = _regpath
207 _pathsrc = "Windows registry"
208 except:
209 # otherwise keep using the default
210 pass
211
212 if _preffileopenpath:
213 self.fileopenpath = _preffileopenpath
214 else:
215 self.fileopenpath = _path
216
217 #--------
218 # Create the ASCXX 'Library' object
219
220 loading.print_status("Creating ASCEND 'Library' object","ASCENDLIBRARY = "+_path+" FROM "+_pathsrc)
221 self.library = ascpy.Library(str(_path))
222
223 self.sim = None
224
225 #-------------------
226 # Set up the window and main widget actions
227
228 self.glade_file = os.path.join(self.assets_dir,config.GLADE_FILE)
229
230 loading.print_status("Setting up windows") #,"GLADE_FILE = %s" % self.glade_file)
231
232 glade = gtk.glade.XML(self.glade_file,"browserwin")
233
234 self.window = glade.get_widget("browserwin")
235
236
237 if not self.window:
238 raise RuntimeError("Couldn't load window from glade file")
239
240 _display = self.window.get_screen().get_display().get_name()
241 _geom=self.prefs.getGeometrySizePosition(_display,"browserwin")
242 if _geom:
243 self.window.resize(_geom[0],_geom[1])
244 self.window.move(_geom[2],_geom[3])
245
246 self.window.connect("delete_event", self.delete_event)
247
248 self.browserpaned=glade.get_widget("browserpaned")
249 _geom2=self.prefs.getGeometryValue(_display,"browserpaned")
250 if _geom2:
251 self.browserpaned.set_position(_geom2)
252
253 buttons = ["open","reload","solve","integrate","check","methodrun"]
254 for n in buttons:
255 name = "%sbutton"%n
256 setattr(self,name,glade.get_widget(name))
257 getattr(self,name).connect("clicked",getattr(self,"%s_click"%n))
258
259 widgets = ["autotoggle","automenu","methodsel","maintabs","lowertabs","consolescroll","statusbar","browsermenu"]
260 for n in widgets:
261 setattr(self,n,glade.get_widget(n))
262
263 self.autotoggle.connect("toggled",self.auto_toggle)
264
265 self.show_solving_popup=glade.get_widget("show_solving_popup")
266 self.show_solving_popup.set_active(self.prefs.getBoolPref("SolverReporter","show_popup",True))
267 self.close_on_converged=glade.get_widget("close_on_converged")
268 self.close_on_converged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_converged",True))
269 self.close_on_nonconverged=glade.get_widget("close_on_nonconverged")
270 self.close_on_nonconverged.set_active(self.prefs.getBoolPref("SolverReporter","close_on_nonconverged",True))
271 self.solver_engine=glade.get_widget("solver_engine")
272
273 self.use_relation_sharing=glade.get_widget("use_relation_sharing")
274 self.use_relation_sharing.set_active(self.prefs.getBoolPref("Compiler","use_relation_sharing",True))
275
276 self.use_binary_compilation=glade.get_widget("use_binary_compilation")
277 self.use_binary_compilation.set_active(self.prefs.getBoolPref("Compiler","use_binary_compilation",False))
278 self.use_binary_compilation.set_sensitive(self.use_relation_sharing.get_active())
279
280 glade.signal_autoconnect(self)
281
282 #-------
283 # Status icons
284
285 self.fixedimg = gtk.Image()
286 self.fixedimg.set_from_file(os.path.join(self.options.assets_dir,'locked.png'))
287
288 self.inactiveimg = gtk.Image()
289 self.inactiveimg.set_from_file(os.path.join(self.options.assets_dir,'unattached.png'))
290
291 self.iconstatusunknown = None
292 self.iconfixed = self.fixedimg.get_pixbuf()
293 self.iconsolved = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
294 self.iconactive = self.window.render_icon(gtk.STOCK_NO,gtk.ICON_SIZE_MENU)
295 self.iconinactive = self.inactiveimg.get_pixbuf()
296 self.iconunsolved = None
297
298 self.statusicons={
299 ascpy.ASCXX_INST_STATUS_UNKNOWN: self.iconstatusunknown
300 ,ascpy.ASCXX_VAR_FIXED: self.iconfixed
301 ,ascpy.ASCXX_VAR_SOLVED: self.iconsolved
302 ,ascpy.ASCXX_VAR_ACTIVE: self.iconactive
303 ,ascpy.ASCXX_VAR_UNSOLVED: self.iconunsolved
304 ,ascpy.ASCXX_REL_INACTIVE: self.iconinactive
305 }
306
307
308 self.statusmessages={
309 ascpy.ASCXX_INST_STATUS_UNKNOWN: "Status unknown"
310 ,ascpy.ASCXX_VAR_FIXED: "Fixed"
311 ,ascpy.ASCXX_VAR_SOLVED: "Converged"
312 ,ascpy.ASCXX_VAR_ACTIVE: "Active (unconverged)"
313 ,ascpy.ASCXX_VAR_UNSOLVED: "Not yet visited"
314 ,ascpy.ASCXX_REL_INACTIVE: "Inactive"
315 }
316
317 #-------------------
318 # waitwin
319
320 self.waitwin = gtk.gdk.Window(self.window.window,
321 gtk.gdk.screen_width(),
322 gtk.gdk.screen_height(),
323 gtk.gdk.WINDOW_CHILD,
324 0,
325 gtk.gdk.INPUT_ONLY)
326
327 _cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
328 self.waitwin.set_cursor(_cursor)
329
330 #-------------------
331 # pixbufs to be used in the error listing
332
333 self.iconok = self.window.render_icon(gtk.STOCK_YES,gtk.ICON_SIZE_MENU)
334 self.iconinfo = self.window.render_icon(gtk.STOCK_DIALOG_INFO,gtk.ICON_SIZE_MENU)
335 self.iconwarning = self.window.render_icon(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_MENU)
336 self.iconerror = self.window.render_icon(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_MENU)
337
338 #--------------------
339 # pixbufs for solver_var status
340
341 #--------------------
342 # set up the error view
343
344 self.errorview = glade.get_widget("errorview")
345 errstorecolstypes = [gtk.gdk.Pixbuf,str,str,str,int]
346 self.errorstore = gtk.TreeStore(*errstorecolstypes)
347 errtitles = ["","Location","Message"];
348 self.errorview.set_model(self.errorstore)
349 self.errcols = [ gtk.TreeViewColumn() for _type in errstorecolstypes]
350
351 i = 0
352 for tvcolumn in self.errcols[:len(errtitles)]:
353 tvcolumn.set_title(errtitles[i])
354 self.errorview.append_column(tvcolumn)
355
356 if i>0:
357 _renderer = gtk.CellRendererText()
358 tvcolumn.pack_start(_renderer, True)
359 tvcolumn.add_attribute(_renderer, 'text', i)
360 if(i==2):
361 tvcolumn.add_attribute(_renderer, 'foreground', 3)
362 tvcolumn.add_attribute(_renderer, 'weight', 4)
363 else:
364 _renderer1 = gtk.CellRendererPixbuf()
365 tvcolumn.pack_start(_renderer1, False)
366 tvcolumn.add_attribute(_renderer1, 'pixbuf', int(0))
367
368 i = i + 1
369
370
371 #--------------------
372 # set up the error reporter callback
373 self.reporter = ascpy.getReporter()
374 self.reporter.setPythonErrorCallback(self.error_callback)
375
376
377 #-------
378 # Solver engine list
379
380 _slvlist = ascpy.getSolvers()
381 self.solver_engine_menu = gtk.Menu()
382 self.solver_engine_menu.show()
383 self.solver_engine.set_submenu(self.solver_engine_menu)
384 self.solver_engine_menu_dict = {}
385 _fmi = None
386 for _s in _slvlist:
387 _mi = gtk.RadioMenuItem(_fmi,_s.getName(),False)
388 if _fmi==None:
389 _fmi = _mi
390 _mi.show()
391 _mi.connect('toggled',self.on_select_solver_toggled,_s.getName())
392 self.solver_engine_menu.append(_mi)
393 self.solver_engine_menu_dict[_s.getName()]=_mi
394
395 _pref_solver = self.prefs.getStringPref("Solver","engine","QRSlv")
396 _mi = self.solver_engine_menu_dict.get(_pref_solver)
397 if _mi:
398 _mi.set_active(1)
399
400 #--------
401 # Assign an icon to the main window
402
403 self.icon = None
404 if config.ICON_EXTENSION:
405 _iconpath = ""
406 try:
407 _icon = gtk.Image()
408 _iconpath = os.path.join(self.assets_dir,'ascend'+config.ICON_EXTENSION)
409 _icon.set_from_file(_iconpath)
410 _iconpbuf = _icon.get_pixbuf()
411 self.window.set_icon(_iconpbuf)
412 self.icon = _iconpbuf
413 except Exception, e:
414 print "FAILED TO SET APPLICATION ICON PATH '%s': %s" % (_iconpath,str(e))
415 self.reporter.reportError("FAILED to set application icon '%s': %s"
416 % (_iconpath,str(e))
417 )
418
419 #-------------------
420 # set up the module view
421
422 self.modtank = {}
423 self.moduleview = ModuleView(self,glade, self.library)
424
425 #--------------------
426 # set up the methods combobox
427
428 self.methodstore = gtk.ListStore(str)
429 self.methodsel.set_model(self.methodstore)
430 _methodrenderer = gtk.CellRendererText()
431 self.methodsel.pack_start(_methodrenderer, True)
432 self.methodsel.add_attribute(_methodrenderer, 'text',0)
433
434 #--------
435 # set up the instance browser view
436
437 self.modelview = ModelView(self, glade)
438
439 #--------
440 # set up the tabs
441 self.tabs = {}
442 self.activetab = None # most recent observer tab
443
444 #--------
445 # set the state of the 'auto' toggle
446
447 self.is_auto = self.prefs.getBoolPref("Browser","auto_solve",True)
448 self.autotoggle.set_active(self.is_auto)
449 self.automenu.set_active(self.is_auto)
450
451 #--------
452 # tell libascend about this 'browser' object
453
454 #print dir(ascpy.Registry())
455 ascpy.Registry().set("browser",self)
456
457 #--------
458 # options
459
460 if(len(args)==1):
461 try:
462 self.do_open(args[0])
463 except RuntimeError,e:
464 self.reporter.reportError(str(e))
465 return
466
467 #print "Options: ",self.options
468
469 _model = None
470 if self.options.model:
471 _model = self.options.model
472 print "MODEL: '%s'" % _model
473 elif self.options.auto_sim:
474 _head, _tail = os.path.split(args[0])
475 if(_tail):
476 _model, _ext = os.path.splitext(_tail)
477
478 if _model:
479 try:
480 _t=self.library.findType(_model)
481 if not _t.isModel():
482 if self.options.auto_sim:
483 self.reporter.reportError("Won't auto-instantiate with type '%s': not a MODEL." % _model)
484 elif _t.hasParameters():
485 if self.options.auto_sim:
486 self.reporter.reportError("Won't auto-instantiate MODEL %s: model requires parameters." % _model)
487 else:
488 try:
489 self.do_sim(_t)
490 if not self.options.model:
491 self.reporter.reportNote("Instantiated self-titled model '%s'" %_model)
492 except RuntimeError, e:
493 self.reporter.reportError("Failed to create instance of '%s': %s"
494 %(_model, str(e))
495 );
496 except RuntimeError, e:
497 if self.options.model:
498 self.reporter.reportError("Unknown model type '%s': %s"
499 %(_model, str(e))
500 );
501
502
503 #--------
504 # report absence of solvers if nec.
505
506 if not len(ascpy.getSolvers()):
507 print "NO SOLVERS LOADED!"
508 self.reporter.reportError( "No solvers were loaded! ASCEND is probably not configured correctly." )
509
510 #--------
511 # IPython console, if available
512
513 import console
514 console.create_widget(self)
515
516 def run(self):
517 self.window.show()
518 loading.print_status("ASCEND is now running")
519 loading.complete()
520 gtk.main()
521
522 # ------------------
523 # SOLVER LIST
524
525 def set_solver(self,solvername):
526 """ this sets the active solver in the GUI, which is the default applied to newly instantiated models """
527 self.solver = ascpy.Solver(solvername)
528 self.prefs.setStringPref("Solver","engine",solvername)
529 self.reporter.reportNote("Set solver engine to '%s'" % solvername)
530
531 # --------------------------------------------
532 # MAJOR GUI COMMANDS
533
534 def on_fix_variable_activate(self,*args):
535 self.modelview.on_fix_variable_activate(*args)
536
537 def on_free_variable_activate(self,*args):
538 self.modelview.on_free_variable_activate(*args)
539
540 def on_select_solver_toggled(self,widget,solvername):
541 if widget.get_active():
542 self.set_solver(solvername)
543
544 def do_open(self,filename):
545 # TODO does the user want to lose their work?
546 # TODO do we need to chdir?
547
548 _context = self.statusbar.get_context_id("do_open")
549
550 self.errorstore.clear()
551 self.modelview.clear()
552
553 # self.library.clear()
554
555 #print "Filename =",filename
556 self.statusbar.push(_context,"Loading '"+filename+"'")
557 try:
558 self.filename = filename
559 # call the low-level 'load' command...
560 self.library.load(filename)
561 except RuntimeError,e:
562 self.statusbar.pop(_context)
563 raise
564
565 try:
566 self.statusbar.pop(_context)
567 except TypeError,e:
568 print "For some reason, a type error (context=%s,filename=%s): %s" % (_context,filename,e)
569
570 # Load the current list of modules into self.modules
571 self.moduleview.refresh(self.library)
572
573 self.sim = None;
574 self.maintabs.set_current_page(0);
575
576 # See http://www.daa.com.au/pipermail/pygtk/2005-October/011303.html
577 # for details on how the 'wait cursor' is done.
578 def start_waiting(self, message):
579 self.waitcontext = self.statusbar.get_context_id("waiting")
580 self.statusbar.push(self.waitcontext,message)
581
582 if self.waitwin:
583 self.waitwin.show()
584
585 while gtk.events_pending():
586 gtk.main_iteration()
587
588 def stop_waiting(self):
589 if self.waitwin:
590 self.statusbar.pop(self.waitcontext)
591 self.waitwin.hide()
592
593 def do_sim(self, type_object):
594 self.sim = None;
595 # TODO: clear out old simulation first!
596
597 #print "DO_SIM(%s)" % str(type_object.getName())
598 self.start_waiting("Compiling...")
599
600 try:
601 _v = self.prefs.getBoolPref("Compiler","use_relation_sharing",True)
602 ascpy.getCompiler().setUseRelationSharing(_v)
603
604 _v = self.prefs.getBoolPref("Compiler","use_binary_compilation",True)
605 ascpy.getCompiler().setBinaryCompilation(True)
606
607 self.sim = type_object.getSimulation(str(type_object.getName())+"_sim",False)
608
609 #self.reporter.reportNote("SIMULATION ASSIGNED")
610 except RuntimeError, e:
611 self.stop_waiting()
612 self.reporter.reportError(str(e))
613 return
614
615 self.stop_waiting()
616
617 # get method names and load them into the GUI
618 self.methodstore.clear()
619 _methods = self.sim.getType().getMethods()
620 _activemethod = None;
621 for _m in _methods:
622 _i = self.methodstore.append([_m.getName()])
623 if _m.getName()=="on_load":
624 self.methodsel.set_active_iter(_i)
625
626 self.modelview.setSimulation(self.sim)
627
628 # run the 'on_load' method
629 self.start_waiting("Running default method...")
630 try:
631 #self.reporter.reportNote("SIMULATION CREATED, RUNNING DEFAULT METHOD NOW...")
632 self.sim.runDefaultMethod()
633 except RuntimeError, e:
634 self.stop_waiting()
635 self.reporter.reportError(str(e))
636 return
637 self.stop_waiting()
638
639 self.modelview.refreshtree()
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 try:
657 self.sim.build()
658 except RuntimeError,e:
659 self.reporter.reportError("Couldn't build system: %s",str(e));
660 return
661
662 if not hasattr(self,'solver'):
663 self.reporter.reportError("No solver assigned!")
664 return
665
666 self.start_waiting("Solving with %s..." % self.solver.getName())
667
668 if self.prefs.getBoolPref("SolverReporter","show_popup",True):
669 reporter = PopupSolverReporter(self,self.sim.getNumVars())
670 else:
671 reporter = SimpleSolverReporter(self)
672
673 try:
674 self.sim.solve(self.solver,reporter)
675 except RuntimeError,e:
676 self.reporter.reportError(str(e))
677
678 self.stop_waiting()
679
680 self.modelview.refreshtree()
681
682 def do_integrate(self):
683 if not self.sim:
684 self.reporter.reportError("No model selected yet")
685 return
686
687 try:
688 self.sim.build()
689 except RuntimeError,e:
690 self.reporter.reportError("Couldn't build system: %s",str(e))
691 return
692
693 integwin = IntegratorWindow(self,self.sim)
694 _integratorreporter = integwin.run()
695 if _integratorreporter!=None:
696 _integratorreporter.run()
697 self.sim.processVarStatus()
698 self.modelview.refreshtree()
699
700
701 def do_check(self):
702 try:
703 self.sim.build()
704 except RuntimeError,e:
705 self.reporter.reportError("Couldn't build system: %s",str(e));
706 return
707
708 self.start_waiting("Checking system...")
709
710 try:
711 self.sim.checkInstance()
712 self.reporter.reportWarning("System instance check run, check above for error (if any).")
713 # the above gives output but doesn't throw errors or return a status.
714 # ... this is a problem (at the C level)
715
716 status = self.sim.checkDoF()
717 if status==ascpy.ASCXX_DOF_UNDERSPECIFIED:
718 self.on_show_fixable_variables_activate(None)
719 elif status==ascpy.ASCXX_DOF_OVERSPECIFIED:
720 self.on_show_freeable_variables_activate(None)
721 elif status==ascpy.ASCXX_DOF_STRUCT_SINGULAR:
722 if not self.sim.checkStructuralSingularity():
723 sing = self.sim.getSingularityInfo()
724 title = "Structural singularity"
725 text = title
726 msgs = {
727 "The singularity can be reduced by freeing the following variables" : sing.freeablevars
728 ,"Relations involved in the structural singularity" : sing.rels
729 ,"Variables involved in the structural singularity" : sing.vars
730 }
731 for k,v in msgs.iteritems():
732 text+="\n\n%s:" % k
733 if len(v):
734 _l = [j.getName() for j in v]
735 _l.sort()
736 text+= "\n\t" + "\n\t".join(_l)
737 else:
738 text += "\nnone"
739
740 _dialog = InfoDialog(self,self.window,text,title)
741 _dialog.run()
742 else:
743 self.reporter.reportNote("System DoF check OK")
744
745 except RuntimeError, e:
746 self.stop_waiting()
747 self.reporter.reportError(str(e))
748 return
749
750 self.stop_waiting()
751 self.modelview.refreshtree()
752
753 def do_method(self,method):
754 if not self.sim:
755 self.reporter.reportError("No model selected yet")
756
757 try:
758 self.sim.run(method)
759 except RuntimeError,e:
760 self.reporter.reportError(str(e))
761
762 self.sim.processVarStatus()
763 self.modelview.refreshtree()
764
765 def do_quit(self):
766 loading.print_status("Saving window location")
767 self.reporter.clearPythonErrorCallback()
768
769 _w,_h = self.window.get_size()
770 _t,_l = self.window.get_position()
771 _display = self.window.get_screen().get_display().get_name()
772 self.prefs.setGeometrySizePosition(_display,"browserwin",_w,_h,_t,_l );
773
774 _p = self.browserpaned.get_position()
775 self.prefs.setGeometryValue(_display,"browserpaned",_p);
776
777 loading.print_status("Saving current directory")
778 self.prefs.setStringPref("Directories","fileopenpath",self.fileopenpath)
779
780 self.prefs.setBoolPref("Browser","auto_solve",self.is_auto)
781
782 loading.print_status("Saving preferences")
783 # causes prefs to be saved unless they are still being used elsewher
784 del(self.prefs)
785
786 loading.print_status("Clearing error callback")
787 self.reporter.clearPythonErrorCallback()
788
789 loading.print_status("Closing down GTK")
790 gtk.main_quit()
791
792 loading.print_status("Clearing library")
793 self.library.clear()
794
795 loading.print_status("Quitting")
796
797 return False
798
799 def on_tools_sparsity_click(self,*args):
800
801 self.reporter.reportNote("Preparing incidence matrix...")
802 _im = self.sim.getIncidenceMatrix()
803
804 self.reporter.reportNote("Plotting incidence matrix...")
805
806 _sp = IncidenceMatrixWindow(_im)
807 _sp.run()
808
809 def on_units_click(self,*args):
810 T = self.modelview.get_selected_type()
811 _un = UnitsDialog(self,T)
812 _un.run()
813
814 def on_tools_incidencegraph_click(self,*args):
815 self.reporter.reportNote("Preparing incidence graph...")
816 import tempfile
817 f,fname = tempfile.mkstemp(suffix=".png")
818 f = file(fname,'wb')
819 self.reporter.reportNote("temp file name = %s" % fname)
820 self.reporter.reportNote("file = %s" % f)
821 self.start_waiting("Creating incidence graph...")
822 try:
823 self.sim.write(f,'dot') # create a PNG file in f
824 except Exception,e:
825 self.stop_waiting()
826 self.reporter.reportError("Failed to create incidence graph: %s" % str(e))
827 self.stop_waiting()
828 f.close()
829 _ig = ImageWindow(self, self.window, fname, "Incidence Graph")
830 _ig.run()
831 os.unlink(fname)
832
833 def on_tools_repaint_tree_activate(self,*args):
834 self.reporter.reportNote("Repainting model view...")
835 self.modelview.refreshtree()
836
837 def on_diagnose_blocks_click(self,*args):
838 try:
839 _bl = self.sim.getActiveBlock()
840 except RuntimeError, e:
841 self.reporter.reportError(str(e))
842 return
843 _db = DiagnoseWindow(self,_bl)
844 _db.run();
845
846 def on_add_observer_click(self,*args):
847 self.create_observer()
848
849 def on_keep_observed_click(self,*args):
850 print "KEEPING..."
851 if len(self.observers) <= 0:
852 self.reporter.reportError("No observer defined!")
853 return
854 self.tabs[self.currentobservertab].do_add_row()
855
856 def on_copy_observer_matrix_click(self,*args):
857 if self.clip == None:
858 self.clip = gtk.Clipboard()
859
860 if len(self.observers) <= 0:
861 self.reporter.reportError("No observer defined!")
862 return
863 self.tabs[self.currentobservertab].copy_to_clipboard(self.clip)
864
865 def on_use_relation_sharing_toggle(self,checkmenuitem,*args):
866 _v = checkmenuitem.get_active()
867 self.prefs.setBoolPref("Compiler","use_relation_sharing",_v)
868 self.reporter.reportNote("Relation sharing set to "+str(_v))
869 self.use_binary_compilation.set_sensitive(_v);
870
871 def on_use_binary_compilation_toggle(self,checkmenuitem,*args):
872 _v = checkmenuitem.get_active()
873 self.prefs.setBoolPref("Compiler","use_binary_compilation",_v)
874 self.reporter.reportNote("Binary compilation set to "+str(_v))
875
876 def on_show_solving_popup_toggle(self,checkmenuitem,*args):
877 _v = checkmenuitem.get_active()
878 self.prefs.setBoolPref("SolverReporter","show_popup",_v)
879 print "SET TO",_v
880
881 def on_close_on_converged_toggle(self,checkmenuitem,*args):
882 _v = checkmenuitem.get_active()
883 self.prefs.setBoolPref("SolverReporter","close_on_converged",_v)
884
885 def on_close_on_nonconverged_toggle(self,checkmenuitem,*args):
886 _v = checkmenuitem.get_active()
887 self.prefs.setBoolPref("SolverReporter","close_on_nonconverged",_v)
888
889 def on_show_variables_near_bounds_activate(self,*args):
890 _epsilon = 1e-4;
891 text = "Variables Near Bounds"
892 title=text;
893 text += "\n"
894 _vars = self.sim.getVariablesNearBounds(_epsilon)
895 if len(_vars):
896 for _v in _vars:
897 text += "\n%s"%_v.getName()
898 else:
899 text +="\nnone"
900 _dialog = InfoDialog(self,self.window,text,title)
901 _dialog.run()
902
903 def on_show_vars_far_from_nominals_activate(self,*args):
904 _bignum = self.prefs.getRealPref("Browser","far_from_nominals",10);
905 text = "Variables Far from Nominals"
906 title=text;
907 text += "\n"
908 _vars = self.sim.getVariablesFarFromNominals(_bignum)
909 if len(_vars):
910 for _v in _vars:
911 text += "\n%s"%_v.getName()
912 else:
913 text +="\nnone"
914
915 text+="\n\nAbove calculated using a relative error of %f" % float(_bignum)
916 text+="\nModify this value in .ascend.ini, section '[Browser]', key 'far_from_nominals'."
917 _dialog = InfoDialog(self,self.window,text,title)
918 _dialog.run()
919
920 # ----------------------------------
921 # ERROR PANEL
922
923 def get_error_row_data(self,sev,filename,line,msg):
924 try:
925 _sevicon = {
926 0 : self.iconok
927 ,1 : self.iconinfo
928 ,2 : self.iconwarning
929 ,4 : self.iconerror
930 ,8 : self.iconinfo
931 ,16 : self.iconwarning
932 ,32 : self.iconerror
933 ,64 : self.iconerror
934 }[sev]
935 except KeyError:
936 _sevicon = self.iconerror
937
938 _fontweight = pango.WEIGHT_NORMAL
939 if sev==32 or sev==64:
940 _fontweight = pango.WEIGHT_BOLD
941
942 _fgcolor = "black"
943 if sev==8:
944 _fgcolor = "#888800"
945 elif sev==16:
946 _fgcolor = "#884400"
947 elif sev==32 or sev==64:
948 _fgcolor = "#880000"
949 elif sev==0:
950 _fgcolor = BROWSER_FIXED_COLOR
951
952 if not filename and not line:
953 _fileline = ""
954 else:
955 if(len(filename) > 25):
956 filename = "..."+filename[-22:]
957 _fileline = filename + ":" + str(line)
958
959 _res = (_sevicon,_fileline,msg.rstrip(),_fgcolor,_fontweight)
960 #print _res
961 return _res
962
963 def error_callback(self,sev,filename,line,msg):
964 #print "SEV =",sev
965 #print "FILENAME =",filename
966 #print "LINE =",line
967 #print "MSG =",msg
968 pos = self.errorstore.append(None, self.get_error_row_data(sev, filename,line,msg))
969 path = self.errorstore.get_path(pos)
970 col = self.errorview.get_column(3)
971 self.errorview.scroll_to_cell(path,col)
972 return 0;
973
974 # --------------------------------
975 # BUTTON METHODS
976
977 def open_click(self,*args):
978 #loading.print_status("CURRENT FILEOPENPATH is",self.fileopenpath)
979 dialog = gtk.FileChooserDialog("Open ASCEND model...",
980 self.window,
981 gtk.FILE_CHOOSER_ACTION_OPEN,
982 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)
983 )
984 dialog.set_current_folder(self.fileopenpath)
985 dialog.set_default_response(gtk.RESPONSE_OK)
986 dialog.set_transient_for(self.window)
987 dialog.set_modal(True)
988
989 filter = gtk.FileFilter()
990 filter.set_name("*.a4c, *.a4l")
991 filter.add_pattern("*.[Aa]4[Cc]")
992 filter.add_pattern("*.[Aa]4[Ll]")
993 dialog.add_filter(filter)
994
995 filter = gtk.FileFilter()
996 filter.set_name("All files")
997 filter.add_pattern("*")
998 dialog.add_filter(filter)
999
1000 response = dialog.run()
1001 _filename = dialog.get_filename()
1002 print "\nFILENAME SELECTED:",_filename
1003
1004 _path = dialog.get_current_folder()
1005 if _path:
1006 self.fileopenpath = _path
1007
1008 dialog.hide()
1009
1010 if response == gtk.RESPONSE_OK:
1011 self.reporter.reportNote("File %s selected." % dialog.get_filename() )
1012 self.library.clear()
1013 self.do_open( _filename)
1014
1015 def reload_click(self,*args):
1016 _type = None
1017 if(self.sim):
1018 _type = self.sim.getType().getName().toString();
1019
1020 self.library.clear()
1021
1022 try:
1023 self.do_open(self.filename)
1024 if _type:
1025 _t = self.library.findType(_type)
1026 self.do_sim(_t)
1027 except RuntimeError,e:
1028 self.reporter.reportError(str(e))
1029
1030 def props_activate(self,widget,*args):
1031 return self.modelview.props_activate(self,widget,*args)
1032
1033 def observe_activate(self,widget,*args):
1034 return self.modelview.observe_activate(self,widget,*args)
1035
1036 def solve_click(self,*args):
1037 #self.reporter.reportError("Solving simulation '" + self.sim.getName().toString() +"'...")
1038 self.do_solve()
1039
1040 def console_click(self,*args):
1041 self.lowertabs.set_current_page(1)
1042 self.consoletext.grab_focus()
1043
1044 def integrate_click(self,*args):
1045 self.do_integrate()
1046
1047 def check_click(self,*args):
1048 self.do_check()
1049 #self.reporter.reportError("CHECK clicked")
1050
1051 def preferences_click(self,*args):
1052 if not self.sim:
1053 self.reporter.reportError("No simulation created yet!");
1054 self.sim.setSolver(self.solver)
1055 _params = self.sim.getParameters()
1056 _paramswin = SolverParametersWindow(
1057 browser=self
1058 ,params=_params
1059 ,name=self.solver.getName()
1060 )
1061 if _paramswin.run() == gtk.RESPONSE_OK:
1062 print "PARAMS UPDATED"
1063 self.sim.setParameters(_paramswin.params)
1064 else:
1065 print "PARAMS NOT UPDATED"
1066
1067 def methodrun_click(self,*args):
1068 _sel = self.methodsel.get_active_text()
1069 if _sel:
1070 _method = None
1071 _methods = self.sim.getType().getMethods()
1072 for _m in _methods:
1073 if _m.getName()==_sel:
1074 _method = _m
1075 if not _method:
1076 self.reporter.reportError("Method is not valid")
1077 return
1078 self.do_method(_method)
1079 else:
1080 self.reporter.reportError("No method selected")
1081
1082 def auto_toggle(self,button,*args):
1083 self.is_auto = button.get_active()
1084 if hasattr(self,'automenu'):
1085 self.automenu.set_active(self.is_auto)
1086 else:
1087 raise RuntimeError("no automenu")
1088
1089 #if self.is_auto:
1090 # self.reporter.reportSuccess("Auto mode is now ON")
1091 #else:
1092 # self.reporter.reportSuccess("Auto mode is now OFF")
1093
1094 def on_file_quit_click(self,*args):
1095 self.do_quit()
1096
1097 def on_tools_auto_toggle(self,checkmenuitem,*args):
1098 self.is_auto = checkmenuitem.get_active()
1099 self.autotoggle.set_active(self.is_auto)
1100
1101 def on_help_about_click(self,*args):
1102 _xml = gtk.glade.XML(self.glade_file,"aboutdialog")
1103 _about = _xml.get_widget("aboutdialog")
1104 _about.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
1105 _about.set_transient_for(self.window);
1106 _about.set_version(config.VERSION)
1107 _about.run()
1108 _about.destroy()
1109
1110 def on_help_contents_click(self,*args):
1111 _help = Help(HELP_ROOT)
1112 _help.run()
1113
1114 def on_report_a_bug_click(self,*args):
1115 import urllib
1116 import platform
1117 _plat = str(platform.system())
1118 _version = config.VERSION
1119 _help = Help(
1120 url="http://ascendbugs.cheme.cmu.edu/report/?project_id=ascend&platform=%s&build=%s"
1121 % (_plat,_version)
1122 )
1123 _help.run()
1124
1125 def on_help_check_for_updates_click(self,*args):
1126 v = VersionCheck()
1127 title = "Check for updates"
1128 text = "Your version is %s\n" % config.VERSION
1129 try:
1130 v.check()
1131 if config.VERSION==v.latest:
1132 text += "You are running the latest released version"
1133 else:
1134 text += "Latest version is %s\n" % v.latest
1135 if v.info:
1136 text += "Get more info at %s\n" % v.info
1137 if v.download:
1138 text += "Download from %s\n" % v.download
1139 except Exception, e:
1140 text += "\nUnable to check version\n"
1141 text += str(e)
1142
1143 _dialog = InfoDialog(self,self.window,text,title)
1144 _dialog.run()
1145
1146 def on_show_fixable_variables_activate(self,*args):
1147 try:
1148 v = self.sim.getFixableVariables()
1149 except RuntimeError,e:
1150 self.reporter.reportError(str(e))
1151 text = "Fixable Variables"
1152 title = text
1153 text += "\n"
1154 if len(v):
1155 for var in v:
1156 text += "\n%s"%var
1157 else:
1158 text += "\nnone"
1159 _dialog = InfoDialog(self,self.window,text,title)
1160 _dialog.run()
1161
1162 def on_show_fixed_vars_activate(self,*args):
1163 try:
1164 v = self.sim.getFixedVariables()
1165 text = "Fixed Variables"
1166 title = text
1167 text += "\n"
1168 if len(v):
1169 for var in v:
1170 text += "\n%s"%var
1171 else:
1172 text += "\nnone"
1173 _dialog = InfoDialog(self,self.window,text,title)
1174 _dialog.run()
1175 except RuntimeError,e:
1176 self.reporter.reportError(str(e))
1177
1178 def on_show_freeable_variables_activate(self,*args):
1179 try:
1180 v = self.sim.getFreeableVariables()
1181 except RuntimeError,e:
1182 self.reporter.reportError(str(e))
1183
1184 text = "Freeable Variables"
1185 title = text
1186 text += "\n"
1187 if len(v):
1188 for var in v:
1189 text += "\n%s" % var
1190 else:
1191 text += "\nnone"
1192 _dialog = InfoDialog(self,self.window,text,title)
1193 _dialog.run()
1194
1195 def on_show_external_functions_activate(self,*args):
1196 v = self.library.getExtMethods()
1197 text = "External Functions"
1198 title = text
1199 text +="\nHere is the list of external functions currently present in"
1200 text +=" the Library:"
1201
1202 if len(v):
1203 for ext in v:
1204 text += "\n\n%s (%d inputs, %d outputs):" % \
1205 (ext.getName(), ext.getNumInputs(), ext.getNumOutputs())
1206 text += "\n%s" % ext.getHelp()
1207 else:
1208 text +="\n\nNone"
1209 _dialog = InfoDialog(self,self.window,text,title)
1210 _dialog.run()
1211
1212 def on_maintabs_switch_page(self,notebook,page,pagenum):
1213 #print("Page switched to %d" % pagenum)
1214 if pagenum in self.tabs.keys():
1215 self.currentobservertab = pagenum
1216
1217 def create_observer(self,name=None):
1218 _xml = gtk.glade.XML(self.glade_file,"observervbox");
1219 _label = gtk.Label();
1220 _tab = self.maintabs.append_page(_xml.get_widget("observervbox"),_label);
1221 _obs = ObserverTab(xml=_xml, name=name, browser=self, tab=_tab)
1222 _label.set_text(_obs.name)
1223 self.observers.append(_obs)
1224 self.tabs[_tab] = _obs
1225 self.currentobservertab = _tab
1226 return _obs
1227
1228 def sync_observers(self):
1229 for _o in self.observers:
1230 _o.sync()
1231
1232 def delete_event(self, widget, event):
1233 self.do_quit()
1234 return False
1235
1236 def observe(self,instance):
1237 if len(self.observers) ==0:
1238 self.create_observer()
1239 _observer = self.tabs[self.currentobservertab]
1240 _observer.add_instance(instance)
1241
1242 if __name__ == "__main__":
1243 b = Browser();
1244 b.run()

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