Status: | Superseded |
---|---|
Proposed branch: | lp:~spud/spud/group-view |
Merge into: | lp:spud |
Prerequisite: | lp:~spud/spud/slice-view |
Diff against target: |
581 lines (+191/-93) 4 files modified
diamond/diamond/choice.py (+6/-0) diamond/diamond/interface.py (+150/-89) diamond/diamond/tree.py (+4/-1) diamond/gui/gui.glade (+31/-3) |
To merge this branch: | bzr merge lp:~spud/spud/group-view |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Patrick Farrell | Pending | ||
Review via email:
|
This proposal has been superseded by a proposal from 2011-07-26.
Commit message
Description of the change
Allows nodes to be grouped together in the LHS hiding all other nodes.
To post a comment you must log in.
lp:~spud/spud/group-view
updated
- 449. By Fraser Waters
-
Merge from trunk.
- 450. By Fraser Waters
-
Added edit menu options. Fixed grouping on whole tree.
- 451. By Fraser Waters
-
Changed __class__ == to isinstance
- 452. By Fraser Waters
-
Choices and optionals show in group view.
- 453. By Fraser Waters
-
__str__ on Tree and Choice returns the display name.
- 454. By Fraser Waters
-
In group mode use name paths, in normal mode use display names.
- 455. By Fraser Waters
-
Refresh fix.
- 456. By Fraser Waters
-
Select the node you group or ungroup on.
- 457. By Fraser Waters
-
Grouping bug fix for choices.
- 458. By Fraser Waters
-
Fixed long names, and more choice bugs
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'diamond/diamond/choice.py' |
2 | --- diamond/diamond/choice.py 2011-07-25 13:41:47 +0000 |
3 | +++ diamond/diamond/choice.py 2011-07-26 16:14:06 +0000 |
4 | @@ -196,5 +196,11 @@ |
5 | |
6 | def is_sliceable(self): |
7 | return self.get_current_tree().is_sliceable() |
8 | + |
9 | + def __str__(self): |
10 | + """ |
11 | + Returns the display name of the selected tree. |
12 | + """ |
13 | + return self.get_display_name() |
14 | |
15 | gobject.type_register(Choice) |
16 | |
17 | === modified file 'diamond/diamond/interface.py' |
18 | --- diamond/diamond/interface.py 2011-07-25 13:51:34 +0000 |
19 | +++ diamond/diamond/interface.py 2011-07-26 16:14:06 +0000 |
20 | @@ -90,7 +90,7 @@ |
21 | treeview: the LHS tree widget |
22 | |
23 | Important routines: |
24 | - cellcombo_edited: called when a choice is selected on the left-hand pane |
25 | + cellcombo_changed: called when a choice is selected on the left-hand pane |
26 | init_treemodel: set up the treemodel and treeview |
27 | on_treeview_clicked: when a row is clicked, process the consequences (e.g. activate inactive instance) |
28 | set_treestore: stuff the treestore with a given tree.Tree |
29 | @@ -139,7 +139,10 @@ |
30 | "on_copy_spud_path": self.on_copy_spud_path, |
31 | "on_copy": self.on_copy, |
32 | "on_paste": self.on_paste, |
33 | - "on_slice": self.on_slice} |
34 | + "on_slice": self.on_slice, |
35 | + "on_group": self.on_group, |
36 | + "on_ungroup": self.on_ungroup} |
37 | + |
38 | self.gui.signal_autoconnect(signals) |
39 | |
40 | self.main_window = self.gui.get_widget("mainWindow") |
41 | @@ -157,6 +160,7 @@ |
42 | self.suffix = suffix |
43 | |
44 | self.selected_node = None |
45 | + self.selected_iter = None |
46 | self.update_options_frame() |
47 | |
48 | self.file_path = os.getcwd() |
49 | @@ -668,7 +672,7 @@ |
50 | ios = StringIO.StringIO(clipboard.wait_for_text()) |
51 | |
52 | if self.selected_iter is not None: |
53 | - node = self.treestore.get_value(self.selected_iter, 3) |
54 | + node = self.treestore.get_value(self.selected_iter, 1) |
55 | |
56 | if node != None: |
57 | |
58 | @@ -729,6 +733,80 @@ |
59 | def _slice_destroy(self, widget): |
60 | self.on_select_row() |
61 | |
62 | + |
63 | + groupmode = False |
64 | + |
65 | + def on_group(self, widget = None): |
66 | + """ |
67 | + Clears the treeview and then fills it with nodes |
68 | + with the same type as the selected node. |
69 | + """ |
70 | + |
71 | + if self.selected_node == self.tree or not self.selected_iter: |
72 | + self.statusbar.set_statusbar("Cannot group on this element.") |
73 | + return #Group on the entire tree... ie don't group or nothing selected |
74 | + |
75 | + self.gui.get_widget("menuitemUngroup").show() |
76 | + self.gui.get_widget("popupmenuitemUngroup").show() |
77 | + |
78 | + self.groupmode = True |
79 | + node, tree = self.treestore.get(self.selected_iter, 0, 1) |
80 | + |
81 | + self.treeview.freeze_child_notify() |
82 | + self.treeview.set_model(None) |
83 | + |
84 | + def get_nodes(node, tree): |
85 | + nodes = [] |
86 | + |
87 | + if isinstance(tree, choice.Choice): |
88 | + child = tree.get_current_tree() |
89 | + if child.name == node.name: |
90 | + nodes.append(tree) |
91 | + nodes += get_nodes(node, child) |
92 | + else: |
93 | + for child in tree.get_children(): |
94 | + if child.name == node.name: |
95 | + nodes.append(child) |
96 | + nodes += get_nodes(node, child) |
97 | + |
98 | + return nodes |
99 | + |
100 | + self.set_treestore(None, get_nodes(tree, self.tree), True) |
101 | + |
102 | + self.treeview.set_model(self.treestore) |
103 | + self.treeview.thaw_child_notify() |
104 | + |
105 | + path = self.get_treestore_path_from_node(node) |
106 | + self.treeview.get_selection().select_path(path) |
107 | + |
108 | + return |
109 | + |
110 | + def on_ungroup(self, widget = None): |
111 | + """ |
112 | + Restores the treeview to normal. |
113 | + """ |
114 | + |
115 | + self.gui.get_widget("menuitemUngroup").hide() |
116 | + self.gui.get_widget("popupmenuitemUngroup").hide() |
117 | + |
118 | + self.groupmode = False |
119 | + node = self.treestore.get_value(self.selected_iter, 0) |
120 | + |
121 | + self.treeview.freeze_child_notify() |
122 | + self.treeview.set_model(None) |
123 | + |
124 | + self.set_treestore(None, [self.tree], True) |
125 | + |
126 | + self.treeview.set_model(self.treestore) |
127 | + self.treeview.thaw_child_notify() |
128 | + |
129 | + path = self.get_treestore_path_from_node(node) |
130 | + self.treeview.expand_to_path(path) |
131 | + self.treeview.scroll_to_cell(path) |
132 | + self.treeview.get_selection().select_path(path) |
133 | + |
134 | + return |
135 | + |
136 | ## LHS ### |
137 | |
138 | def init_datatree(self): |
139 | @@ -773,16 +851,14 @@ |
140 | self.treeview.get_selection().set_select_function(self.options_tree_select_func) |
141 | self.options_tree_select_func_enabled = True |
142 | |
143 | - model = gtk.ListStore(str, str, gobject.TYPE_PYOBJECT) |
144 | self.cellcombo = cellCombo = gtk.CellRendererCombo() |
145 | - cellCombo.set_property("model", model) |
146 | cellCombo.set_property("text-column", 0) |
147 | cellCombo.set_property("editable", True) |
148 | cellCombo.set_property("has-entry", False) |
149 | - cellCombo.connect("edited", self.cellcombo_edited) |
150 | + cellCombo.connect("changed", self.cellcombo_changed) |
151 | |
152 | # Node column |
153 | - column = gtk.TreeViewColumn("Node", cellCombo, text=0) |
154 | + column = gtk.TreeViewColumn("Node", cellCombo) |
155 | column.set_property("expand", True) |
156 | column.set_resizable(True) |
157 | column.set_cell_data_func(cellCombo, self.set_combobox_liststore) |
158 | @@ -800,12 +876,11 @@ |
159 | imgcolumn.set_cell_data_func(cellPicture, self.set_cellpicture_cardinality) |
160 | optionsTree.append_column(imgcolumn) |
161 | |
162 | - # 0: display name, |
163 | - # 1: gtk.ListStore containing the display names of possible choices |
164 | - # 2: pointer to node in self.tree -- a choice or a tree |
165 | - # 3: pointer to currently active tree |
166 | + # 0: pointer to node in self.tree -- a choice or a tree |
167 | + # 1: pointer to currently active tree |
168 | + # 2: gtk.ListStore containing the display names of possible choices |
169 | |
170 | - self.treestore = gtk.TreeStore(str, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT) |
171 | + self.treestore = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT) |
172 | self.treeview.set_model(self.treestore) |
173 | self.treeview.set_enable_search(False) |
174 | |
175 | @@ -820,8 +895,7 @@ |
176 | liststore = gtk.ListStore(str, gobject.TYPE_PYOBJECT) |
177 | |
178 | for t in choice_or_tree.get_choices(): |
179 | - name = t.get_display_name() |
180 | - liststore.append([name, t]) |
181 | + liststore.append([str(t), t]) |
182 | |
183 | return liststore |
184 | |
185 | @@ -851,9 +925,9 @@ |
186 | liststore = self.create_liststore(t) |
187 | |
188 | if replace: |
189 | - child_iter = self.treestore.insert_before(iter, replacediter, [t.get_display_name(), liststore, t, t]) |
190 | + child_iter = self.treestore.insert_before(iter, replacediter, [t, t, liststore]) |
191 | else: |
192 | - child_iter = self.treestore.append(iter, [t.get_display_name(), liststore, t, t]) |
193 | + child_iter = self.treestore.append(iter, [t, t, liststore]) |
194 | |
195 | attrid = t.connect("on-set-attr", self.on_set_attr, self.treestore.get_path(child_iter)) |
196 | dataid = t.connect("on-set-data", self.on_set_data, self.treestore.get_path(child_iter)) |
197 | @@ -871,9 +945,9 @@ |
198 | continue |
199 | |
200 | if replace: |
201 | - child_iter = self.treestore.insert_before(iter, replacediter, [ts_choice.get_display_name(), liststore, t, ts_choice]) |
202 | + child_iter = self.treestore.insert_before(iter, replacediter, [t, ts_choice, liststore]) |
203 | else: |
204 | - child_iter = self.treestore.append(iter, [ts_choice.get_display_name(), liststore, t, ts_choice]) |
205 | + child_iter = self.treestore.append(iter, [t, ts_choice, liststore]) |
206 | |
207 | attrid = t.connect("on-set-attr", self.on_set_attr, self.treestore.get_path(child_iter)) |
208 | dataid = t.connect("on-set-data", self.on_set_data, self.treestore.get_path(child_iter)) |
209 | @@ -916,7 +990,7 @@ |
210 | self.set_treestore(iter, []) |
211 | return |
212 | |
213 | - choice_or_tree, active_tree = self.treestore.get(iter, 2, 3) |
214 | + choice_or_tree, active_tree = self.treestore.get(iter, 0, 1) |
215 | if active_tree.active is False or choice_or_tree.active is False: |
216 | return |
217 | |
218 | @@ -927,7 +1001,7 @@ |
219 | child_iter = self.treestore.iter_children(iter) |
220 | while child_iter is not None: |
221 | # fix for recursive schemata! |
222 | - child_active_tree = self.treestore.get_value(child_iter, 3) |
223 | + child_active_tree = self.treestore.get_value(child_iter, 1) |
224 | if child_active_tree.schemaname == active_tree.schemaname: |
225 | debug.deprint("Warning: recursive schema elements not supported: %s" % active_tree.name) |
226 | child_iter = self.treestore.iter_next(child_iter) |
227 | @@ -961,15 +1035,20 @@ |
228 | foreground colour. |
229 | """ |
230 | |
231 | - liststore, choice_or_tree, active_tree = self.treestore.get(iter, 1, 2, 3) |
232 | - |
233 | - # set the model for the cellcombo, where it gets the possible choices for the name |
234 | + choice_or_tree, active_tree, liststore = self.treestore.get(iter, 0, 1, 2) |
235 | + |
236 | + if self.groupmode and self.treestore.iter_parent(iter) is None: |
237 | + cellCombo.set_property("text", choice_or_tree.get_name_path()) |
238 | + else: |
239 | + cellCombo.set_property("text", str(choice_or_tree)) |
240 | + |
241 | + |
242 | cellCombo.set_property("model", liststore) |
243 | |
244 | # set the properties: colour, etc. |
245 | - if choice_or_tree.__class__ is tree.Tree: |
246 | + if isinstance(choice_or_tree, tree.Tree): |
247 | cellCombo.set_property("editable", False) |
248 | - elif choice_or_tree.__class__ is choice.Choice: |
249 | + elif isinstance(choice_or_tree, choice.Choice): |
250 | cellCombo.set_property("editable", True) |
251 | |
252 | if self.treestore_iter_is_active(iter): |
253 | @@ -987,8 +1066,8 @@ |
254 | This hook function sets up the other gtk.CellRendererPixbuf, the one that gives |
255 | the clue to the user whether this is a choice or not. |
256 | """ |
257 | - |
258 | - choice_or_tree = self.treestore.get_value(iter, 2) |
259 | + |
260 | + choice_or_tree = self.treestore.get_value(iter, 0) |
261 | if isinstance(choice_or_tree, tree.Tree): |
262 | cell.set_property("stock-id", None) |
263 | elif isinstance(choice_or_tree, choice.Choice): |
264 | @@ -1003,7 +1082,7 @@ |
265 | something can be added or removed or has to be there. |
266 | """ |
267 | |
268 | - choice_or_tree = self.treestore.get_value(iter, 2) |
269 | + choice_or_tree = self.treestore.get_value(iter, 0) |
270 | if choice_or_tree.cardinality == "": |
271 | cell.set_property("stock-id", None) |
272 | elif choice_or_tree.cardinality == "?" or choice_or_tree.cardinality == "*": |
273 | @@ -1029,7 +1108,7 @@ |
274 | Toggles the state of part of the tree. |
275 | """ |
276 | |
277 | - choice_or_tree = self.treestore.get_value(iter, 2) |
278 | + choice_or_tree = self.treestore.get_value(iter, 0) |
279 | |
280 | if choice_or_tree.active: |
281 | self.collapse_tree(iter) |
282 | @@ -1045,13 +1124,8 @@ |
283 | Collapses part of the tree. |
284 | """ |
285 | |
286 | - choice_or_tree, = self.treestore.get(iter, 2) |
287 | - parent_iter = self.treestore.iter_parent(iter) |
288 | - |
289 | - if parent_iter == None: |
290 | - parent_tree = None |
291 | - else: |
292 | - parent_tree = self.treestore.get_value(parent_iter, 3) |
293 | + choice_or_tree, = self.treestore.get(iter, 0) |
294 | + parent_tree = choice_or_tree.parent |
295 | |
296 | if not choice_or_tree.active: |
297 | return |
298 | @@ -1088,16 +1162,11 @@ |
299 | return |
300 | |
301 | def delete_tree(self, iter): |
302 | - choice_or_tree, = self.treestore.get(iter, 2) |
303 | - parent_iter = self.treestore.iter_parent(iter) |
304 | + choice_or_tree, = self.treestore.get(iter, 0) |
305 | + parent_tree = choice_or_tree.parent |
306 | isSelected = self.treeview.get_selection().iter_is_selected(iter) |
307 | sibling = self.treestore.iter_next(iter) |
308 | |
309 | - if parent_iter == None: |
310 | - parent_tree = None |
311 | - else: |
312 | - parent_tree = self.treestore.get_value(parent_iter, 3) |
313 | - |
314 | confirm = dialogs.prompt(self.main_window, "Are you sure you want to delete this node?") |
315 | if confirm == gtk.RESPONSE_YES: |
316 | parent_tree.delete_child_by_ref(choice_or_tree) |
317 | @@ -1114,13 +1183,8 @@ |
318 | Expands part of the tree. |
319 | """ |
320 | |
321 | - choice_or_tree, active_tree = self.treestore.get(iter, 2, 3) |
322 | - parent_iter = self.treestore.iter_parent(iter) |
323 | - |
324 | - if parent_iter == None: |
325 | - parent_tree = None |
326 | - else: |
327 | - parent_tree = self.treestore.get_value(parent_iter, 3) |
328 | + choice_or_tree, active_tree = self.treestore.get(iter, 0, 1) |
329 | + parent_tree = choice_or_tree.parent |
330 | |
331 | if choice_or_tree.active: |
332 | return |
333 | @@ -1140,8 +1204,7 @@ |
334 | liststore = self.create_liststore(new_tree) |
335 | self.expand_treestore(iter) |
336 | iter = self.treestore.insert_after( |
337 | - parent=parent_iter, sibling=iter, |
338 | - row=[new_tree.get_display_name(), liststore, new_tree, new_tree.get_current_tree()]) |
339 | + None, iter, [new_tree, new_tree.get_current_tree(), liststore]) |
340 | attrid = new_tree.connect("on-set-attr", self.on_set_attr, self.treestore.get_path(iter)) |
341 | dataid = new_tree.connect("on-set-data", self.on_set_data, self.treestore.get_path(iter)) |
342 | self.signals[new_tree] = (attrid, dataid) |
343 | @@ -1243,7 +1306,7 @@ |
344 | return |
345 | |
346 | self.selected_iter = iter = self.treestore.get_iter(path) |
347 | - choice_or_tree, active_tree = self.treestore.get(iter, 2, 3) |
348 | + choice_or_tree, active_tree = self.treestore.get(iter, 0, 1) |
349 | |
350 | debug.dprint(active_tree) |
351 | |
352 | @@ -1367,26 +1430,18 @@ |
353 | |
354 | return |
355 | |
356 | - def cellcombo_edited(self, cellrenderertext, path, new_text): |
357 | + def cellcombo_changed(self, combo, tree_path, combo_iter): |
358 | """ |
359 | This is called when a cellcombo on the left-hand treeview is edited, |
360 | i.e. the user chooses between more than one possible choice. |
361 | """ |
362 | |
363 | - iter = self.treestore.get_iter(path) |
364 | - self.treestore.set(iter, 0, new_text) |
365 | - choice = self.treestore.get_value(iter, 2) |
366 | + tree_iter = self.treestore.get_iter(tree_path) |
367 | + choice = self.treestore.get_value(tree_iter, 0) |
368 | |
369 | # get the ref to the new active choice |
370 | - liststore = self.treestore.get_value(iter, 1) |
371 | - list_iter = liststore.get_iter_first() |
372 | - ref = None |
373 | - while list_iter is not None: |
374 | - list_text = liststore.get_value(list_iter, 0) |
375 | - if list_text == new_text: |
376 | - ref = liststore.get_value(list_iter, 1) |
377 | - break |
378 | - list_iter = liststore.iter_next(list_iter) |
379 | + liststore = self.treestore.get_value(tree_iter, 2) |
380 | + ref = liststore.get_value(combo_iter, 1) |
381 | |
382 | # record the choice in the datatree |
383 | choice.set_active_choice_by_ref(ref) |
384 | @@ -1394,7 +1449,7 @@ |
385 | |
386 | name = self.get_spudpath(new_active_tree) |
387 | self.statusbar.set_statusbar(name) |
388 | - self.treestore.set(iter, 3, new_active_tree) |
389 | + self.treestore.set(tree_iter, 1, new_active_tree) |
390 | self.current_spudpath = name |
391 | xpath = self.get_xpath(new_active_tree) |
392 | self.current_xpath = xpath |
393 | @@ -1405,12 +1460,12 @@ |
394 | if plugin.matches(xpath): |
395 | self.add_plugin_button(plugin) |
396 | |
397 | - self.remove_children(iter) |
398 | - self.expand_treestore(iter) |
399 | - self.treeview.expand_row(path, False) |
400 | + self.remove_children(tree_iter) |
401 | + self.expand_treestore(tree_iter) |
402 | + self.treeview.expand_row(tree_path, False) |
403 | |
404 | self.set_saved(False) |
405 | - self.selected_node = self.get_painted_tree(iter) |
406 | + self.selected_node = self.get_painted_tree(tree_iter) |
407 | self.update_options_frame() |
408 | |
409 | return |
410 | @@ -1435,20 +1490,7 @@ |
411 | if attr != "name": |
412 | return |
413 | |
414 | - iter = self.treestore.get_iter(path) |
415 | - liststore = self.treestore.get_value(iter, 1) |
416 | - active_tree = self.treestore.get_value(iter, 3) |
417 | - new_name = active_tree.get_display_name() |
418 | - self.treestore.set_value(iter, 0, new_name) |
419 | - |
420 | - # find the liststore iter corresponding to the painted choice |
421 | - list_iter = liststore.get_iter_first() |
422 | - while list_iter is not None: |
423 | - liststore_tree = liststore.get_value(list_iter, 1) |
424 | - if liststore_tree is active_tree: |
425 | - liststore.set_value(list_iter, 0, new_name) |
426 | - list_iter = liststore.iter_next(list_iter) |
427 | - |
428 | + self.treeview.queue_draw() |
429 | self.treeview.queue_resize() |
430 | |
431 | def get_painted_tree(self, iter_or_tree, lock_geometry_dim = True): |
432 | @@ -1465,7 +1507,7 @@ |
433 | if isinstance(iter_or_tree, tree.Tree): |
434 | active_tree = iter_or_tree |
435 | else: |
436 | - active_tree = self.treestore.get_value(iter_or_tree, 3) |
437 | + active_tree = self.treestore.get_value(iter_or_tree, 1) |
438 | |
439 | painted_tree = active_tree.get_mixed_data() |
440 | |
441 | @@ -1505,7 +1547,26 @@ |
442 | return None |
443 | |
444 | return iter |
445 | + |
446 | + def get_treestore_path_from_node(self, node): |
447 | + """ |
448 | + Look for the path for the given node. |
449 | + """ |
450 | |
451 | + def search(iter, node, indent=""): |
452 | + while iter: |
453 | + if self.treestore.get_value(iter, 0) is node: |
454 | + return iter |
455 | + else: |
456 | + child = search(self.treestore.iter_children(iter), node, indent + " ") |
457 | + if child: return child |
458 | + |
459 | + iter = self.treestore.iter_next(iter) |
460 | + return iter |
461 | + |
462 | + iter = search(self.treestore.get_iter_first(), node) |
463 | + return self.treestore.get_path(iter) if iter else None |
464 | + |
465 | def set_geometry_dim_tree(self): |
466 | """ |
467 | Find the iter into the treestore corresponding to the geometry dimension, and |
468 | @@ -1567,8 +1628,8 @@ |
469 | """ |
470 | |
471 | while iter is not None: |
472 | - choice_or_tree = self.treestore.get_value(iter, 2) |
473 | - active_tree = self.treestore.get_value(iter, 3) |
474 | + choice_or_tree = self.treestore.get_value(iter, 0) |
475 | + active_tree = self.treestore.get_value(iter, 1) |
476 | if not choice_or_tree.active or not active_tree.active: |
477 | return False |
478 | iter = self.treestore.iter_parent(iter) |
479 | @@ -1629,7 +1690,7 @@ |
480 | iter = self.treestore.get_iter_first() |
481 | if iter is None: |
482 | yield None |
483 | - choice_or_tree = self.treestore.get_value(iter, 2) |
484 | + choice_or_tree = self.treestore.get_value(iter, 0) |
485 | |
486 | if self.choice_or_tree_matches(text, choice_or_tree, isinstance(choice_or_tree, choice.Choice)): |
487 | yield iter |
488 | |
489 | === modified file 'diamond/diamond/tree.py' |
490 | --- diamond/diamond/tree.py 2011-07-25 13:41:47 +0000 |
491 | +++ diamond/diamond/tree.py 2011-07-26 16:14:06 +0000 |
492 | @@ -301,7 +301,7 @@ |
493 | def unpickle(self, pick): |
494 | return pickle.loads(bz2.decompress(base64.b64decode(pick))) |
495 | |
496 | - def __str__(self): |
497 | + def print_str(self): |
498 | s = "name: %s at %s\n" % (self.name, hex(id(self))) |
499 | s = s + "schemaname: %s\n" % self.schemaname |
500 | s = s + "attrs: %s\n" % self.attrs |
501 | @@ -538,6 +538,9 @@ |
502 | return True |
503 | |
504 | return (self.datatype is not None and self.datatype != "fixed") or self.attrs |
505 | + |
506 | + def __str__(self): |
507 | + return self.get_display_name() |
508 | |
509 | gobject.type_register(Tree) |
510 | |
511 | |
512 | === modified file 'diamond/gui/gui.glade' |
513 | --- diamond/gui/gui.glade 2011-07-22 15:46:25 +0000 |
514 | +++ diamond/gui/gui.glade 2011-07-26 16:14:06 +0000 |
515 | @@ -132,6 +132,20 @@ |
516 | <accelerator key="V" signal="activate" modifiers="GDK_CONTROL_MASK"/> |
517 | </widget> |
518 | </child> |
519 | + <child> |
520 | + <widget class="GtkMenuItem" id="menuitemGroup"> |
521 | + <property name="visible">True</property> |
522 | + <property name="label" translatable="yes">Group</property> |
523 | + <signal name="activate" handler="on_group"/> |
524 | + </widget> |
525 | + </child> |
526 | + <child> |
527 | + <widget class="GtkMenuItem" id="menuitemUngroup"> |
528 | + <property name="visible">False</property> |
529 | + <property name="label" translatable="yes">Ungroup</property> |
530 | + <signal name="activate" handler="on_ungroup"/> |
531 | + </widget> |
532 | + </child> |
533 | </widget> |
534 | </child> |
535 | </widget> |
536 | @@ -488,7 +502,7 @@ |
537 | <widget class="GtkMenu" id="popupmenu"> |
538 | <property name="visible">True</property> |
539 | <child> |
540 | - <widget class="GtkMenuItem" id="menuitemCopy"> |
541 | + <widget class="GtkMenuItem" id="popupmenuitemCopy"> |
542 | <property name="visible">True</property> |
543 | <property name="label" translatable="yes">Copy</property> |
544 | <property name="use_underline">True</property> |
545 | @@ -496,7 +510,7 @@ |
546 | </widget> |
547 | </child> |
548 | <child> |
549 | - <widget class="GtkMenuItem" id="menuitemPaste"> |
550 | + <widget class="GtkMenuItem" id="popupmenuitemPaste"> |
551 | <property name="visible">True</property> |
552 | <property name="label" translatable="yes">Paste</property> |
553 | <property name="use_underline">True</property> |
554 | @@ -504,12 +518,26 @@ |
555 | </widget> |
556 | </child> |
557 | <child> |
558 | - <widget class="GtkMenuItem" id="menuitemSlice"> |
559 | + <widget class="GtkMenuItem" id="popupmenuitemSlice"> |
560 | <property name="visible">True</property> |
561 | <property name="label" translatable="yes">Slice</property> |
562 | <property name="use_underline">True</property> |
563 | <signal name="activate" handler="on_slice"/> |
564 | </widget> |
565 | </child> |
566 | + <child> |
567 | + <widget class="GtkMenuItem" id="popupmenuitemGroup"> |
568 | + <property name="visible">True</property> |
569 | + <property name="label" translatable="yes">Group</property> |
570 | + <signal name="activate" handler="on_group"/> |
571 | + </widget> |
572 | + </child> |
573 | + <child> |
574 | + <widget class="GtkMenuItem" id="popupmenuitemUngroup"> |
575 | + <property name="visible">False</property> |
576 | + <property name="label" translatable="yes">Ungroup</property> |
577 | + <signal name="activate" handler="on_ungroup"/> |
578 | + </widget> |
579 | + </child> |
580 | </widget> |
581 | </glade-interface> |