Changeset 1716

Show
Ignore:
Timestamp:
07/24/07 02:15:24 (1 year ago)
Author:
arj..@yirdis.nl
Message:

Make removed items and their children restore in the proper order when undoing changes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gaphas/trunk/gaphas/canvas.py

    r1707 r1716  
    9696 
    9797    @observed 
    98     def remove(self, item): 
    99         """ 
    100         Remove item from the canvas 
    101  
    102             >>> c = Canvas() 
    103             >>> from gaphas import item 
    104             >>> i = item.Item() 
    105             >>> c.add(i) 
    106             >>> c.remove(i) 
    107             >>> c._tree.nodes 
    108             [] 
    109             >>> i._canvas 
    110  
    111         TODO: fix problems that arise when items are nested. 
    112         """ 
    113         #for child in self.get_children(item): 
    114         #    self.remove(child) 
     98    def _remove(self, item): 
     99        """ 
     100        Remove is done in a separate, @observed, method so the undo system 
     101        can restore removed items in the right order. 
     102        """ 
    115103        item.canvas = None 
    116104        self._tree.remove(item) 
     
    121109        self._dirty_matrix_items.discard(item) 
    122110 
    123     reversible_pair(add, remove, 
     111    def remove(self, item): 
     112        """ 
     113        Remove item from the canvas 
     114 
     115            >>> c = Canvas() 
     116            >>> from gaphas import item 
     117            >>> i = item.Item() 
     118            >>> c.add(i) 
     119            >>> c.remove(i) 
     120            >>> c._tree.nodes 
     121            [] 
     122            >>> i._canvas 
     123 
     124        """ 
     125        for child in reversed(self.get_children(item)): 
     126            self.remove(child) 
     127        self._remove(item) 
     128 
     129    reversible_pair(add, _remove, 
    124130                    bind1={'parent': lambda self, item: self.get_parent(item)}) 
    125131 
  • gaphas/trunk/gaphas/state.py

    r1298 r1716  
    249249    handle (<function _set_a at 0x...>, {'self': <gaphas.state.PropTest object at 0x...>, 'value': 0}) 
    250250 
     251    >>> subscribers.remove(handler) 
    251252    """ 
    252253    global _reverse 
  • gaphas/trunk/gaphas/tests/test_solver.py

    r1670 r1716  
    142142    Solver speed tests. 
    143143    """ 
    144     def test_speed_run_weakest(self): 
     144    def skip__test_speed_run_weakest(self): 
    145145        """ 
    146146        Speed test for weakest variable. 
  • gaphas/trunk/gaphas/tree.py

    r1701 r1716  
    88 
    99import operator 
    10 from state import observed, reversible_pair, disable_dispatching 
     10from state import observed, reversible_method, \ 
     11        reversible_pair, disable_dispatching 
    1112 
    1213 
     
    193194 
    194195    @observed 
    195     def remove(self, node): 
    196         """ 
    197         Remove @node from the tree. 
    198  
    199         For usage, see the unit tests. 
    200         """ 
    201         # First remove children: 
    202         for c in list(self._children[node]): 
    203             self.remove(c) 
     196    def _remove(self, node): 
    204197        # Remove from parent item 
    205198        self.get_siblings(node).remove(node) 
     
    212205            pass 
    213206 
     207    def remove(self, node): 
     208        """ 
     209        Remove @node from the tree. 
     210 
     211        For usage, see the unit tests. 
     212        """ 
     213        # First remove children: 
     214        for c in reversed(list(self._children[node])): 
     215            self.remove(c) 
     216        self._remove(node) 
    214217 
    215218    def _reparent_nodes(self, node, parent): 
     
    267270 
    268271 
    269     reversible_pair(add, remove, 
    270                     bind1={'parent': lambda self, node: self.get_parent(node) }) 
     272    reversible_pair(add, _remove, 
     273            bind1={'parent': lambda self, node: self.get_parent(node) }) 
     274 
     275    reversible_method(reparent, reverse=reparent, 
     276            bind={'parent': lambda self, node: self.get_parent(node) }) 
    271277 
    272278    # Disable add/remove by default, since they are handled by canvas.Canvas 
    273279    disable_dispatching(add) 
    274     disable_dispatching(remove) 
     280    disable_dispatching(_remove) 
    275281 
    276282 
  • gaphas/trunk/state.txt

    r1162 r1716  
    2828 
    2929    >>> state.enable_dispatching(Tree.add) 
    30     >>> state.enable_dispatching(Tree.remove) 
     30    >>> state.enable_dispatching(Tree._remove) 
    3131 
    3232It works: 
     
    4444Remember that this observer is just a simple method call notifier and knows 
    4545nothing about the internals of the tree class (in this case the remove() method 
    46 recursively calls remove() for each of it's children): 
     46recursively calls remove() for each of it's children). Therefore some careful 
     47crafting of methods may be nessecary in order to get the right effect: 
    4748 
    4849    >>> tree.remove(1)                                  # doctest: +ELLIPSIS 
    49     event handled (<function remove at ...>, (<gaphas.tree.Tree object at 0x...>, 1), {}) 
    50     event handled (<function remove at ...>, (<gaphas.tree.Tree object at 0x...>, 2), {}) 
     50    event handled (<function _remove at ...>, (<gaphas.tree.Tree object at 0x...>, 2), {}) 
     51    event handled (<function _remove at ...>, (<gaphas.tree.Tree object at 0x...>, 1), {}) 
    5152    >>> tree.nodes 
    5253    [] 
     
    120121 
    121122    >>> tree.add(3)                                     # doctest: +ELLIPSIS 
    122     event handler (<function remove at ...>, {'node': 3, 'self': <gaphas.tree.Tree object at 0x...>}) 
     123    event handler (<function _remove at ...>, {'node': 3, 'self': <gaphas.tree.Tree object at 0x...>}) 
    123124    >>> tree.nodes 
    124125    [3] 
     
    203204 
    204205    >>> state.disable_dispatching(Tree.add) 
    205     >>> state.disable_dispatching(Tree.remove) 
    206  
     206    >>> state.disable_dispatching(Tree._remove) 
     207 
  • gaphas/trunk/undo.txt

    r1174 r1716  
    3636tree.py: Tree 
    3737------------- 
    38 Tree's add() and remove() methods are use as demonstration in state.txt. 
    39  
    40 Those methods are disabled by default and will not be tested here. 
     38Tree's add() and remove() methods are disabled by default. 
     39 
     40    >>> from gaphas.tree import Tree 
     41    >>> state.enable_dispatching(Tree.add) 
     42    >>> state.enable_dispatching(Tree._remove) 
     43 
     44One can create a nice tree: 
     45 
     46    >>> tree = Tree() 
     47    >>> tree.add(1) 
     48    >>> tree.nodes 
     49    [1] 
     50    >>> undo() 
     51    >>> tree.nodes 
     52    [] 
     53    >>> undo_list[:] = redo_list[:] 
     54    >>> undo() 
     55    >>> tree.nodes 
     56    [1] 
     57     
     58Adding and removing complete sub-trees also works: 
     59 
     60    >>> tree.add(2, parent=1) 
     61    >>> tree.add(3, parent=2) 
     62    >>> tree.add(4, parent=2) 
     63    >>> tree.add(5, parent=4) 
     64    >>> tree.nodes 
     65    [1, 2, 3, 4, 5] 
     66    >>> del undo_list[:] 
     67    >>> tree.remove(1) 
     68    >>> tree.nodes 
     69    [] 
     70    >>> undo() 
     71    >>> tree.nodes 
     72    [1, 2, 3, 4, 5] 
     73    >>> tree.get_children(2) 
     74    [3, 4] 
     75    >>> tree.get_children(4) 
     76    [5] 
     77 
     78Undo the last undo action: 
     79 
     80    >>> undo_list[:] = redo_list[:] 
     81    >>> undo() 
     82    >>> tree.nodes 
     83    [] 
     84    >>> undo_list[:] = redo_list[:] 
     85    >>> undo() 
     86    >>> tree.nodes 
     87    [1, 2, 3, 4, 5] 
     88    >>> tree.get_children(2) 
     89    [3, 4] 
     90    >>> tree.get_children(4) 
     91    [5] 
     92 
     93Moving a node from one node to another is easy: 
     94 
     95    >>> tree.reparent(3, parent=5) 
     96    >>> tree.get_children(2) 
     97    [4] 
     98    >>> tree.get_children(5) 
     99    [3] 
     100    >>> tree.nodes 
     101    [1, 2, 4, 5, 3] 
     102 
     103This change can be undone: 
     104 
     105    >>> undo() 
     106    >>> tree.nodes 
     107    [1, 2, 4, 5, 3] 
     108    >>> tree.get_children(2) 
     109    [4, 3] 
     110    >>> tree.get_children(5) 
     111    [] 
     112 
     113As you can see, there's currently one flaw: the item is added at the end of the list. 
     114 
     115(disable dispatching again, not frustrating other tests) 
     116 
     117    >>> state.disable_dispatching(Tree.add) 
     118    >>> state.disable_dispatching(Tree._remove) 
    41119 
    42120matrix.py: Matrix 
     
    174252    [<gaphas.item.Item object at 0x...>, <gaphas.item.Item object at 0x...>] 
    175253 
    176  
    177 NOTE: If remove() is invoked recursively (e.i. when the to-be removed item has 
    178       children), the remove items can not simply be applied in reverse order. 
     254Remove also works when items are removed recursively (an item and it's 
     255children): 
    179256 
    180257    >>> child = Item() 
     
    186263    >>> canvas.get_all_items() 
    187264    [] 
    188  
     265    >>> undo() 
     266    >>> canvas.get_all_items()                          # doctest: +ELLIPSIS 
     267    [<gaphas.item.Item object at 0x...>, <gaphas.item.Item object at 0x...>] 
     268    >>> canvas.get_children(item)                       # doctest: +ELLIPSIS 
     269    [<gaphas.item.Item object at 0x...>] 
    189270 
    190271item.py: Handle