Merge lp:~spud/spud/copy-paste-fix into lp:spud

Proposed by Fraser Waters
Status: Superseded
Proposed branch: lp:~spud/spud/copy-paste-fix
Merge into: lp:spud
Diff against target: 482 lines (+86/-108)
4 files modified
diamond/diamond/choice.py (+23/-47)
diamond/diamond/interface.py (+41/-29)
diamond/diamond/schema.py (+16/-21)
diamond/diamond/tree.py (+6/-11)
To merge this branch: bzr merge lp:~spud/spud/copy-paste-fix
Reviewer Review Type Date Requested Status
Fraser Waters Needs Resubmitting
Cian Wilson Needs Information
Patrick Farrell Pending
Review via email: mp+69465@code.launchpad.net

This proposal supersedes a proposal from 2011-07-18.

This proposal has been superseded by a proposal from 2011-07-28.

Description of the change

Fix for bug #811200 and #812348. on_paste was not handling MixedTree's in the same way as on_copy. on_paste was not handling choices correctly.

To post a comment you must log in.
Revision history for this message
Cian Wilson (cwilson) wrote : Posted in a previous version of this proposal

With that branch I'm still getting the same error:

  File "/usr/lib/python2.7/dist-packages/diamond/interface.py", line 695, in on_paste
    newnode = self.s.read(ios, node)
  File "/usr/lib/python2.7/dist-packages/diamond/schema.py", line 532, in read
    datatree = self.valid_node(root)
  File "/usr/lib/python2.7/dist-packages/diamond/schema.py", line 167, in valid_node
    eidtree.parent.children.remove(eidtree)
ValueError: list.remove(x): x not in list

and behaviour as reported in bug #811200 (i.e. saving the file immediately afterwards saves a file that's different from the one you're seeing and you also don't get a copied branch of the tree).

Can anyone else reproduce this or have I mangled my paths somewhere? (I packaged the branch and installed it so shouldn't be mixing versions of diamond.)

review: Needs Information
Revision history for this message
Patrick Farrell (pefarrell) wrote : Posted in a previous version of this proposal

I attempted to replicate #811200 with this branch.

I don't get Cian's terminal error; I think that's been fixed, and I suspect it's something to do with running the wrong version of diamond. Cian: when you check out a branch, just do

cd branch
./configure
python diamond/bin/diamond [args]

and it will automatically use the right code.

But I get a different bug. It doesn't give any exception, but when I save the file I get

<?xml version='1.0' encoding='utf-8'?>
<dummy_options>
  <system name="Dummy">
    <nonlinear_solver name="Simple">
      <type name="SNES">
        <python name="Jacobian" rank="1">
          <string_value lines="20" type="python">some python code here</string_value>
        </python>
      </type>
    </nonlinear_solver>
    <nonlinear_solver>
      <type name="SNES">
        <python name="Jacobian" rank="1">
          <string_value type="python" lines="20"/>
        </python>
      </type>
    </nonlinear_solver>
  </system>
</dummy_options>

Note that the second nonlinear solver has a) lost its name, and b) lost its python code. It *looks* fine in the live diamond window, but if you save it it gets lost. (If you open it up again, you'll get all sorts of lost element errors.)

Revision history for this message
Cian Wilson (cwilson) wrote : Posted in a previous version of this proposal

> cd branch
> ./configure
> python diamond/bin/diamond [args]

I get the same error (terminal output and all) running the command this way:

cwilson@uisce:copy-paste-fix$ python diamond/bin/diamond -s ~/temp/schema/dummy.rng ~/temp/schema/dummy.dml

Just to confirm it's the branch I'm running:
cwilson@uisce:copy-paste-fix$ bzr info
Repository tree (format: 2a)
Location:
  shared repository: /home/cwilson/spud/bzr-repo
  repository branch: .

Related branches:
  parent branch: bzr+ssh://bazaar.launchpad.net/~spud/spud/copy-paste-fix/

> <?xml version='1.0' encoding='utf-8'?>
> <dummy_options>
> <system name="Dummy">
> <nonlinear_solver name="Simple">
> <type name="SNES">
> <python name="Jacobian" rank="1">
> <string_value lines="20" type="python">some python code
> here</string_value>
> </python>
> </type>
> </nonlinear_solver>
> <nonlinear_solver>
> <type name="SNES">
> <python name="Jacobian" rank="1">
> <string_value type="python" lines="20"/>
> </python>
> </type>
> </nonlinear_solver>
> </system>
> </dummy_options>
>
> Note that the second nonlinear solver has a) lost its name, and b) lost its
> python code. It *looks* fine in the live diamond window, but if you save it it
> gets lost. (If you open it up again, you'll get all sorts of lost element
> errors.)

With the exception of looking fine in the diamond window before I close it (i.e. it doesn't look like it's copied to me and diamond shows elements as blue still) that sounds like the same behaviour I see on reopening the file.

Revision history for this message
Patrick Farrell (pefarrell) wrote : Posted in a previous version of this proposal

Also: I seem to get different behaviour depending on whether I CTRL+C/CTRL+V, or right-click copy, right-click paste. When I right-click copy, I get the following error in the terminal:

Traceback (most recent call last):
  File "/data/pfarrell/src/spud/copy-paste-fix/diamond/bin/../diamond/interface.py", line 658, in on_copy
    if widget is not self.treeview and gobject.signal_lookup("copy-clipboard", widget):
TypeError: type must be instantiable or an interface

The XML appears correct regardless of which approach is taken.

When I paste onto the blank nonlinear_solver, it doesn't have the right cardinality: it doesn't have the '-' on the right-hand side of the treeview to deactivate it.

Revision history for this message
Cian Wilson (cwilson) wrote : Posted in a previous version of this proposal

The above was done by first adding a new nonlinear_solver element then running CTRL+C on the old copy nonlinear_solver::Simple then moving to the new element and pressing CTRL+V.

If instead I use the right-click feature I get:

Traceback (most recent call last):
  File "/home/cwilson/spud/bzr-repo/copy-paste-fix/diamond/bin/../diamond/interface.py", line 658, in on_copy
    if widget is not self.treeview and gobject.signal_lookup("copy-clipboard", widget):
TypeError: type must be instantiable or an interface

on copy and:

Traceback (most recent call last):
  File "/home/cwilson/spud/bzr-repo/copy-paste-fix/diamond/bin/../diamond/interface.py", line 681, in on_paste
    if widget is not self.treeview and gobject.signal_lookup("paste-clipboard", widget):
TypeError: type must be instantiable or an interface

on paste.

Revision history for this message
Fraser Waters (fraser-waters08) wrote : Posted in a previous version of this proposal

"TypeError: type must be instantiable or an interface"

I found the cause of that, it's fixed in my local version.

The rest I'm not sure, I'll look into it more it's probably some confusion between Choices, Trees and MixedTrees. Really need to standardize them at some point.

Revision history for this message
Cian Wilson (cwilson) wrote :

Repeating the steps (and using the schema and options file) in bug #811200 (i.e. activating a new nonlinear_solver element, copying nonlinear_solver::Simple and trying to paste it into the new active element - using Ctrl+C and Ctrl+V) I get the error:

  File "/usr/lib/python2.7/dist-packages/diamond/interface.py", line 684, in on_paste
    newnode = self.s.read(ios, node)
  File "/usr/lib/python2.7/dist-packages/diamond/schema.py", line 526, in read
    datatree = self.valid_node(root)
  File "/usr/lib/python2.7/dist-packages/diamond/schema.py", line 156, in valid_node
    xpath = self.tree.xpath(eid)
  File "lxml.etree.pyx", line 2029, in lxml.etree._ElementTree.xpath (src/lxml/lxml.etree.c:45934)
  File "xpath.pxi", line 363, in lxml.etree.XPathDocumentEvaluator.__call__ (src/lxml/lxml.etree.c:114234)
  File "apihelpers.pxi", line 1364, in lxml.etree._utf8 (src/lxml/lxml.etree.c:22190)
TypeError: Argument must be bytes or unicode, got 'Choice'

Nothing appears in the pasted to element.

If I then delete the node that I just failed to copy information to and save the file, close it and reopen it, it reappears as I last saw (and saved) it so that part of the bug appears fixed.

I get the same error using right-click copy and paste and if the element being pasted to is active or not.

Can anyone reproduce this with this branch? I've built packages from this branch and overwritten my previously installed spud so am reasonably confident I'm not getting paths muddled.

review: Needs Information
Revision history for this message
Patrick Farrell (pefarrell) wrote :

Cian: yes, I can reproduce your behaviour. Thanks again for your thorough testing.

We know that the way choices are handled needs to be changed (there's another bug I didn't bother writing up), so Fraser will start on that soon.

Revision history for this message
Fraser Waters (fraser-waters08) wrote :

Yes just to confirm. Choice nodes aren't being handled correctly at the moment. I'm working on it. Trying to paste on a choice should always fail at the moment. If your getting bugs with normal nodes keep reporting them, because they SHOULD work.

review: Needs Fixing
Revision history for this message
Fraser Waters (fraser-waters08) wrote :

Choice nodes should be handled correctly now.

review: Needs Resubmitting

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'diamond/diamond/choice.py'
--- diamond/diamond/choice.py 2011-07-26 14:04:07 +0000
+++ diamond/diamond/choice.py 2011-07-28 13:56:32 +0000
@@ -31,23 +31,23 @@
31 __gsignals__ = { "on-set-data" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str,)),31 __gsignals__ = { "on-set-data" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str,)),
32 "on-set-attr" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, str))}32 "on-set-attr" : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (str, str))}
3333
34 def __init__(self, l, cardinality=''):34 def __init__(self, choices, schemaname="", cardinality=''):
35 gobject.GObject.__init__(self)35 gobject.GObject.__init__(self)
3636
37 self.l = l37 self.choices = choices
38 if l == []:38 if choices == []:
39 raise Exception39 raise Exception
40 self.index = 040 self.index = 0
41 name = ""41 name = ""
42 for choice in l:42 for choice in choices:
43 assert choice.__class__ is tree.Tree43 assert choice.__class__ is tree.Tree
44 name = name + choice.name + ":"
45 choice.connect("on-set-data", self._on_set_data)44 choice.connect("on-set-data", self._on_set_data)
46 choice.connect("on-set-attr", self._on_set_attr)45 choice.connect("on-set-attr", self._on_set_attr)
4746
48 name = name[:-1]47 name = ":".join(choice.name for choice in choices)
48
49 self.name = name49 self.name = name
50 self.schemaname = name50 self.schemaname = schemaname
51 self.cardinality = cardinality51 self.cardinality = cardinality
52 self.parent = None52 self.parent = None
53 self.set_default_active()53 self.set_default_active()
@@ -67,21 +67,21 @@
67 self.index = i67 self.index = i
6868
69 def find_tree(self, name):69 def find_tree(self, name):
70 for t in self.l:70 for t in self.choices:
71 if t.name == name:71 if t.name == name:
72 return t72 return t
7373
74 debug.deprint("self.name == %s" % self.name, 0)74 debug.deprint("self.name == %s" % self.name, 0)
75 for choice in self.l:75 for choice in self.choices:
76 debug.deprint("choice.name == %s" % choice.name, 0)76 debug.deprint("choice.name == %s" % choice.name, 0)
77 raise Exception, "No such choice name: %s" % name77 raise Exception, "No such choice name: %s" % name
7878
79 def set_active_choice_by_name(self, name):79 def set_active_choice_by_name(self, name):
80 matched = False80 matched = False
81 for t in self.l:81 for t in self.choices:
82 if t.name == name.strip():82 if t.name == name.strip():
83 matched = True83 matched = True
84 self.index = self.l.index(t)84 self.index = self.choices.index(t)
8585
86 if not matched:86 if not matched:
87 raise Exception, "no such name %s found" % name87 raise Exception, "no such name %s found" % name
@@ -89,11 +89,11 @@
89 self.recompute_validity()89 self.recompute_validity()
9090
91 def set_active_choice_by_ref(self, ref):91 def set_active_choice_by_ref(self, ref):
92 self.index = self.l.index(ref)92 self.index = self.choices.index(ref)
93 self.recompute_validity()93 self.recompute_validity()
9494
95 def get_current_tree(self):95 def get_current_tree(self):
96 return self.l[self.index]96 return self.choices[self.index]
9797
98 def add_children(self, schema):98 def add_children(self, schema):
99 return self.get_current_tree().add_children(schema)99 return self.get_current_tree().add_children(schema)
@@ -106,7 +106,7 @@
106106
107 def copy(self):107 def copy(self):
108 new_choices = []108 new_choices = []
109 for choice in self.l:109 for choice in self.choices:
110 new_choices.append(choice.copy())110 new_choices.append(choice.copy())
111111
112 new_choice = Choice(new_choices)112 new_choice = Choice(new_choices)
@@ -114,37 +114,23 @@
114 setattr(new_choice, attr, copy.copy(getattr(self, attr)))114 setattr(new_choice, attr, copy.copy(getattr(self, attr)))
115115
116 new_choice.set_parent(self.parent)116 new_choice.set_parent(self.parent)
117 for choice in new_choice.l:117 for choice in new_choice.choices:
118 choice.children = copy.copy([])118 choice.children = copy.copy([])
119119
120 return new_choice120 return new_choice
121121
122 def get_possible_names(self):122 def get_possible_names(self):
123 return [x.name for x in self.l]123 return [x.name for x in self.choices]
124124
125 def set_parent(self, parent):125 def set_parent(self, parent):
126 self.parent = parent126 self.parent = parent
127 for choice in self.l:127 for choice in self.choices:
128 choice.parent = parent128 choice.parent = parent
129129
130 def write_core(self, parent):130 def write_core(self, parent):
131 l = self.l131 self.choices[self.index].write_core(parent)
132 for i in range(len(l)):
133 if self.index == i:
134 l[i].write_core(parent)
135# else:
136# root=etree.Element(parent.tag)
137# l[i].write_core(root)
138# comment_buffer = StringIO.StringIO(etree.tostring(root))
139# comment_text = ("DIAMOND MAGIC COMMENT (neglected choice subtree %s):\n" % l[i].schemaname)
140# comment_text = comment_text + base64.b64encode(bz2.compress(comment_buffer.getvalue()))
141# parent.append(etree.Comment(unicode(comment_text)))
142
143 return parent132 return parent
144133
145 def choices(self):
146 return self.l
147
148 def is_comment(self):134 def is_comment(self):
149 return False135 return False
150136
@@ -167,7 +153,7 @@
167 return [self.get_current_tree()]153 return [self.get_current_tree()]
168154
169 def get_choices(self):155 def get_choices(self):
170 return self.l156 return self.choices
171157
172 def is_hidden(self):158 def is_hidden(self):
173 """159 """
@@ -176,20 +162,7 @@
176 return False162 return False
177163
178 def get_name_path(self, leaf = True):164 def get_name_path(self, leaf = True):
179 name = self.get_display_name() if leaf else self.get_name()165 return self.get_current_tree().get_name_path(leaf)
180
181 if self.parent is None:
182 return name
183 else:
184
185 pname = self.parent.get_name_path(False)
186
187 if name is None:
188 return pname
189 elif pname is None:
190 return name
191 else:
192 return pname + "/" + name
193166
194 def get_mixed_data(self):167 def get_mixed_data(self):
195 return self168 return self
@@ -203,4 +176,7 @@
203 """176 """
204 return self.get_display_name()177 return self.get_display_name()
205178
179 def __repr__(self):
180 return self.get_name_path() + "[" + self.name + "]"
181
206gobject.type_register(Choice)182gobject.type_register(Choice)
207183
=== modified file 'diamond/diamond/interface.py'
--- diamond/diamond/interface.py 2011-07-28 12:03:24 +0000
+++ diamond/diamond/interface.py 2011-07-28 13:56:32 +0000
@@ -283,9 +283,6 @@
283 # if we have a relative path, make it absolute283 # if we have a relative path, make it absolute
284 filename = os.path.abspath(filename)284 filename = os.path.abspath(filename)
285 285
286 if filename == self.filename:
287 return
288
289 try:286 try:
290 os.stat(filename)287 os.stat(filename)
291 except OSError:288 except OSError:
@@ -638,12 +635,19 @@
638 else:635 else:
639 return self._get_focus_widget(focus)636 return self._get_focus_widget(focus)
640637
638 def _handle_clipboard(self, widget, signal):
639 if isinstance(widget, gtk.MenuItem):
640 return False
641 else:
642 widget = self._get_focus_widget(self.main_window)
643 if widget is not self.treeview and gobject.signal_lookup(signal + "-clipboard", widget):
644 widget.emit(signal + "-clipboard")
645 return True
646 return False
647
641 def on_copy(self, widget=None):648 def on_copy(self, widget=None):
642 if not isinstance(widget, gtk.MenuItem):649 if self._handle_clipboard(widget, "copy"):
643 widget = self._get_focus_widget(self.main_window)650 return
644 if widget is not self.treeview and gobject.signal_lookup("copy-clipboard", widget):
645 widget.emit("copy-clipboard")
646 return
647651
648 if isinstance(self.selected_node, mixedtree.MixedTree):652 if isinstance(self.selected_node, mixedtree.MixedTree):
649 node = self.selected_node.parent653 node = self.selected_node.parent
@@ -662,28 +666,39 @@
662 return666 return
663667
664 def on_paste(self, widget=None):668 def on_paste(self, widget=None):
665 if not isinstance(widget, gtk.MenuItem):669 if self._handle_clipboard(widget, "paste"):
666 widget = self._get_focus_widget(self.main_window)670 return
667 if widget is not self.treeview and gobject.signal_lookup("paste-clipboard", widget):
668 widget.emit("paste-clipboard")
669 return
670671
671 clipboard = gtk.clipboard_get()672 clipboard = gtk.clipboard_get()
672 ios = StringIO.StringIO(clipboard.wait_for_text())673 ios = StringIO.StringIO(clipboard.wait_for_text())
673 674
674 if self.selected_iter is not None: 675 if self.selected_iter is not None:
675 node = self.treestore.get_value(self.selected_iter, 1)676 node = self.treestore.get_value(self.selected_iter, 0)
676677
677 if node != None:678 if node != None:
679
680 expand = not node.active
681 if expand:
682 self.expand_tree(self.selected_iter)
678683
679 newnode = self.s.read(ios, node)684 newnode = self.s.read(ios, node)
680685
681 if newnode is None:686 if newnode is None:
687 if expand:
688 self.collapse_tree(self.selected_iter, False)
682 self.statusbar.set_statusbar("Trying to paste invalid XML.")689 self.statusbar.set_statusbar("Trying to paste invalid XML.")
683 return690 return
684691
685 if not node.active:692 if node.parent is not None:
686 self.expand_tree(self.selected_iter)693 newnode.set_parent(node.parent)
694 children = node.parent.get_children()
695 children.insert(children.index(node), newnode)
696 children.remove(node)
697
698 self.set_treestore(self.selected_iter, [newnode], True, True)
699
700 newnode.recompute_validity()
701 self.treeview.queue_draw()
687702
688 # Extract and display validation errors703 # Extract and display validation errors
689 lost_eles, added_eles, lost_attrs, added_attrs = self.s.read_errors()704 lost_eles, added_eles, lost_attrs, added_attrs = self.s.read_errors()
@@ -710,12 +725,6 @@
710 dialogs.long_message(self.main_window, msg)725 dialogs.long_message(self.main_window, msg)
711 726
712 self.set_saved(False) 727 self.set_saved(False)
713
714 self.treeview.freeze_child_notify()
715 iter = self.set_treestore(self.selected_iter, [newnode], True, True)
716 self.treeview.thaw_child_notify()
717
718 self.treeview.get_selection().select_iter(iter)
719728
720 return729 return
721730
@@ -907,7 +916,7 @@
907 if replace:916 if replace:
908 replacediter = iter917 replacediter = iter
909 iter = self.treestore.iter_parent(replacediter)918 iter = self.treestore.iter_parent(replacediter)
910 else:919 else:
911 self.remove_children(iter)920 self.remove_children(iter)
912 921
913 for t in new_tree:922 for t in new_tree:
@@ -1119,7 +1128,7 @@
11191128
1120 return1129 return
1121 1130
1122 def collapse_tree(self, iter):1131 def collapse_tree(self, iter, confirm = True):
1123 """1132 """
1124 Collapses part of the tree.1133 Collapses part of the tree.
1125 """1134 """
@@ -1147,7 +1156,7 @@
1147 self.set_saved(False)1156 self.set_saved(False)
1148 self.remove_children(iter)1157 self.remove_children(iter)
1149 else:1158 else:
1150 self.delete_tree(iter)1159 self.delete_tree(iter, confirm)
11511160
1152 elif choice_or_tree.cardinality == "+":1161 elif choice_or_tree.cardinality == "+":
1153 count = parent_tree.count_children_by_schemaname(choice_or_tree.schemaname)1162 count = parent_tree.count_children_by_schemaname(choice_or_tree.schemaname)
@@ -1155,20 +1164,23 @@
1155 # do nothing1164 # do nothing
1156 return1165 return
1157 else: # count > 21166 else: # count > 2
1158 self.delete_tree(iter)1167 self.delete_tree(iter, confirm)
1159 1168
1160 parent_tree.recompute_validity()1169 parent_tree.recompute_validity()
1161 self.treeview.queue_draw()1170 self.treeview.queue_draw()
1162 return1171 return
11631172
1164 def delete_tree(self, iter):1173 def delete_tree(self, iter, confirm):
1165 choice_or_tree, = self.treestore.get(iter, 0)1174 choice_or_tree, = self.treestore.get(iter, 0)
1166 parent_tree = choice_or_tree.parent1175 parent_tree = choice_or_tree.parent
1167 isSelected = self.treeview.get_selection().iter_is_selected(iter)1176 isSelected = self.treeview.get_selection().iter_is_selected(iter)
1168 sibling = self.treestore.iter_next(iter)1177 sibling = self.treestore.iter_next(iter)
11691178
1170 confirm = dialogs.prompt(self.main_window, "Are you sure you want to delete this node?")1179 if confirm:
1171 if confirm == gtk.RESPONSE_YES:1180 response = dialogs.prompt(self.main_window, "Are you sure you want to delete this node?")
1181
1182 # not A or B == A implies B
1183 if not confirm or response == gtk.RESPONSE_YES:
1172 parent_tree.delete_child_by_ref(choice_or_tree)1184 parent_tree.delete_child_by_ref(choice_or_tree)
1173 self.remove_children(iter)1185 self.remove_children(iter)
1174 self.treestore.remove(iter)1186 self.treestore.remove(iter)
11751187
=== modified file 'diamond/diamond/schema.py'
--- diamond/diamond/schema.py 2011-07-18 11:49:27 +0000
+++ diamond/diamond/schema.py 2011-07-28 13:56:32 +0000
@@ -142,10 +142,10 @@
142 return results142 return results
143143
144 def valid_node(self, eid):144 def valid_node(self, eid):
145 if isinstance(eid, tree.Tree):145 if isinstance(eid, tree.Tree) or isinstance(eid, choice.Choice):
146 eidtree = eid146 eidtree = eid
147 eid = eid.schemaname147 eid = eid.schemaname
148148
149 if eid == ":start":149 if eid == ":start":
150 try:150 try:
151 node = self.tree.xpath('/t:grammar/t:start', namespaces={'t': 'http://relaxng.org/ns/structure/1.0'})[0]151 node = self.tree.xpath('/t:grammar/t:start', namespaces={'t': 'http://relaxng.org/ns/structure/1.0'})[0]
@@ -162,12 +162,8 @@
162 node = self.to_tree(node)162 node = self.to_tree(node)
163 163
164 if eidtree is not None:164 if eidtree is not None:
165 if eidtree.parent is not None:
166 eidtree.parent.children.append(node)
167 eidtree.parent.children.remove(eidtree)
168 node.set_parent(eidtree.parent)
169 node.attrs = eidtree.attrs
170 node.cardinality = eidtree.cardinality165 node.cardinality = eidtree.cardinality
166 node.parent = eidtree.parent
171167
172 return node168 return node
173169
@@ -176,7 +172,7 @@
176 f = self.callbacks[tag]172 f = self.callbacks[tag]
177 facts = {}173 facts = {}
178 x = f(element, facts)174 x = f(element, facts)
179 return x175 return x
180176
181 #############################################177 #############################################
182 # Beginning of schema processing functions. #178 # Beginning of schema processing functions. #
@@ -389,20 +385,19 @@
389 if "schemaname" in facts:385 if "schemaname" in facts:
390 return386 return
391387
388 facts['schemaname'] = self.tree.getpath(element)
389
392 r = []390 r = []
393 children = self.choice_children(self.element_children(element))391 children = self.choice_children(self.element_children(element))
394 392
395 # bloody simplified RNG393 # bloody simplified RNG
396 if len(children) == 2:394 if len(children) == 2:
397 empty = [x for x in children if self.tag(x) == "empty"]395 empty = [x for x in children if self.tag(x) == "empty"]
398 nonempty = [x for x in children if self.tag(x) != "empty"]396 if empty:
399 if len(empty) > 0:397 nonempty = [x for x in children if self.tag(x) != "empty"]
400 tag = self.tag(nonempty[0])398 tag = self.tag(nonempty[0])
401 if tag == "oneOrMore":399 f = self.callbacks[tag]
402 return self.cb_oneormore(element, facts)400 return f(element, facts)
403 else:
404 f = self.callbacks[tag]
405 return f(element, facts)
406401
407 for child in children:402 for child in children:
408 newfacts = {}403 newfacts = {}
@@ -533,7 +528,7 @@
533528
534 xmlnode = doc.getroot()529 xmlnode = doc.getroot()
535 self.xml_read_merge(datatree, xmlnode)530 self.xml_read_merge(datatree, xmlnode)
536 self.xml_read_core(datatree, xmlnode, doc)531 self.xml_read_core(datatree.get_current_tree(), xmlnode, doc)
537532
538 if len(self.lost_eles) != 0:533 if len(self.lost_eles) != 0:
539 debug.deprint("WARNING: Lost XML elements:\n" + str(self.lost_eles))534 debug.deprint("WARNING: Lost XML elements:\n" + str(self.lost_eles))
@@ -564,7 +559,7 @@
564 xmlname = xmlnode.get("name")559 xmlname = xmlnode.get("name")
565 have_found = False560 have_found = False
566561
567 possibles = [tree_choice for tree_choice in datatree.choices() if tree_choice.name == xmlnode.tag]562 possibles = [tree_choice for tree_choice in datatree.get_choices() if tree_choice.name == xmlnode.tag]
568 # first loop over the fixed-value names563 # first loop over the fixed-value names
569 for tree_choice in possibles:564 for tree_choice in possibles:
570 if "name" not in tree_choice.attrs:565 if "name" not in tree_choice.attrs:
@@ -698,7 +693,7 @@
698693
699 for schemachild in priority_queue:694 for schemachild in priority_queue:
700 if schemachild.cardinality in ['', '?']:695 if schemachild.cardinality in ['', '?']:
701 for curtree in schemachild.choices():696 for curtree in schemachild.get_choices():
702 name = curtree.name697 name = curtree.name
703698
704 have_fixed_name = False699 have_fixed_name = False
@@ -725,7 +720,7 @@
725 xmls[schemachild.schemaname] = copy.deepcopy([])720 xmls[schemachild.schemaname] = copy.deepcopy([])
726 elif schemachild.cardinality in ['*', '+']:721 elif schemachild.cardinality in ['*', '+']:
727 xmls[schemachild.schemaname] = copy.deepcopy([])722 xmls[schemachild.schemaname] = copy.deepcopy([])
728 for curtree in schemachild.choices():723 for curtree in schemachild.get_choices():
729 name = curtree.name724 name = curtree.name
730725
731 have_fixed_name = False726 have_fixed_name = False
@@ -803,7 +798,7 @@
803 bins[schemachild.schemaname].append(child)798 bins[schemachild.schemaname].append(child)
804799
805 # search for neglected choices800 # search for neglected choices
806 if schemachild.__class__ is choice.Choice and schemachild.cardinality in ['', '?']:801 if isinstance(schemachild, choice.Choice) and schemachild.cardinality in ['', '?']:
807 for child in bins[schemachild.schemaname]:802 for child in bins[schemachild.schemaname]:
808803
809 # Does the child have a valid XML node attached?804 # Does the child have a valid XML node attached?
@@ -811,7 +806,7 @@
811 if child.xmlnode is None: continue806 if child.xmlnode is None: continue
812807
813 current_choice = child.get_current_tree()808 current_choice = child.get_current_tree()
814 for tree_choice in child.l:809 for tree_choice in child.get_choices():
815 if tree_choice is current_choice: continue810 if tree_choice is current_choice: continue
816811
817 return bins812 return bins
818813
=== modified file 'diamond/diamond/tree.py'
--- diamond/diamond/tree.py 2011-07-26 14:04:07 +0000
+++ diamond/diamond/tree.py 2011-07-28 13:56:32 +0000
@@ -266,7 +266,7 @@
266266
267 sub_tree=etree.Element(self.name)267 sub_tree=etree.Element(self.name)
268 268
269 for key in self.attrs.keys():269 for key in self.attrs:
270 val = self.attrs[key]270 val = self.attrs[key]
271 output_val = val[1]271 output_val = val[1]
272 if output_val is not None:272 if output_val is not None:
@@ -275,17 +275,9 @@
275 for child in self.children:275 for child in self.children:
276 if child.active is True:276 if child.active is True:
277 child.write_core(sub_tree)277 child.write_core(sub_tree)
278# else:
279# if child.cardinality == '?':
280# root=etree.Element(self.name)
281# child.write_core(root)
282# comment_buffer = StringIO.StringIO(etree.tostring(root))
283# comment_text = ("DIAMOND MAGIC COMMENT (inactive optional subtree %s):\n" % child.schemaname)
284# comment_text = comment_text + base64.b64encode(bz2.compress(comment_buffer.getvalue()))
285# sub_tree.append(etree.Comment(unicode(comment_text)))
286 278
287 if self.data is not None:279 if self.data is not None:
288 sub_tree.text=(unicode(self.data))280 sub_tree.text = unicode(self.data)
289 281
290 if parent is not None:282 if parent is not None:
291 parent.append(sub_tree)283 parent.append(sub_tree)
@@ -541,6 +533,9 @@
541533
542 def __str__(self):534 def __str__(self):
543 return self.get_display_name()535 return self.get_display_name()
544 536
537 def __repr__(self):
538 return self.get_name_path()
539
545gobject.type_register(Tree)540gobject.type_register(Tree)
546541

Subscribers

People subscribed via source and target branches