Mercurial > MadButterfly
comparison pyink/domview.py @ 1340:10d5f06f7566
Fix issue of shouting error when removing a node.
- It shout a Python traceback message when removing a node that is
referenced by a svg:use node.
- when the node been removed, the node would be duplicated. The
duplication was used to replace the svg:use one.
- The ID of inserted duplication is the same as duplicated node,
and modified to a new and unique ID.
- Original design of domview_monitor can not handle it.
- It is resolved by changing domview_monitor._id2node from single
mapping to multiple mapping one.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Sun, 06 Feb 2011 23:12:48 +0800 |
parents | 0b5ee9c90af7 |
children | 972d749b9656 |
comparison
equal
deleted
inserted
replaced
1339:20cf3e2a0a9d | 1340:10d5f06f7566 |
---|---|
626 self._on_remove_node, None) | 626 self._on_remove_node, None) |
627 dom_event.addEventListener(doc, 'DOMAttrModified', | 627 dom_event.addEventListener(doc, 'DOMAttrModified', |
628 self._on_attr_modified, None) | 628 self._on_attr_modified, None) |
629 pass | 629 pass |
630 | 630 |
631 ## \brief Add a node to id2node mapping. | |
632 # | |
633 # domview_monitor._id2node is a multiple mapping to map a key to | |
634 # multiple node. The reason that it is not a single mapping is | |
635 # Inkscape would insert a node with the ID from the node been | |
636 # copied, and change its ID to a unique one later. So, we must | |
637 # provide the capability to handle two or more nodes with the same | |
638 # ID. | |
639 def _map_id2node(self, node, node_id): | |
640 if node_id in self._id2node: | |
641 old_value = self._id2node[node_id] | |
642 if isinstance(old_value, list): | |
643 old_value.append(node) | |
644 else: | |
645 self._id2node[node_id] = [old_value, node] | |
646 pass | |
647 else: | |
648 self._id2node[node_id] = node | |
649 pass | |
650 pass | |
651 | |
652 def _unmap_id2node(self, node, node_id): | |
653 if node_id not in self._id2node: | |
654 raise ValueError, 'invalide node ID (%s)' % (node_id) | |
655 | |
656 value = self._id2node[node_id] | |
657 if isinstance(value, list): | |
658 value.remove(node) | |
659 if not value: | |
660 del self._id2node[node_id] | |
661 pass | |
662 pass | |
663 else: | |
664 del self._id2node[node_id] | |
665 pass | |
666 pass | |
667 | |
631 ## \brief Rescan the tree. | 668 ## \brief Rescan the tree. |
632 # | 669 # |
633 def _monitor_reparse(self): | 670 def _monitor_reparse(self): |
634 self._maxframe = 0 | 671 self._maxframe = 0 |
635 self._id2node = {} | 672 self._id2node = {} |
647 try: | 684 try: |
648 child_id = child.getAttribute('id') | 685 child_id = child.getAttribute('id') |
649 except: | 686 except: |
650 pass | 687 pass |
651 else: | 688 else: |
652 if child_id not in self._id2node: | 689 self._map_id2node(child, child_id) |
653 self._id2node[child_id] = child | |
654 pass | |
655 pass | 690 pass |
656 | 691 |
657 if child.name() == 'ns0:scene' and _id_eq(node, self._scenes_node): | 692 if child.name() == 'ns0:scene' and _id_eq(node, self._scenes_node): |
658 try: | 693 try: |
659 ref = child.getAttribute('ref') | 694 ref = child.getAttribute('ref') |
705 try: | 740 try: |
706 child_id = child.getAttribute('id') | 741 child_id = child.getAttribute('id') |
707 except: | 742 except: |
708 pass | 743 pass |
709 else: | 744 else: |
710 if child_id not in self._id2node: | 745 self._unmap_id2node(child, child_id) |
711 raise ValueError, \ | |
712 'remove a node that is never known (%s)' % (child_id) | |
713 del self._id2node[child_id] | |
714 pass | 746 pass |
715 | 747 |
716 if child.name() == 'ns0:scene' and _id_eq(node, self._scenes_node): | 748 if child.name() == 'ns0:scene' and _id_eq(node, self._scenes_node): |
717 try: | 749 try: |
718 ref = child.getAttribute('ref') | 750 ref = child.getAttribute('ref') |
735 def _on_attr_modified(self, node, name, old_value, new_value): | 767 def _on_attr_modified(self, node, name, old_value, new_value): |
736 if old_value == new_value: | 768 if old_value == new_value: |
737 return | 769 return |
738 | 770 |
739 if name == 'id': | 771 if name == 'id': |
740 if old_value and (old_value not in self._id2node): | 772 if old_value and old_value in self._id2node: |
741 raise ValueError, \ | 773 self._unmap_id2node(node, old_value) |
742 'old ID value of passed node is invalid one (%s)' % \ | |
743 (old_value) | |
744 if (new_value in self._id2node): | |
745 raise ValueError, \ | |
746 'new ID value of passed node is invalid one (%s)' % \ | |
747 (new_value) | |
748 | |
749 if old_value: | |
750 del self._id2node[old_value] | |
751 pass | 774 pass |
752 if new_value: | 775 if new_value: |
753 self._id2node[new_value] = node | 776 self._map_id2node(node, new_value) |
754 pass | 777 pass |
755 pass | 778 pass |
756 elif name == 'ref' and node.name() == 'ns0:scene': | 779 elif name == 'ref' and node.name() == 'ns0:scene': |
757 parent_node = node.parent() | 780 parent_node = node.parent() |
758 scenes_node = self._scenes_node | 781 scenes_node = self._scenes_node |
870 pass | 893 pass |
871 | 894 |
872 ## \brief Return the node with given ID. | 895 ## \brief Return the node with given ID. |
873 # | 896 # |
874 def get_node(self, node_id): | 897 def get_node(self, node_id): |
875 return self._id2node[node_id] | 898 value = self._id2node[node_id] |
899 if isinstance(value, list): | |
900 return value[-1] | |
901 return value | |
876 | 902 |
877 ## \brief Return a scene node corresponding to a scene group of given ID. | 903 ## \brief Return a scene node corresponding to a scene group of given ID. |
878 # | 904 # |
879 def get_scene(self, group_id): | 905 def get_scene(self, group_id): |
880 return self._group2scene[group_id] | 906 return self._group2scene[group_id] |