Changeset 1973

Show
Ignore:
Timestamp:
08/19/07 13:15:19 (1 year ago)
Author:
arj..@yirdis.nl
Message:

first attempt for new style namespace model.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gaphor/trunk/gaphor/ui/namespace.py

    r1314 r1973  
    1313from gaphor import UML 
    1414from gaphor.UML.event import ModelFactoryEvent, FlushFactoryEvent 
     15from gaphor.UML.event import IElementCreateEvent, IElementDeleteEvent 
     16from gaphor.UML.event import AssociationSetEvent 
    1517from gaphor.transaction import Transaction 
    1618 
     
    372374 
    373375 
     376 
     377class NewNamespaceModel(gtk.GenericTreeModel): 
     378 
     379 
     380    def __init__(self, factory): 
     381        # Init parent: 
     382        gtk.GenericTreeModel.__init__(self) 
     383 
     384        # We own the references to the iterators. 
     385        self.set_property ('leak_references', 0) 
     386 
     387        self.factory = factory 
     388 
     389        self._nodes = { None: [] } 
     390 
     391        self.exclude = _default_exclude_list 
     392 
     393        #component.provideHandler(self.flush) 
     394        #component.provideHandler(self._build_model) 
     395        component.provideHandler(self._on_element_create) 
     396        component.provideHandler(self._on_element_delete) 
     397        component.provideHandler(self._on_association_set) 
     398 
     399    def path_from_element(self, e): 
     400        if e: 
     401            ns = e.namespace 
     402            n = self._nodes[ns] 
     403            try: 
     404                return self.path_from_element(ns) + (n.index(e),) 
     405            except ValueError: 
     406                print 'falied:', n, ns 
     407        else: 
     408            return () 
     409 
     410    def element_from_path(self, path): 
     411        """ 
     412        Get the node form a path. None is returned if no node is found. 
     413        """ 
     414        try: 
     415            node = self._nodes[None] 
     416            for index in path: 
     417                node = node[index] 
     418            return node 
     419        except IndexError: 
     420            return None 
     421        #    print 'No path to node %s' % path 
     422 
     423    @component.adapter(IElementCreateEvent) 
     424    def _on_element_create(self, event): 
     425        if event.service is self.factory: 
     426            log.debug('adding node %s' % event.element) 
     427            e = event.element 
     428            self._nodes[e] = [] 
     429            # self.insert() 
     430            parent = self._nodes[e.namespace] 
     431            parent.append(e) 
     432            print 'nodes', e.namespace,  parent 
     433            path = self.path_from_element(e) 
     434            self.row_inserted(path, self.get_iter(path)) 
     435            # TODO: add child nodes 
     436 
     437    @component.adapter(IElementDeleteEvent) 
     438    def _on_element_delete(self, event): 
     439        if event.service is self.factory: 
     440            log.debug('deleting node %s' % event.element) 
     441            e = event.element 
     442            path = self.path_from_element(e) 
     443            def remove(n): 
     444                for c in self._nodes[n]: 
     445                    remove(c) 
     446                del self._nodes[n] 
     447            remove(e) 
     448            self.row_deleted(path) 
     449 
     450    @component.adapter(AssociationSetEvent) 
     451    def _on_association_set(self, event): 
     452        print ('assocation set %s' % event.property) 
     453        if event.property is UML.NamedElement.namespace: 
     454            e = event.element 
     455            if not self._nodes.has_key(e): 
     456                return 
     457            old_value, new_value = event.old_value, event.new_value 
     458            path = self.path_from_element(old_value) + self._nodes[old_value].index(e) 
     459            self.row_deleted(path) 
     460            self._nodes[old_value].remove(e) 
     461 
     462            parent = self._nodes[e.namespace] 
     463            parent.append(e) 
     464            print 'set nodes', e.namespace,  parent 
     465            path = self.path_from_element(e) 
     466            self.row_inserted(path, self.get_iter(path)) 
     467 
     468    @component.adapter(FlushFactoryEvent) 
     469    def flush(self, event=None): 
     470        for i in self._nodes[None]: 
     471            self.row_deleted((0,)) 
     472        self._nodes = {None: []} 
     473 
     474    @component.adapter(ModelFactoryEvent) 
     475    def _build_model(self, event=None): 
     476        toplevel = self.factory.select(lambda e: isinstance(e, UML.Namespace) and not e.namespace) 
     477 
     478        for t in toplevel: 
     479            self.new_node_from_element(t, self.root) 
     480 
     481    # TreeModel methods: 
     482 
     483    def on_get_flags(self): 
     484        """ 
     485        Returns the GtkTreeModelFlags for this particular type of model. 
     486        """ 
     487        return 0 
     488 
     489    def on_get_n_columns(self): 
     490        """ 
     491        Returns the number of columns in the model. 
     492        """ 
     493        return 1 
     494 
     495    def on_get_column_type(self, index): 
     496        """ 
     497        Returns the type of a column in the model. 
     498        """ 
     499        return gobject.TYPE_PYOBJECT 
     500 
     501    def on_get_path(self, node): 
     502        """ 
     503        Returns the path for a node as a tuple (0, 1, 1). 
     504        """ 
     505        return self.path_from_element(node) 
     506 
     507    def on_get_iter(self, path): 
     508        """ 
     509        Returns the node corresponding to the given path. 
     510        The path is a tuple of values, like (0 1 1). Returns None if no 
     511        iterator can be created. 
     512        """ 
     513        return self.element_from_path(path) 
     514 
     515    def on_get_value(self, node, column): 
     516        """ 
     517        Returns the model element that matches 'node'. 
     518        """ 
     519        assert column == 0, 'column can only be 0' 
     520        return node 
     521 
     522    def on_iter_next(self, node): 
     523        """ 
     524        Returns the next node at this level of the tree. None if no 
     525        next element. 
     526        """ 
     527        try: 
     528            parent = self._nodes[node.namespace] 
     529            index = parent.index(node) 
     530            return parent[index + 1] 
     531        except IndexError, e: 
     532            #print 'error: on_next_iter', e, parent 
     533            #import traceback 
     534            #traceback.print_exc() 
     535            return None 
     536         
     537    def on_iter_has_child(self, node): 
     538        """ 
     539        Returns true if this node has children, or None. 
     540        """ 
     541        return len(self._nodes[node]) > 0 
     542 
     543    def on_iter_children(self, node): 
     544        """ 
     545        Returns the first child of this node, or None. 
     546        """ 
     547        return self._nodes[node][0] 
     548 
     549    def on_iter_n_children(self, node): 
     550        """ 
     551        Returns the number of children of this node. 
     552        """ 
     553        return len(self._nodes[node]) 
     554 
     555    def on_iter_nth_child(self, node, n): 
     556        """ 
     557        Returns the nth child of this node. 
     558        """ 
     559        try: 
     560            nodes = self._nodes[node] 
     561            return nodes[n] 
     562        except TypeError, e: 
     563            #print e, node, n 
     564            #import traceback 
     565            #traceback.print_exc() 
     566            return None 
     567 
     568    def on_iter_parent(self, node): 
     569        """ 
     570        Returns the parent of this node or None if no parent 
     571        """ 
     572        #print "on_iter_parent", node 
     573        return node.namespace 
     574 
     575 
    374576class NamespaceView(gtk.TreeView): 
    375577 
  • gaphor/trunk/gaphor/ui/tests/test_namespace.py

    r1955 r1973  
    33from gaphor.tests.testcase import TestCase 
    44import gaphor.UML as UML 
    5 from gaphor.ui.namespace import NamespaceModel 
     5from gaphor.ui.namespace import NamespaceModel, NewNamespaceModel 
    66from gaphor.application import Application 
    77 
     
    117117        print UML.Package.ownedClassifier 
    118118 
     119 
     120class NewNamespaceTestCase(TestCase): 
     121 
     122    services = [ 'element_factory' ] 
     123 
     124    def test(self): 
     125        factory = Application.get_service('element_factory') 
     126 
     127        ns = NewNamespaceModel(factory) 
     128 
     129        m = factory.create(UML.Package) 
     130        m.name = 'm' 
     131        assert ns._nodes.has_key(m) 
     132        assert ns.path_from_element(m) == (0,) 
     133        assert ns.element_from_path((0,)) is m 
     134 
     135        a = factory.create(UML.Package) 
     136        a.name = 'a' 
     137        assert a in ns._nodes 
     138        assert m in ns._nodes 
     139        assert ns.path_from_element(a) == (1,)  
     140 
     141        a.package = m 
     142        assert a in ns._nodes 
     143        assert a in ns._nodes[m] 
     144        assert m in ns._nodes 
     145        assert a.package is m 
     146        assert a in m.ownedMember 
     147        assert a.namespace is m 
     148        assert ns.path_from_element(a) == (0, 0), ns.path_from_element(a) 
     149 
    119150if __name__ == '__main__': 
    120151    import unittest