/[ascend]/branches/adrian/pygtk/modelview.py
ViewVC logotype

Contents of /branches/adrian/pygtk/modelview.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3018 - (show annotations) (download) (as text)
Mon Jul 20 12:22:06 2015 UTC (3 years, 4 months ago) by adrian
File MIME type: text/x-python
File size: 27079 byte(s)
Added dialog boxes for when and logrel types
1 from gi.repository import GdkPixbuf
2
3 import ascpy
4 from properties import *
5 from unitsdialog import *
6 from study import *
7
8 BROWSER_FIXED_COLOR = "#008800"
9 BROWSER_FREE_COLOR = "#000088"
10 BROWSER_SETTING_COLOR = "#4444AA"
11
12 BROWSER_INCLUDED_COLOR = "black"
13 BROWSER_UNINCLUDED_COLOR = "#888888"
14
15 ORIGINAL_PATH_INDEX = 7
16
17 class ModelView:
18 def __init__(self,browser,builder):
19 self.browser = browser # the parent object: the entire ASCEND browser
20
21 self.builder = builder
22 self.notes = browser.library.getAnnotationDatabase()
23
24 self.modelview = builder.get_object("browserview")
25
26 self.otank = {}
27
28 # name, type, value, foreground, weight, editable, status-icon
29 columns = [str,str,str,str,int,bool,GdkPixbuf.Pixbuf,str]
30 self.modelstore = Gtk.TreeStore(*columns)
31 titles = ["Name","Type","Value"]
32 self.modelview.set_model(self.modelstore)
33 self.tvcolumns = [ Gtk.TreeViewColumn() for _type in columns[:len(titles)] ]
34
35 self.modelview.connect("row-expanded", self.row_expanded )
36 self.modelview.connect("button-press-event", self.on_treeview_event )
37 self.modelview.connect("key-press-event",self.on_treeview_event )
38
39 # data columns are: name type value colour weight editable
40
41 i = 0
42 for tvcolumn in self.tvcolumns[:len(titles)]:
43 tvcolumn.set_title(titles[i])
44 self.modelview.append_column(tvcolumn)
45
46 if(i==2):
47 # add status icon
48 renderer1 = Gtk.CellRendererPixbuf()
49 tvcolumn.pack_start(renderer1, False)
50 tvcolumn.add_attribute(renderer1, 'pixbuf', 6)
51
52 renderer = Gtk.CellRendererText()
53 tvcolumn.pack_start(renderer, True)
54 tvcolumn.add_attribute(renderer, 'text', i)
55 tvcolumn.add_attribute(renderer, 'foreground', 3)
56 tvcolumn.add_attribute(renderer, 'weight', 4)
57 if(i==2):
58 tvcolumn.add_attribute(renderer, 'editable', 5)
59 renderer.connect('edited',self.cell_edited_callback)
60 i = i + 1
61
62 #--------------------
63 # get all menu icons and set up the context menu for fixing/freeing vars
64 _imagelist = []
65 for i in range(6):
66 _imagelist.append("image%s" % (i+1))
67 self.browser.builder.add_objects_from_file(self.browser.glade_file, _imagelist)
68 self.browser.builder.add_objects_from_file(self.browser.glade_file, ["treecontext"])
69
70 self.treecontext = self.browser.builder.get_object("treecontext")
71 self.fixmenuitem = self.browser.builder.get_object("fix1")
72 self.freemenuitem = self.browser.builder.get_object("free1")
73 self.propsmenuitem = self.browser.builder.get_object("properties1")
74 self.observemenuitem = self.browser.builder.get_object("observe1")
75 self.studymenuitem = self.browser.builder.get_object("study1")
76 self.unitsmenuitem = self.browser.builder.get_object("units1")
77 self.hidevariable = self.browser.builder.get_object("hide_var")
78 self.showallmenuitem = self.browser.builder.get_object("show_variables_all")
79 self.hideallmenuitem = self.browser.builder.get_object("hide_variables_all")
80 self.showmenuitem = self.browser.builder.get_object("show_variables")
81 self.hidemenuitem = self.browser.builder.get_object("hide_variables")
82
83 self.fixmenuitem.connect("activate",self.fix_activate)
84 self.freemenuitem.connect("activate",self.free_activate)
85 self.propsmenuitem.connect("activate",self.props_activate)
86 self.observemenuitem.connect("activate",self.observe_activate)
87 self.studymenuitem.connect("activate", self.study_activate)
88 self.unitsmenuitem.connect("activate",self.units_activate)
89 self.showallmenuitem.connect("activate", self.show_all_variables)
90 self.hideallmenuitem.connect("activate", self.hide_all_variables)
91 self.hidevariable.connect("activate", self.show_variable)
92
93 self.variables = {"showed": [], "hidden": []}
94
95 if not self.treecontext:
96 raise RuntimeError("Couldn't create browsercontext")
97
98 def setSimulation(self,sim):
99 # instance hierarchy
100 self.sim = sim
101 self.modelstore.clear()
102 self.otank = {} # map path -> (name,value)
103 self.browser.disable_menu()
104 try:
105 self.make( self.sim.getName(),self.sim.getModel() )
106 self.browser.enable_on_model_tree_build()
107 except Exception,e:
108 self.browser.reporter.reportError("Error building tree: %s" % e)
109
110 self.fill_variables_menus()
111
112 filtered_model = self.modelstore.filter_new()
113 filtered_model.set_visible_func(self.filter_rows)
114 self.modelview.set_model(filtered_model)
115 self.modelview.expand_row(filtered_model.get_path(filtered_model.get_iter_first()), False)
116
117 self.browser.maintabs.set_current_page(1)
118
119 def fill_variables_menus(self):
120 # show all variables
121 vars = []
122 for instance in self.otank.values():
123 if not str(instance[1].getType()) in vars:
124 vars.append(str(instance[1].getType()))
125 self.variables["showed"] = sorted(vars)
126 for instype in self.variables["showed"]:
127 menuitem = Gtk.MenuItem(instype)
128 menuitem.connect("activate", self.show_variable)
129 self.hidemenuitem.get_submenu().append(menuitem)
130 self.hidemenuitem.show_all()
131 self.hideallmenuitem.set_sensitive(True)
132
133 def clear_variables_menus(self):
134 self.variables = {"showed": [], "hidden": []}
135 allitem = self.hidemenuitem.get_submenu().get_children()[0]
136 for item in list(self.hidemenuitem.get_submenu().get_children()):
137 self.hidemenuitem.get_submenu().remove(item)
138 self.hidemenuitem.get_submenu().append(allitem)
139 allitem.set_sensitive(False)
140 allitem = self.showmenuitem.get_submenu().get_children()[0]
141 for item in list(self.showmenuitem.get_submenu().get_children()):
142 self.showmenuitem.get_submenu().remove(item)
143 self.showmenuitem.get_submenu().append(allitem)
144 allitem.set_sensitive(False)
145
146 def show_all_variables(self, *args):
147 for instype in list(self.variables["hidden"]):
148 self.set_variable_visibility(instype, True)
149
150 model = self.modelview.get_model()
151 model.refilter()
152 self.modelview.expand_row(model.get_path(model.get_iter_first()), False)
153
154 def hide_all_variables(self, *args):
155 for instype in list(self.variables["showed"]):
156 self.set_variable_visibility(instype, False)
157
158 self.modelview.get_model().refilter()
159
160 def show_variable(self, widget):
161 # if context menu
162 if widget.get_label().startswith("Hide "):
163 _model, _pathlist = self.modelview.get_selection().get_selected_rows()
164 for _path in _pathlist:
165 piter = _model.get_iter(_path)
166 originalpath = _model.get_value(piter, ORIGINAL_PATH_INDEX)
167 _, ins = self.otank[originalpath]
168 self.set_variable_visibility(str(ins.getType()), False)
169 # if main menu
170 else:
171 instype = widget.get_label()
172 if widget in self.hidemenuitem.get_submenu().get_children():
173 self.set_variable_visibility(instype, False)
174 else:
175 self.set_variable_visibility(instype, True)
176
177 self.modelview.get_model().refilter()
178
179 def set_variable_visibility(self, instype, show):
180 if show:
181 if instype in self.variables["hidden"]:
182 self.variables["hidden"].remove(instype)
183 self.variables["showed"].append(instype)
184 menuitem = None
185 for item in self.showmenuitem.get_submenu().get_children():
186 if item.get_label() == instype:
187 menuitem = item
188 break
189 if menuitem is not None:
190 self.showmenuitem.get_submenu().remove(menuitem)
191 self.hidemenuitem.get_submenu().insert(menuitem, self.get_menu_position(menuitem, self.hidemenuitem))
192
193 else:
194 if instype in self.variables["showed"]:
195 self.variables["showed"].remove(instype)
196 self.variables["hidden"].append(instype)
197 menuitem = None
198 for item in self.hidemenuitem.get_submenu().get_children():
199 if item.get_label() == instype:
200 menuitem = item
201 break
202 if menuitem is not None:
203 self.hidemenuitem.get_submenu().remove(menuitem)
204 self.showmenuitem.get_submenu().insert(menuitem, self.get_menu_position(menuitem, self.showmenuitem))
205
206 self.hideallmenuitem.set_sensitive(len(self.variables["showed"]) > 0)
207 self.showallmenuitem.set_sensitive(len(self.variables["hidden"]) > 0)
208
209 def get_menu_position(self, menuitem, menu):
210 children = menu.get_submenu().get_children()
211 for i in range(1, len(children)):
212 if children[i].get_label() > menuitem.get_label():
213 return i
214
215 return len(children)
216
217 def filter_rows(self, model, piter, data):
218 path = model.get_path(piter)
219 if str(path) not in self.otank:
220 return False
221
222 name, value = self.otank[path.to_string()]
223 instype = str(value.getType())
224 return instype in self.variables["showed"]
225
226 def clear(self):
227 self.clear_variables_menus()
228 self.modelstore.clear()
229 self.otank = {}
230
231 # --------------------------------------------
232 # INSTANCE TREE
233
234 def get_tree_row_data(self,instance): # for instance browser
235 _value = str(instance.getValue())
236 _type = str(instance.getType())
237 _name = str(instance.getName())
238 _fgcolor = BROWSER_INCLUDED_COLOR
239 _fontweight = Pango.Weight.NORMAL
240 _editable = False
241 _statusicon = None
242 if instance.getType().isRefinedSolverVar():
243 _editable = True
244 _fontweight = Pango.Weight.BOLD
245 if instance.isFixed():
246 _fgcolor = BROWSER_FIXED_COLOR
247 else:
248 _fgcolor = BROWSER_FREE_COLOR
249 _fontweight = Pango.Weight.BOLD
250 _status = instance.getStatus();
251 _statusicon = self.browser.statusicons[_status]
252 elif instance.isRelation():
253 _status = instance.getStatus();
254 _statusicon = self.browser.statusicons[_status]
255 if not instance.isIncluded():
256 _fgcolor = BROWSER_UNINCLUDED_COLOR
257 elif instance.isBool() or instance.isReal() or instance.isInt():
258 # TODO can't edit constants that have already been refined
259 _editable = True
260 _fgcolor = BROWSER_SETTING_COLOR
261 _fontweight = Pango.Weight.BOLD
262 elif instance.isSymbol() and not instance.isConst():
263 _editable = True
264 _fgcolor = BROWSER_SETTING_COLOR
265 _fontweight = Pango.Weight.BOLD
266
267 #if(len(_value) > 80):
268 # _value = _value[:80] + "..."
269
270 return [_name, _type, _value, _fgcolor, _fontweight, _editable, _statusicon, None]
271
272 def make_row(self, piter, value, name=None): # for instance browser
273 assert(value)
274 _piter = self.modelstore.append(piter, self.get_tree_row_data(value))
275 path = self.modelstore.get_path(_piter)
276 self.modelstore.set_value(_piter, ORIGINAL_PATH_INDEX, str(path))
277 if name is not None:
278 self.modelstore.set_value(_piter, 0, str(name))
279 return _piter
280
281 def refreshtree(self):
282 # @TODO FIXME use a better system than colour literals!
283 for _path in self.otank: # { path : (name,value) }
284 _iter = self.modelstore.get_iter(_path)
285 _name, _instance = self.otank[_path]
286 _value = str(_instance.getValue())
287 ##### CELSIUS TEMPERATURE WORKAROUND
288 if _instance.getType().isRefinedReal() and str(_instance.getType().getDimensions()) == 'TMP':
289 units = Preferences().getPreferredUnitsOrigin(str(_instance.getType().getName()))
290 if units == CelsiusUnits.get_celsius_sign():
291 temp = _value.split(" ")[0]
292 _value = CelsiusUnits.convert_kelvin_to_celsius(temp, str(_instance.getType())) + " " + CelsiusUnits.get_celsius_sign()
293 ##### CELSIUS TEMPERATURE WORKAROUND
294 self.modelstore.set_value(_iter, 2, _value)
295 if _instance.getType().isRefinedSolverVar():
296 if _instance.isFixed() and self.modelstore.get_value(_iter,3)==BROWSER_FREE_COLOR:
297 self.modelstore.set_value(_iter,3,BROWSER_FIXED_COLOR)
298 elif not _instance.isFixed() and self.modelstore.get_value(_iter,3)==BROWSER_FIXED_COLOR:
299 self.modelstore.set_value(_iter,3,BROWSER_FREE_COLOR)
300 if self.browser.statusicons[_instance.getStatus()] != None:
301 self.modelstore.set_value(_iter, 6, self.browser.statusicons[_instance.getStatus()])
302 elif _instance.isRelation():
303 if self.browser.statusicons[_instance.getStatus()] != None:
304 self.modelstore.set_value(_iter, 6, self.browser.statusicons[_instance.getStatus()])
305 if _instance.isIncluded():
306 self.modelstore.set_value(_iter,3,BROWSER_INCLUDED_COLOR)
307 else:
308 self.modelstore.set_value(_iter,3,BROWSER_UNINCLUDED_COLOR)
309
310 def get_selected_type(self):
311 return self.get_selected_instance().getType()
312
313 def get_selected_instance(self):
314 model, pathlist = self.modelview.get_selection().get_selected_rows()
315 if len(pathlist) == 0:
316 return None
317
318 piter = self.modelview.get_model().get_iter(pathlist[0])
319 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
320 name, instance = self.otank[originalpath]
321 return instance
322
323 def cell_edited_callback(self, renderer, path, newtext, **kwargs):
324 # get back the Instance object we just edited (having to use this seems like a bug)
325 #path = tuple( map(int,path.split(":")) )
326 piter = self.modelview.get_model().get_iter(path)
327 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
328 if not self.otank.has_key(originalpath):
329 raise RuntimeError("cell_edited_callback: invalid path '%s'" % path)
330
331 _name, _instance = self.otank[originalpath]
332
333 if _instance.isReal():
334 if _instance.getValue() == newtext:
335 return True
336 # only real-valued things can have units
337
338 ##### CELSIUS TEMPERATURE WORKAROUND
339 if str(_instance.getType().getDimensions()) == 'TMP':
340 pref = Preferences()
341 units = pref.getPreferredUnitsOrigin(str(_instance.getType().getName()))
342 if units == CelsiusUnits.get_celsius_sign() and len(newtext.split(" ")) == 1 or newtext.split(" ")[1] == CelsiusUnits.get_celsius_sign():
343 newtext = CelsiusUnits.convert_celsius_to_kelvin(newtext.split(" ")[0], str(_instance.getType()))
344 pref.setPreferredUnits(str(_instance.getType().getName()), CelsiusUnits.get_celsius_sign())
345 ##### CELSIUS TEMPERATURE WORKAROUND
346
347 _e = RealAtomEntry(_instance, newtext)
348 try:
349 _e.checkEntry()
350 _e.setValue()
351 _e.exportPreferredUnits(self.browser.prefs)
352 except InputError, e:
353 self.browser.reporter.reportError(str(e))
354 return True
355
356 else:
357 if _instance.isBool():
358 _lower = newtext.lower();
359 if _lower.startswith("t") or _lower.startswith("y") or _lower.strip()=="1":
360 newtext = 1
361 elif _lower.startswith("f") or _lower.startswith("n") or _lower.strip()=="0":
362 newtext = 0
363 else:
364 self.browser.reporter.reportError("Invalid entry for a boolean variable: '%s'" % newtext)
365 return True
366 _val = bool(newtext);
367 if _val == _instance.getValue():
368 self.browser.reporter.reportNote("Boolean atom '%s' was not altered" % _instance.getName())
369 return True
370 _instance.setBoolValue(_val)
371
372 elif _instance.isInt():
373 _val = int(newtext)
374 if _val == _instance.getValue():
375 self.browser.reporter.reportNote("Integer atom '%s' was not altered" % _instance.getName())
376 return True
377 _instance.setIntValue(_val)
378 elif _instance.isSymbol():
379 _val = str(newtext)
380 if _val == _instance.getValue():
381 self.browser.reporter.reportNote("Symbol atom '%s' was not altered" % _instance.getName())
382 return True
383 _instance.setSymbolValue(ascpy.SymChar(_val))
384
385 else:
386 self.browser.reporter.reportError("Attempt to set a non-real, non-boolean, non-integer value!")
387 return True
388
389 # now that the variable is set, update the GUI and re-solve if desired
390 _iter = self.modelstore.get_iter(path)
391 self.modelstore.set_value(_iter,2, str(_instance.getValue()))
392
393 if _instance.getType().isRefinedSolverVar():
394 self.modelstore.set_value(_iter,3,BROWSER_FIXED_COLOR) # set the row green as fixed
395
396 self.browser.do_solve_if_auto()
397 return True
398
399 ##### EXTERNAL RELATION WORKAROUND
400 def get_external_relation_outputs(self, value):
401 relation = str(value.getRelationAsString(self.browser.sim.getModel()))
402 relation = relation[relation.find('(') + 1:relation.find(')')]
403 relation = relation.replace(',', '').replace(';', '')
404 params = relation.split('\n')
405 result = []
406 for r in params:
407 if "OUTPUT" in r:
408 result.append(r.split("OUTPUT")[0].strip())
409 return result
410 ##### EXTERNAL RELATION WORKAROUND
411
412 def make_children(self, value, piter, depth=5):
413 assert(value)
414 if value.isCompound():
415 children=value.getChildren();
416 ##### EXTERNAL RELATION WORKAROUND
417 index = 0
418 relation_outputs = None
419 ##### EXTERNAL RELATION WORKAROUND
420 for child in children:
421 try:
422 _name = child.getName()
423 ##### EXTERNAL RELATION WORKAROUND
424 if str(value.getType().getName()) == "array" and str(child.getType().getName()) == "relation":
425 if relation_outputs is None:
426 relation_outputs = self.get_external_relation_outputs(child)
427
428 if index < len(relation_outputs):
429 _name = relation_outputs[index]
430 index += 1
431 ##### EXTERNAL RELATION WORKAROUND
432 _piter = self.make_row(piter, child, _name)
433 if child.isCompound() and len(child.getChildren()) > 0 and depth > 0:
434 self.make_children(child, _piter, depth - 1)
435 _path = self.modelstore.get_path(_piter)
436 self.otank[_path.to_string()] = (child.getName(), child)
437 #self.browser.reporter.reportError("2 Added %s at path %s" % (_name,repr(_path)))
438 except Exception,e:
439 self.browser.reporter.reportError("%s: %s" % (_name,e))
440
441
442 def make(self, name=None, value=None, path=None, depth=1):
443 if path is None:
444 # make root node
445 piter = self.make_row(None, value)
446 path = self.modelstore.get_path( piter )
447 self.otank[ path.to_string() ] = (name, value)
448 #self.browser.reporter.reportError("4 Added %s at path %s" % (name, path))
449 else:
450 name, value = self.otank[ path.to_string() ]
451
452 assert(value)
453
454 piter = self.modelstore.get_iter( path )
455 if not self.modelstore.iter_has_child( piter ):
456 #self.browser.reporter.reportNote( "name=%s has CHILDREN..." % name )
457 self.make_children(value,piter)
458
459 if depth:
460 for i in range( self.modelstore.iter_n_children( piter ) ):
461 tmp_path = path.copy()
462 tmp_path.append_index(i)
463 if tmp_path.to_string() not in self.otank.keys():
464 continue
465
466 self.make(path=tmp_path, depth=depth - 1)
467 else:
468 self.modelview.expand_row(self.modelstore.get_path(self.modelstore.get_iter_first()),False) # Edit here only.
469
470 def row_expanded(self, modelview, piter, path):
471 originalpath = Gtk.TreePath.new_from_string(modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX))
472 self.make(path=originalpath)
473
474
475 # ------------------------------
476 # CONTEXT MENU
477
478 def on_treeview_event(self,widget,event):
479 _path = None
480 _contextmenu = False
481 if event.type == Gdk.EventType.KEY_PRESS:
482 _keyval = Gdk.keyval_name(event.keyval)
483 _path, _col = self.modelview.get_cursor()
484 if _keyval == 'Menu':
485 _contextmenu = True
486 _button = 3
487 elif _keyval == 'F2' or _keyval == 'Return':
488 print "F2 pressed"
489 self.modelview.set_cursor(_path, self.tvcolumns[2], 1)
490 return True
491 elif event.type == Gdk.EventType.BUTTON_PRESS:
492 _x = int(event.x)
493 _y = int(event.y)
494 _button = event.button
495 _pthinfo = self.modelview.get_path_at_pos(_x, _y)
496 if _pthinfo is not None:
497 _path, _col, _cellx, _celly = _pthinfo
498 if event.button == 3:
499 _contextmenu = True
500
501 if not _contextmenu:
502 #print "NOT DOING ANYTHING ABOUT %s" % Gdk.keyval_name(event.keyval)
503 return False
504
505 if _path:
506 piter = self.modelview.get_model().get_iter(_path)
507 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
508 _name, _instance = self.otank[originalpath]
509 # set the statusbar
510 nn = self.notes.getNotes(self.sim.getModel().getType(),ascpy.SymChar("inline"),_name)
511 for n in nn:
512 print "%s: (%s) %s" % (n.getId(),str(n.getLanguage()),n.getText())
513
514 self.builder.get_object("free_variable").set_sensitive(False)
515 self.builder.get_object("fix_variable").set_sensitive(False)
516 self.builder.get_object("propsmenuitem").set_sensitive(False)
517 if _instance.isReal():
518 self.builder.get_object("units").set_sensitive(True)
519 if _instance.getType().isRefinedSolverVar():
520 self.builder.get_object("propsmenuitem").set_sensitive(True)
521 if _instance.isFixed():
522 self.builder.get_object("free_variable").set_sensitive(True)
523 else:
524 self.builder.get_object("fix_variable").set_sensitive(True)
525 elif _instance.isRelation():
526 self.builder.get_object("propsmenuitem").set_sensitive(True)
527
528 self.unitsmenuitem.set_sensitive(False)
529 self.fixmenuitem.set_sensitive(False)
530 self.freemenuitem.set_sensitive(False)
531 self.observemenuitem.set_sensitive(False)
532 self.studymenuitem.set_sensitive(False)
533 self.propsmenuitem.set_sensitive(False)
534 self.hidevariable.set_sensitive(False)
535
536 # if selected more than one row
537 model, pathlist = self.modelview.get_selection().get_selected_rows()
538 if len(pathlist) > 1 and _path in pathlist:
539 _fixed = False
540 _free = False
541 _observe = False
542 for p in pathlist:
543 piter = self.modelview.get_model().get_iter(p)
544 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
545 _name, _instance = self.otank[originalpath]
546 if _instance.getType().isRefinedSolverVar():
547 _fixed |= _instance.isFixed()
548 _free |= not _instance.isFixed()
549 _observe = True
550 if _fixed:
551 self.freemenuitem.set_sensitive(True)
552 if _free:
553 self.fixmenuitem.set_sensitive(True)
554 if _observe:
555 self.observemenuitem.set_sensitive(True)
556
557 self.hidevariable.set_sensitive(True)
558 self.hidevariable.set_label("Hide selected types")
559
560 self.modelview.grab_focus()
561 self.treecontext.popup(None, None, None, None, _button, event.time)
562 return True
563
564 if _instance.isReal():
565 print "CAN POP: real atom"
566 self.unitsmenuitem.set_sensitive(True)
567
568 if _instance.getType().isRefinedSolverVar():
569 self.propsmenuitem.set_sensitive(True)
570 self.observemenuitem.set_sensitive(True)
571 if _instance.isFixed():
572 self.freemenuitem.set_sensitive(True)
573 if len(self.browser.observers) > 0:
574 self.studymenuitem.set_sensitive(True)
575 else:
576 self.fixmenuitem.set_sensitive(True)
577 elif _instance.isRelation() or _instance.isLogicalRelation() or _instance.isWhen():
578 self.propsmenuitem.set_sensitive(True)
579 elif _instance.isModel():
580 # MODEL instances have a special context menu:
581 self.modelmenu = self.get_model_context_menu(_instance)
582 self.modelview.grab_focus()
583 self.modelview.set_cursor(_path,_col,0)
584 print "RUNNING POPUP MENU"
585 self.modelmenu.popup(None, None, None, None, _button, event.time)
586 return True
587
588 self.hidevariable.set_label("Hide " + str(_instance.getType()))
589 self.hidevariable.set_sensitive(True)
590
591 self.modelview.grab_focus()
592 self.modelview.set_cursor( _path, _col, 0)
593 self.treecontext.popup( None, None, None,None, _button, event.time)
594 return True
595
596 def get_model_context_menu(self,instance):
597 menu = Gtk.Menu()
598
599 if instance.isPlottable():
600 print "PLOTTABLE"
601 mi = Gtk.ImageMenuItem("P_lot",True);
602 img = Gtk.Image()
603 img.set_from_file(self.browser.options.assets_dir+'/plot.png')
604 mi.set_image(img)
605 mi.show()
606 mi.connect("activate",self.plot_activate)
607 menu.append(mi);
608 sep = Gtk.SeparatorMenuItem(); sep.show()
609 menu.append(sep)
610
611 mi = Gtk.ImageMenuItem("Run method...")
612 mi.set_sensitive(False)
613 img = Gtk.Image()
614 img.set_from_stock(Gtk.STOCK_EXECUTE,Gtk.IconSize.MENU)
615 mi.set_image(img)
616 mi.show()
617 menu.append(mi)
618
619 sep = Gtk.SeparatorMenuItem(); sep.show()
620 menu.append(sep)
621
622 t = instance.getType()
623 ml = t.getMethods()
624 if len(ml):
625 for m in ml:
626 mi = Gtk.MenuItem(m.getName())
627 mi.show()
628 mi.connect("activate",self.run_activate,instance,m)
629 menu.append(mi)
630
631 return menu
632
633 def run_activate(self,widget,instance,method):
634 print "RUNNING %s" % method.getName()
635 try:
636 self.browser.sim.run(method,instance)
637 except Exception,e:
638 self.browser.reporter.reportError(str(e))
639 self.refreshtree()
640
641 def fix_activate(self,widget):
642 _model, _pathlist = self.modelview.get_selection().get_selected_rows()
643 for _path in _pathlist:
644 piter = self.modelview.get_model().get_iter(_path)
645 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
646 _name, _instance = self.otank[originalpath]
647 self.set_fixed(_instance, True)
648 self.browser.do_solve_if_auto()
649 return 1
650
651 def free_activate(self,widget):
652 _model, _pathlist = self.modelview.get_selection().get_selected_rows()
653 for _path in _pathlist:
654 piter = self.modelview.get_model().get_iter(_path)
655 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
656 _name, _instance = self.otank[originalpath]
657 self.set_fixed(_instance, False)
658 self.browser.do_solve_if_auto()
659 return 1
660
661 def plot_activate(self,widget):
662
663 self.browser.reporter.reportNote("plot_activate...");
664 _path,_col = self.modelview.get_cursor()
665 piter = self.modelview.get_model().get_iter(_path)
666 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
667 _instance = self.otank[originalpath][1]
668 if not _instance.isPlottable():
669 self.browser.reporter.reportError("Can't plot instance %s" % _instance.getName().toString())
670 return
671 else:
672 self.browser.reporter.reportNote("Instance %s about to be plotted..." % _instance.getName().toString())
673
674 print("Plotting instance '%s'..." % _instance.getName().toString())
675
676 _plot = _instance.getPlot()
677
678 print "Title: ", _plot.getTitle()
679 _plot.show(True)
680
681 return 1
682
683 def props_activate(self,widget,*args):
684 if not hasattr(self,'sim'):
685 self.browser.reporter.reportError("Can't show properties until a simulation has been created.");
686 return
687 _path,_col = self.modelview.get_cursor()
688 piter = self.modelview.get_model().get_iter(_path)
689 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
690 _instance = self.otank[originalpath][1]
691 if _instance.isRelation() or _instance.isLogicalRelation() or _instance.isWhen():
692 # print "Relation '"+_instance.getName().toString()+"':", \
693 # _instance.getRelationAsString(self.sim.getModel())
694 _dia = RelPropsWin(self.browser, _instance)
695 _dia.run()
696 elif _instance.getType().isRefinedSolverVar():
697 _dia = VarPropsWin(self.browser, _instance)
698 _dia.run()
699 else:
700 self.browser.reporter.reportWarning("Select a variable or relation first...")
701
702 def observe_activate(self,widget,*args):
703 _model, _pathlist = self.modelview.get_selection().get_selected_rows()
704 for _path in _pathlist:
705 piter = self.modelview.get_model().get_iter(_path)
706 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
707 _name, _instance = self.otank[originalpath]
708 if _instance.getType().isRefinedSolverVar():
709 print "OBSERVING",_instance.getName().toString()
710 self.browser.observe(_instance)
711
712 def on_fix_variable_activate(self, widget):
713 self.fix_activate(widget)
714
715 def on_free_variable_activate(self, widget):
716 self.free_activate(widget)
717
718 def set_fixed(self,instance,val):
719 if instance.getType().isRefinedSolverVar():
720 f = instance.isFixed()
721 if (f and not val) or (not f and val):
722 instance.setFixed(val)
723
724
725 def study_activate(self, *args):
726 _path,_col = self.modelview.get_cursor()
727 piter = self.modelview.get_model().get_iter(_path)
728 originalpath = self.modelview.get_model().get_value(piter, ORIGINAL_PATH_INDEX)
729 _instance = self.otank[originalpath][1]
730 self.browser.observe(_instance)
731 _dia = StudyWin(self.browser,_instance)
732 _dia.run()
733
734 def units_activate(self,*args):
735 T = self.get_selected_type()
736 try:
737 _un = UnitsDialog(self.browser,T)
738 _un.run()
739 except:
740 self.browser.reporter.reportError("Unable to display units dialog.")
741

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