| | 376 | |
|---|
| | 377 | class 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 | |
|---|