1 |
#!/usr/bin/env python |
2 |
|
3 |
import os |
4 |
|
5 |
from gi.repository import Gtk, Gdk, GObject, GdkPixbuf |
6 |
|
7 |
import blockinstance |
8 |
import modeltree |
9 |
from unitsdialog import UnitsDialog |
10 |
from varentry_canvas import * |
11 |
|
12 |
SAVED_TAB = 0 |
13 |
|
14 |
#Not a good place to do this, but makes implementation very easy. |
15 |
#TODO: Set up a central mechanism to handle icons, images, colors. |
16 |
_iconfixed = Gtk.Image() |
17 |
_iconfree = Gtk.Image() |
18 |
_iconfixed.set_from_file(os.path.join('..','glade','locked.png')) |
19 |
_iconfree.set_from_file(os.path.join('..','glade','unlocked.png')) |
20 |
_iconfixed = _iconfixed.get_pixbuf() |
21 |
_iconfree = _iconfree.get_pixbuf() |
22 |
_colorfixed = '#33CC00' |
23 |
_colorfree = '#000000' |
24 |
_weightfixed = 700 |
25 |
_weightfree = 400 |
26 |
|
27 |
class BlockProperties(object): |
28 |
''' |
29 |
Pop up window for viewing and editing ASCEND block properties. |
30 |
Hint: The Parameter data is stored in the ListStore i.e. M of MVC of TreeView |
31 |
''' |
32 |
def __init__(self, parent, item, tab= None): |
33 |
#Get the XML |
34 |
glade_file_path = os.path.join('..','glade','bp.glade') |
35 |
builder = Gtk.Builder() |
36 |
builder.add_from_file(glade_file_path) |
37 |
self.dialog = builder.get_object('dialog') |
38 |
self.dialog.set_transient_for(parent) |
39 |
self.parent = parent |
40 |
self.units = self.parent.ascwrap.library.getUnits() |
41 |
|
42 |
self.block = item.blockinstance |
43 |
|
44 |
self.dialog.set_title('Properties of '+ str(self.block.name)) |
45 |
|
46 |
##General Tab## |
47 |
#Set the 'Name:' |
48 |
self.block_name = builder.get_object('block_name') |
49 |
self.block_name.set_text(self.block.name) |
50 |
self.block_name.set_editable(True) |
51 |
|
52 |
#Set the 'Type:' |
53 |
self.type_name = builder.get_object('type_name') |
54 |
text = self.block.blocktype.type |
55 |
self.type_name.set_text(str(text)) |
56 |
self.type_name.set_editable(False) |
57 |
#Set the 'Ports:' |
58 |
self.type_name = builder.get_object('port_name') |
59 |
ports = self.block.ports |
60 |
sorted_ports = [[],[],[]] |
61 |
|
62 |
#Sort the ports |
63 |
for i,j in ports.iteritems(): |
64 |
if j.type == blockinstance.PORT_IN: |
65 |
sorted_ports[0].append(j.name) |
66 |
elif j.type == blockinstance.PORT_OUT: |
67 |
sorted_ports[1].append(j.name) |
68 |
elif j.type == blockinstance.PORT_INOUT: |
69 |
sorted_ports[2].append(j.name) |
70 |
|
71 |
self.general_entry = [builder.get_object('port_name_input'), builder.get_object('port_name_output'), builder.get_object('port_name_inputoutput')] |
72 |
|
73 |
#Display the ports, set them not editable |
74 |
for i in range(len(self.general_entry)): |
75 |
self.general_entry[i].set_editable(False) |
76 |
for port in sorted_ports[i]: |
77 |
self.general_entry[i].set_text(str(sorted_ports[i])) |
78 |
|
79 |
#Stream |
80 |
#self.stream = xml.get_widget('comboboxentry1') |
81 |
#self.stream_store = Gtk.ListStore(GObject.TYPE_STRING) |
82 |
|
83 |
''' |
84 |
for stream in self.parent.ascwrap.streams: |
85 |
try: |
86 |
self.block.blocktype.type.findMember(stream[0]) |
87 |
for sm_type in stream[1]: |
88 |
self.stream_store.append([str(sm_type)]) |
89 |
except RuntimeError: |
90 |
print "DEBUG: Stream not found" |
91 |
|
92 |
self.stream.set_model(self.stream_store) |
93 |
self.stream.set_entry_text_column(0) |
94 |
iter = self.stream_store.get_iter_first() |
95 |
|
96 |
|
97 |
#FIXME Does not properly handle all cases, i.e. if there are multiple |
98 |
#stream in one block |
99 |
for stream in self.parent.ascwrap.streams: |
100 |
if self.block.stream in stream[1]: |
101 |
while True: |
102 |
if self.block.stream == self.stream_store.get_value(iter,0): |
103 |
break; |
104 |
else: |
105 |
iter = self.stream_store.iter_next(iter) |
106 |
self.stream.set_active_iter(iter) |
107 |
|
108 |
self.stream.connect('changed',self.stream_changed) |
109 |
''' |
110 |
##End of General Tab## |
111 |
|
112 |
##Parameters Tab## |
113 |
#Hint: This uses the Gtk.TreeView and Gtk.ListStore |
114 |
|
115 |
self.param_list_store = paramListStore(self.block.params) |
116 |
self.param_tree_model = self.param_list_store.get_model() |
117 |
self.param_tree_view = displayModel(self.parent) |
118 |
self.view_param = self.param_tree_view.draw_view(self.param_tree_model,builder,self.units) |
119 |
self.view_param.columns_autosize() |
120 |
self.param_tree_view.view.connect("button-press-event", self.on_treeview_event ) |
121 |
self.param_tree_view.view.connect("key-press-event",self.on_treeview_event ) |
122 |
##End of Parameters Tab## |
123 |
|
124 |
###Custom Method Tab## |
125 |
#custom_alignment = xml.get_widget('custom_alignment') |
126 |
#self.sourceviewView = gtksourceview.View() |
127 |
#self.sourceviewView.set_show_line_numbers(True) |
128 |
#self.sourceviewLangman = gtksourceview.language_manager_get_default() |
129 |
#op = self.sourceviewLangman.get_search_path() |
130 |
|
131 |
#if os.path.join('..','..','tools','gtksourceview-2.0') not in op: |
132 |
#op.append(os.path.join('..','..','tools','gtksourceview-2.0')) |
133 |
#self.sourceviewLangman.set_search_path(op) |
134 |
|
135 |
#self.sourceviewLang = self.sourceviewLangman.get_language('ascend') |
136 |
#self.sourceviewBuff = gtksourceview.Buffer() |
137 |
#self.sourceviewBuff.set_language(self.sourceviewLang) |
138 |
#self.sourceviewBuff.set_highlight_syntax(True) |
139 |
#self.sourceviewBuff.set_text(self.block.usercode) |
140 |
#self.sourceviewView.set_buffer(self.sourceviewBuff) |
141 |
#custom_alignment.add(self.sourceviewView) |
142 |
#self.sourceviewView.show() |
143 |
###End of Custom Method Tab## |
144 |
|
145 |
##Instance Tab## |
146 |
try: |
147 |
self.instance_box = builder.get_object('instance') |
148 |
self.instance_model = modeltree.TreeView(self.block.instance) |
149 |
self.instance_box.add(self.instance_model.treeview) |
150 |
self.instance_model.treeview.show() |
151 |
except Exception as e: |
152 |
self.instance_box = builder.get_object('instance') |
153 |
self.instance_label = Gtk.Label() |
154 |
self.instance_box.add_with_viewport(self.instance_label) |
155 |
self.instance_label.set_text('Instance not Built, Solve the Canvas Model first!') |
156 |
self.instance_label.show() |
157 |
##End of Instance Tab## |
158 |
|
159 |
self.notebook = builder.get_object('notebook1') |
160 |
|
161 |
global SAVED_TAB |
162 |
if tab is not None: |
163 |
self.notebook.set_current_page(tab) |
164 |
else: |
165 |
self.notebook.set_current_page(SAVED_TAB) |
166 |
|
167 |
##Attach callback to OK## |
168 |
OK_button = builder.get_object('ok') |
169 |
OK_button.connect('clicked',self.save_changes,self.parent,self.block) |
170 |
OK_button.grab_default() |
171 |
|
172 |
##Context Menu## |
173 |
self.treecontext = Gtk.Menu(); |
174 |
self.fixmenuitem = Gtk.ImageMenuItem("_Fix/ _Free"); |
175 |
self.unitsmenuitem = Gtk.ImageMenuItem("Select _Units"); |
176 |
self.fixmenuitem.show(); self.fixmenuitem.set_sensitive(False) |
177 |
self.unitsmenuitem.show(); self.unitsmenuitem.set_sensitive(False) |
178 |
|
179 |
self.treecontext.append(self.fixmenuitem) |
180 |
_sep = Gtk.SeparatorMenuItem(); _sep.show() |
181 |
self.treecontext.append(_sep); |
182 |
self.treecontext.append(self.unitsmenuitem) |
183 |
self.fixmenuitem.connect("activate",self.fixfree_toggle) |
184 |
self.unitsmenuitem.connect("activate",self.units_activate) |
185 |
|
186 |
if not self.treecontext: |
187 |
raise RuntimeError("Couldn't create browsercontext") |
188 |
##End of Context Menu## |
189 |
|
190 |
def save_changes(self,button,parent,block): |
191 |
block.name = self.block_name.get_text() |
192 |
parent.view.canvas.canvasmodelstate = 'Modified' |
193 |
parent.status.push(0,"Modified Block Properties") |
194 |
parent.view.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#FFF')) |
195 |
|
196 |
def on_treeview_event(self,widget,event): |
197 |
|
198 |
self.unitsmenuitem.set_sensitive(False) |
199 |
self.fixmenuitem.set_sensitive(False) |
200 |
_contextmenu = False |
201 |
|
202 |
if event.type==Gdk.EventType.BUTTON_PRESS: |
203 |
_x = int(event.x) |
204 |
_y = int(event.y) |
205 |
_button = event.button |
206 |
_pthinfo = self.param_tree_view.view.get_path_at_pos(_x, _y) |
207 |
if _pthinfo is not None: |
208 |
_path, _col, _cellx, _celly = _pthinfo |
209 |
if event.button == 3: |
210 |
_contextmenu = True |
211 |
self.param_tree_view.view.get_selection().select_path(_path) |
212 |
self.unitsmenuitem.set_sensitive(True) |
213 |
self.fixmenuitem.set_sensitive(True) |
214 |
|
215 |
if _contextmenu: |
216 |
self.treecontext.popup( None, None, None, _button, event.time) |
217 |
return 1 |
218 |
|
219 |
def units_activate(self,widget): |
220 |
model,iter = self.param_tree_view.view.get_selection().get_selected() |
221 |
param = model.get_value(iter,3) |
222 |
_udia = UnitsDialog(self.parent,self.param_tree_view,param.type) |
223 |
_udia.run() |
224 |
|
225 |
def fixfree_toggle(self,widget): |
226 |
model,iter = self.param_tree_view.view.get_selection().get_selected() |
227 |
path = self.param_tree_view.model.get_path(iter) |
228 |
self.param_tree_view.toggle_callback(path=path,model=model) |
229 |
''' |
230 |
def stream_changed(self,widget): |
231 |
stream = widget.get_active_text() |
232 |
self.parent.view.canvas.set_stream(stream) |
233 |
''' |
234 |
def run(self): |
235 |
global SAVED_TAB |
236 |
self.dialog.run() |
237 |
SAVED_TAB = self.notebook.get_current_page() |
238 |
self.dialog.hide() |
239 |
|
240 |
class displayModel(object): |
241 |
''' |
242 |
Draws the Gtk.TreeView, used for the setting of parameters |
243 |
''' |
244 |
def __init__(self,parent): |
245 |
self.parent = parent |
246 |
|
247 |
def draw_view(self,model,builder,units): |
248 |
self.view = builder.get_object('param_tree') |
249 |
self.view.set_model(model) |
250 |
self.view.set_tooltip_column(6) |
251 |
self.model = model |
252 |
#Set the row renderers |
253 |
self.name_render = Gtk.CellRendererText() |
254 |
self.name_render.set_property('foreground-set',True) |
255 |
self.name_render.set_property('weight-set',True) |
256 |
|
257 |
#self.param_render = Gtk.CellRendererText() |
258 |
#self.param_render.set_property('editable',True) |
259 |
#self.param_render.connect('edited', self.set_param_callback,model) |
260 |
#self.param_render.set_property('foreground-set',True) |
261 |
#self.param_render.set_property('weight-set',True) |
262 |
|
263 |
self.icon_render = Gtk.CellRendererPixbuf() |
264 |
|
265 |
self.toggle_render = Gtk.CellRendererToggle() |
266 |
self.toggle_render.connect('toggled',self.toggle_callback,model) |
267 |
self.toggle_render.set_property('indicator-size',0) |
268 |
|
269 |
self.units_render = Gtk.CellRendererText() |
270 |
self.units_render.set_property('editable',True) |
271 |
#self.units_render.set_property('model',self.umodel) |
272 |
#self.units_render.set_property('text-column',0) |
273 |
self.units_render.set_property('foreground-set',True) |
274 |
self.units_render.set_property('weight-set',True) |
275 |
#self.units_render.set_property('has-entry',False) |
276 |
self.units=units |
277 |
self._units = [] |
278 |
#self.units_render.connect('editing-started',self.populate_units,model,self.units) |
279 |
self.units_render.connect('edited',self.set_units_callback,model) |
280 |
|
281 |
self.description_render = Gtk.CellRendererText() |
282 |
self.description_render.set_property('foreground-set',True) |
283 |
self.description_render.set_property('weight-set',True) |
284 |
|
285 |
#Set the column views |
286 |
self.name_column = Gtk.TreeViewColumn('Parameter',self.name_render,text=0,foreground =4, weight=5) |
287 |
#self.name_column.pack_start(self.toggle_render_name,False) |
288 |
#self.name_column.set_attributes(self.param_render,text=1) |
289 |
|
290 |
self.description_column = Gtk.TreeViewColumn('Description',self.description_render,text=6,foreground =4, weight=5) |
291 |
|
292 |
#self.param_column = Gtk.TreeViewColumn('Value') |
293 |
#self.param_column.set_expand(False) |
294 |
#self.param_column.pack_start(self.param_render,False) |
295 |
#self.param_column.set_attributes(self.param_render,text=1, foreground =5, weight=6) |
296 |
#self.param_column.set_expand(False) |
297 |
|
298 |
self.toggle_column = Gtk.TreeViewColumn('Status') |
299 |
self.toggle_column.pack_start(self.icon_render,False) |
300 |
self.toggle_column.pack_start(self.toggle_render,False) |
301 |
self.toggle_column.add_attribute(self.icon_render, "pixbuf", 2) |
302 |
|
303 |
self.units_column = Gtk.TreeViewColumn('Value',self.units_render,text=1, foreground =4, weight=5) |
304 |
|
305 |
self.view.append_column(self.name_column) |
306 |
self.view.append_column(self.toggle_column) |
307 |
#self.view.append_column(self.param_column) |
308 |
self.view.append_column(self.units_column) |
309 |
self.view.append_column(self.description_column) |
310 |
|
311 |
return self.view |
312 |
|
313 |
def toggle_callback(self,cellrendertoggle=None,path=None,model=None,fix=False): |
314 |
iter = model.get_iter(path) |
315 |
param = model.get_value(iter,3) |
316 |
|
317 |
if fix == True: |
318 |
param.fix = True |
319 |
if not param.value: |
320 |
param.value = 0 |
321 |
model.set_value(iter,1,param.getValue()) |
322 |
model.set_value(iter,2,_iconfixed) |
323 |
model.set_value(iter,4,_colorfixed) |
324 |
model.set_value(iter,5,_weightfixed) |
325 |
return |
326 |
|
327 |
if param.fix == 0: |
328 |
param.fix = True |
329 |
if not param.value: |
330 |
param.value = None |
331 |
model.set_value(iter,1,param.getValue()) |
332 |
model.set_value(iter,2,_iconfixed) |
333 |
model.set_value(iter,4,_colorfixed) |
334 |
model.set_value(iter,5,_weightfixed) |
335 |
else: |
336 |
param.fix = False |
337 |
model.set_value(iter,2,_iconfree) |
338 |
model.set_value(iter,4,_colorfree) |
339 |
model.set_value(iter,5,_weightfree) |
340 |
|
341 |
#def set_param_callback(self,cellrendertext,path,new_text,model): |
342 |
#iter = model.get_iter(path) |
343 |
#param = model.get_value(iter,4) |
344 |
#param.value = new_text |
345 |
#model.set_value(iter,1,new_text) |
346 |
#param.fix = True |
347 |
#model.set_value(iter,3,_iconfixed) |
348 |
#if len(new_text) == 0: |
349 |
#model.set_value(iter,3,_iconfree) |
350 |
|
351 |
def set_units_callback(self,combo,path,new_text,model): |
352 |
iter = model.get_iter(path) |
353 |
param = model.get_value(iter,3) |
354 |
valid = False |
355 |
|
356 |
if new_text == '': |
357 |
param.units = str(param.type.getDimensions().getDefaultUnits().getName()) |
358 |
param.value = None |
359 |
model.set_value(iter,1,new_text) |
360 |
self.toggle_callback(path=path,model=model,fix=False) |
361 |
return |
362 |
|
363 |
_entry = RealAtomEntry(param,new_text) |
364 |
|
365 |
try: |
366 |
_entry.checkEntry() |
367 |
_entry.setValue() |
368 |
_entry.exportPreferredUnits(self.parent.prefs) |
369 |
if param.type.getPreferredUnits(): |
370 |
new_text = _entry.getValue() +' ' + _entry.getUnits() |
371 |
param.units = str(_entry.getUnits()) |
372 |
else: |
373 |
new_text = str(_entry.getValue()) +' ' + str(param.type.getDimensions().getDefaultUnits().getName()) |
374 |
param.units = str(param.type.getDimensions().getDefaultUnits().getName()) |
375 |
|
376 |
self.toggle_callback(path=path,model=model,fix=True) |
377 |
combo.set_property('text',new_text) |
378 |
model.set_value(iter,1,new_text) |
379 |
#self.update_all_units(_entry._conv,_entry.getUnits(),param) |
380 |
|
381 |
except InputError,e: |
382 |
self.parent.reporter.reportError(str(e)) |
383 |
return |
384 |
|
385 |
#def populate_units(self,combo,editable,path,model,units): |
386 |
#iter = model.get_iter(path) |
387 |
#param = model.get_value(iter,3) |
388 |
#dim=param.type.getDimensions() |
389 |
#self._units = [] |
390 |
##print 'Populating for Dimension... ' + str(dim) |
391 |
#for u in units: |
392 |
#if u.getDimensions() == dim: |
393 |
#self._units.append(str(u.getName())) |
394 |
|
395 |
#def update_all_units(self,conv,units,param): |
396 |
#def update(model,path,iter): |
397 |
#_param = model.get_value(iter,3) |
398 |
#if str(_param.type) == str(param.type) and not _param==param: |
399 |
#model.set_value(iter,1,param.setValue(conv,units)) |
400 |
#self.model.foreach(update) |
401 |
|
402 |
|
403 |
class paramListStore(object): |
404 |
''' |
405 |
Stores the Parameters in a Gtk.ListStore for Gtk.TreeView |
406 |
First Column: Name |
407 |
Second Column: Value |
408 |
Fourth Column: Lock/Unlock Icon Status |
409 |
Fifth Column: Text Foreground |
410 |
Sixth Column: Text Weight |
411 |
Seventh Column: Tootip Description |
412 |
''' |
413 |
def __init__(self,params): |
414 |
self.list_store = Gtk.ListStore(GObject.TYPE_STRING,GObject.TYPE_STRING,GdkPixbuf.Pixbuf,GObject.TYPE_PYOBJECT,GObject.TYPE_STRING, GObject.TYPE_INT,GObject.TYPE_STRING) |
415 |
self.params = params |
416 |
for name in self.params.keys(): |
417 |
pi=self.params[name] |
418 |
if self.params[name].fix == True: |
419 |
self.list_store.append([pi.name,pi.getValue(), _iconfixed, pi, _colorfixed, _weightfixed,pi.get_description()]) |
420 |
else: |
421 |
self.list_store.append([pi.name,pi.getValue(), _iconfree, pi, _colorfree, _weightfree,pi.get_description()]) |
422 |
def get_model(self): |
423 |
if self.list_store: |
424 |
return self.list_store |
425 |
return None |
426 |
|
427 |
# vim: set ts=4 noet: |