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

Contents of /trunk/pygtk/observer.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 849 - (show annotations) (download) (as text)
Mon Sep 18 15:10:48 2006 UTC (16 years, 8 months ago) by johnpye
File MIME type: text/x-python
File size: 11338 byte(s)
Some progress on a rewrite of the Observer funcitonality so that it can be shared with the IntegratorReporter.
1 import pygtk
2 pygtk.require('2.0')
3 import gtk
4 import gtk.glade
5 import pango
6
7 OBSERVER_INITIAL_COLS = 3 # how many cells are at the start of the table?
8 OBSERVER_ICON, OBSERVER_WEIGHT, OBSERVER_EDIT = range(0,OBSERVER_INITIAL_COLS) # column indices for the start of the TreeStore
9 OBSERVER_NULL = 0 # value that gets added to empty cells in a new column
10
11 # This is messy code since it doesn't observe the convention of keeping your model
12 # separate from your view. It's all mixed up together. Yuck. Part of the
13 # difficulty with that was the fact that TreeStores don't support the adding of
14 # columns.
15
16 # Update: there is a technique for doing this, in fact:
17 # http://www.daa.com.au/pipermail/pygtk/2006-February/011777.html
18
19 OBSERVER_NUM=0
20
21 class ObserverColumn:
22 """
23 A class to identify the instance that relates to a specify column
24 and the units of measurement and column title, etc.
25 """
26 def __init__(self,instance,index,name=None,units=None,browser=None):
27 self.instance = instance
28 self.name = name
29 self.index = index
30
31 if name==None:
32 if browser == None:
33 name = "UNNAMED"
34 else:
35 name = browser.sim.getInstanceName(instance)
36
37 if units == None:
38 units = instance.getType().getPreferredUnits()
39 if units == None:
40 units = instance.getType().getDimensions().getDefaultUnits()
41
42 uname = str(units.getName())
43 if uname.find("/")!=-1:
44 uname = "["+uname+"]"
45
46 if uname == "":
47 _title = "%s" % (name)
48 else:
49 _title = "%s / %s" % (name, uname)
50
51 self.title = _title
52 self.units = units
53 self.uname = uname
54 self.name = name
55
56 def __repr__(self):
57 return "ObserverColumn(name="+self.name+")"
58
59 def cellvalue(self, column, cell, model, iter):
60 print "RENDERING COLUMN",self.index
61 _rowobject = model.get_value(iter,0)
62
63 try:
64 if _rowobject.active:
65 _rawval = self.instance.getRealValue()
66 else:
67 _rawval = _rowobject.values[self.index]
68 _dataval = _rawval / self.units.getConversion()
69 except KeyError:
70 _dataval = "N/A"
71
72 cell.set_property('text', _dataval)
73
74 class ObserverRow:
75 """
76 Just a container for a vector of values, but with columns that
77 should correspond to those in the Observer object's vector of
78 ObserverColumn objects.
79 """
80 def __init__(self,values=None,active=False):
81 if values==None:
82 values={}
83
84 self.values = values
85 self.active = active
86
87 def make_static(self,table):
88 self.active = False
89 print "TABLE COLS:",table.cols
90 print "ROW VALUES:",self.values
91 for index,col in table.cols.iteritems():
92 print "INDEX: ",index,"; COL: ",col
93 self.values[index] = col.instance.getRealValue()
94 print "Made static, values:",self.values
95
96 class ObserverTab:
97
98 def __init__(self,xml,browser,tab,name=None,alive=True):
99 global OBSERVER_NUM
100 self.colindex = 0
101 if name==None:
102 OBSERVER_NUM=OBSERVER_NUM+1
103 name = "Observer %d" % OBSERVER_NUM
104 self.name = name
105 self.browser=browser
106 xml.signal_autoconnect(self)
107 self.view = xml.get_widget('observerview')
108 self.tab = tab
109 self.alive=alive
110 if self.alive:
111 self.browser.reporter.reportNote("New observer is 'alive'")
112
113 self.keptimg = gtk.Image()
114 self.activeimg = gtk.Image()
115 self.activeimg.set_from_file("glade/active.png")
116 # create PixBuf objects from these?
117 self.rows = []
118 _store = gtk.TreeStore(object,int)
119 self.cols = {}
120
121 # create the 'active' pixbuf column
122 _renderer = gtk.CellRendererPixbuf()
123 _col = gtk.TreeViewColumn()
124 _col.set_title("")
125 _col.pack_start(_renderer,False)
126 _col.set_cell_data_func(_renderer, self.activepixbufvalue)
127 self.view.append_column(_col);
128
129 # initially there will not be any other columns
130
131 if self.alive:
132 # for a 'live' Observer, create the 'active' bottom row
133 self.browser.reporter.reportNote("Adding empty row to store")
134 self.activeiter = _store.append(None, [ObserverRow(active=True),0] )
135
136 self.view.set_model(_store)
137 self.browser.reporter.reportNote("Created observer '%s'" % self.name)
138
139 def activepixbufvalue(self,column,cell,model,iter):
140 _rowobject = model.get_value(iter,0)
141 if _rowobject.active:
142 cell.set_property('pixbuf',self.activeimg.get_pixbuf())
143 else:
144 cell.set_property('pixbuf',self.keptimg.get_pixbuf())
145
146 def on_add_clicked(self,*args):
147 self.do_add_row()
148
149 def on_clear_clicked(self,*args):
150 self.browser.reporter.reportError("CLEAR not implemented")
151
152 def do_add_row(self):
153 if self.alive:
154 _rowobject = ObserverRow(active=True)
155 _store = self.view.get_model()
156 _oldrow = _store.get_value(self.activeiter,0)
157 _oldrow.make_static(self)
158 self.activeiter = _store.append(None,[ObserverRow([],True),0])
159 else:
160 self.browser.reporter.reportError("Can't add row: incorrect observer type")
161
162 def on_view_cell_edited(self, renderer, path, newtext, datacolumn):
163 self.browser.reporter.reportError("EDIT not implemented")
164
165 def sync(self):
166 _store = self.view.get_model()
167 _activerow = _store.get_value(self.activeiter,0)
168 _store.set(self.activeiter,1,0 )
169 self.browser.reporter.reportNote("SYNC performed")
170
171 def add_instance(self,instance):
172 _col = ObserverColumn(instance,self.colindex,browser=self.browser)
173 self.cols[self.colindex] = _col
174 self.colindex = self.colindex + 1
175
176 # create a new column
177 _renderer = gtk.CellRendererText()
178 _tvcol = gtk.TreeViewColumn()
179 _tvcol.set_title(_col.title)
180 _tvcol.pack_start(_renderer,False)
181 _tvcol.set_cell_data_func(_renderer, _col.cellvalue)
182 self.view.append_column(_tvcol);
183
184 self.browser.reporter.reportError("cols = "+str(self.cols))
185
186 #-------------------------------------------------------------------------------
187 # OLD STUFF
188
189 class ObserverTab1:
190 """
191 An 'Observer' tab in the Browser interface. Multiple tabs should be
192 possible.
193 """
194 def __init__(self,xml,name,browser,tab):
195 xml.signal_autoconnect(self);
196
197 self.view = xml.get_widget('observerview')
198 self.tab = tab
199
200 self.activeimg = None
201 self.keptimg = None
202
203 # no instances yet in the observer:
204 self.columninstances = []
205
206 self.columns = [gtk.gdk.Pixbuf,int,bool]
207
208 # units for each data column
209 self.units = []
210 self.titles = []
211
212 _store = gtk.TreeStore(*self.columns)
213 self.rows = []
214
215 # add an empty first row
216 self.rows.append([])
217
218 # work towards having multiple observers for multiple simulations
219 self.name = nameself.view.set_model(_store)
220 self.browser = browser
221
222 # create the 'active' pixbuf columns
223 _renderer = gtk.CellRendererPixbuf()
224 _col = gtk.TreeViewColumn()
225 _col.set_title("")
226 _col.pack_start(_renderer,False)
227 _col.add_attribute(_renderer, 'pixbuf', OBSERVER_ICON)
228 self.view.append_column(_col);
229
230 # create the first row
231 print "Adding row",self.rows[0],"to store"
232 _store.append(None, self.make_row(True, self.rows[0]) )
233
234 self.activerow = 0
235
236 self.view.set_model(_store)
237
238 self.browser.reporter.reportNote("Created observer '%s'" % self.name)
239
240 def on_add_clicked(self,*args):
241 self.do_add_row()
242
243 def do_add_row(self):
244 _rownum = len(self.rows)
245
246 # add a copy of the last row
247 self.rows.append(self.rows[_rownum-1])
248 self.activerow = _rownum
249
250 _m = self.view.get_model()
251 _m.set(self.activeiter,OBSERVER_ICON,self.keptimg,OBSERVER_WEIGHT,pango.WEIGHT_NORMAL,OBSERVER_EDIT,False)
252 self.activeiter = _m.append(None,self.make_row(True,self.rows[_rownum]))
253 self.browser.reporter.reportNote("Kept current values");
254
255 # if the observer is the active tab, move the cursor to the new row.
256 if self.browser.maintabs.get_current_page() == self.tab:
257 self.view.set_cursor(_m.get_path(self.activeiter))
258
259 def on_clear_clicked(self,*args):
260 self.rows = []
261 _r = [_i.getRealValue() for _i in self.columninstances]
262 self.rows.append(_r)
263 self.view.get_model().clear();
264 self.view.get_model().append(None,self.make_row(True,_r))
265 self.browser.reporter.reportNote("Observer '%s' cleared" % self.name)
266
267 def on_view_cell_edited(self, renderer, path, newtext, datacolumn):
268 # we can assume it's always the self.activeiter that is edited...
269 if self.columninstances[datacolumn].isFixed():
270 self.columninstances[datacolumn].setRealValue( float(newtext) * self.units[datacolumn].getConversion() )
271 else:
272 self.browser.reporter.reportError("Can't set a FIXED variable from the Observer")
273 return
274 self.browser.do_solve_if_auto()
275
276 def sync(self):
277 #new row data
278 _r = [self.columninstances[_i].getRealValue() / self.units[_i].getConversion() for _i in range(0,len(self.columninstances)) ]
279
280 _r1 = self.make_row(True,_r)
281
282 # stick the row data into the TreeStore
283 _m = self.view.get_model()
284 _i = 0
285 for _c in _r1:
286 _m.set(self.activeiter, _i, _c)
287 _i = _i + 1
288
289 # keep the data in self.rows as well
290 self.rows[self.activerow] = _r;
291
292 def copy_to_clipboard(self,clip):
293 _s = []
294 _s.append('\t'.join(self.titles))
295 for _r in self.rows:
296 _s.append( '\t'.join([`_c` for _c in _r]) )
297
298 clip.set_text('\n'.join(_s),-1)
299
300 self.browser.reporter.reportNote("Observer '%s' data copied to clipboard" % self.name)
301
302 def make_row(self,isactive,row):
303 # add the initial OBSERVER_INITIAL_COLS fields:
304 if isactive:
305 _r = [self.activeimg, pango.WEIGHT_BOLD, True]
306 else:
307 _r = [self.keptimg, pango.WEIGHT_NORMAL, False]
308
309 for _c in row:
310 _r.append(_c)
311
312 return _r
313
314 def add_instance(self, inst):
315 # TODO big changes here....
316 if not inst.getType().isRefinedSolverVar():
317 self.browser.reporter.reportError("Instance is not a refined solver variable: can't 'observe'.");
318 return
319
320 _colnum = len(self.columns)
321 _colname = self.browser.sim.getInstanceName(inst)
322 _rownum = len(self.rows)-1
323
324 # store the instances in self.columninstances for sync purposes
325 self.columninstances.append(inst)
326
327 # create new TreeStore, copy of old, plus one columm
328 self.columns.append(float)
329 _units = inst.getType().getPreferredUnits()
330 if _units == None:
331 _units = inst.getType().getDimensions().getDefaultUnits()
332
333 _uname = str(_units.getName())
334 if _uname.find("/")!=-1:
335 _uname = "["+_uname+"]"
336
337 if _uname == "":
338 _title = "%s" % (_colname)
339 else:
340 _title = "%s / %s" % (_colname, _uname)
341
342 self.titles.append(_title);
343 self.units.append(_units) # we keep a track of the preferred units for the column at the time of the column creation
344
345 _store = gtk.TreeStore(*(self.columns))
346
347 _iter = None
348 _i = 0
349 _active = False
350 for _r in self.rows:
351 _r.append(OBSERVER_NULL)
352 if _i == _rownum:
353 _active = True
354 _iter = _store.append(None, self.make_row(_active,_r) )
355 _i = _i + 1
356
357 self.activeiter = _iter
358
359 # add newest data point in bottom-right
360 _datacol = _colnum - OBSERVER_INITIAL_COLS
361 _dataval = inst.getRealValue() / self.units[_datacol].getConversion() # convert value to units specified when col created
362 self.rows[_rownum][_datacol] = _dataval
363 _store.set_value(self.activeiter, _colnum, _dataval)
364
365 # re-assign store to TreeView
366 self.view.set_model(_store)
367
368 _renderer = gtk.CellRendererText()
369 _renderer.connect('edited',self.on_view_cell_edited, _datacol)
370 _col = gtk.TreeViewColumn(_title, _renderer)
371 _col.add_attribute(_renderer, 'text', _colnum)
372 _col.add_attribute(_renderer, 'weight', OBSERVER_WEIGHT)
373 _col.add_attribute(_renderer, 'editable', OBSERVER_EDIT)
374 _col.set_alignment(0.0)
375 _col.set_reorderable(True)
376 _col.set_sort_column_id(_colnum)
377
378 self.view.append_column(_col);
379
380 self.browser.reporter.reportNote("Added variable '%s' to observer '%s'" % (_colname,self.name))
381
382

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