Changeset 1170

Show
Ignore:
Timestamp:
03/21/07 00:45:08 (1 year ago)
Author:
arjanmol
Message:

Start of services package. Services should be defined here and be registered through entry_points in the Egg-info files. Result is a more tight dependency to zope.component, since services are registered as utilities in the global registry.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gaphor/trunk/gaphor/UML/elementfactory.py

    r1121 r1170  
    33""" 
    44 
     5from zope import interface 
    56from zope import component 
    67from gaphor.misc import uniqueid, odict 
     
    89from gaphor.UML.element import Element 
    910from gaphor.UML.diagram import Diagram 
     11from gaphor.UML.interfaces import ICreateElementEvent, IRemoveElementEvent, \ 
     12                                  IFlushFactoryEvent, IModelFactoryEvent, \ 
     13                                  IService 
    1014from gaphor.UML.event import CreateElementEvent, RemoveElementEvent, \ 
    1115                             FlushFactoryEvent, ModelFactoryEvent 
    1216 
    1317 
    14 class _UndoCreateAction(object): 
     18class _xxUndoCreateAction(object): 
    1519 
    1620    def __init__(self, factory, element): 
     
    3236 
    3337 
    34 class _UndoRemoveAction(object): 
     38class _xxUndoRemoveAction(object): 
    3539 
    3640    def __init__(self, factory, element): 
     
    6165            (element is None) 
    6266    """ 
     67    interface.implements(IService) 
    6368 
    6469    def __init__(self): 
     
    7883        obj = type(id, self) 
    7984        self._elements[id] = obj 
    80         get_undo_manager().add_undo_action(_UndoCreateAction(self, obj)) 
    81         obj.connect('__unlink__', self.__element_signal) 
     85        #get_undo_manager().add_undo_action(_UndoCreateAction(self, obj)) 
     86        obj.connect('__unlink__', self._element_signal) 
    8287        self.notify(obj, 'create') 
    8388        component.handle(CreateElementEvent(self, obj)) 
     
    197202        component.handle(ModelFactoryEvent(self)) 
    198203 
    199     def __element_signal(self, element, pspec): 
     204    def _element_signal(self, element, pspec): 
    200205        """Remove an element from the factory """ 
    201206        #log.debug('element %s send signal %s' % (element, name)) 
     
    204209            # TODO: make undo action 
    205210            del self._elements[element.id] 
    206             get_undo_manager().add_undo_action(_UndoRemoveAction(self, element)) 
     211            #get_undo_manager().add_undo_action(_UndoRemoveAction(self, element)) 
    207212            self.notify(element, 'remove') 
    208213            component.handle(RemoveElementEvent(self, element)) 
     
    212217#            self.notify(element, 'create') 
    213218 
     219component.provideUtility(ElementFactory(), IService, "element_factory") 
     220 
     221 
     222@component.adapter(ICreateElementEvent) 
     223def undo_create_event(event): 
     224    factory = event.service 
     225    element = event.element 
     226    def _undo_create_event(): 
     227        try: 
     228            del factory._elements[element.id] 
     229        except KeyError: 
     230            pass # Key was probably already removed in an unlink call 
     231        factory.notify(element, 'remove') 
     232        component.handle(RemoveElementEvent(factory, element)) 
     233    get_undo_manager().add_undo_action(_undo_create_event) 
     234 
     235component.provideHandler(undo_create_event) 
     236 
     237 
     238@component.adapter(IRemoveElementEvent) 
     239def undo_remove_event(event): 
     240    factory = event.service 
     241    element = event.element 
     242    def _undo_remove_event(): 
     243        factory._elements[element.id] = element 
     244        factory.notify(element, 'create') 
     245        component.handle(CreateElementEvent(factory, element)) 
     246    get_undo_manager().add_undo_action(_undo_remove_event) 
     247 
     248component.provideHandler(undo_remove_event) 
     249 
     250 
     251# vim:sw=4:et 
  • gaphor/trunk/gaphor/UML/event.py

    r1121 r1170  
    2626    interface.implements(ICreateElementEvent) 
    2727 
    28     def __init__(self, factory, element): 
    29         self.factory = factory 
     28    def __init__(self, service, element): 
     29        self.service = service 
    3030        self.element = element 
    3131 
     
    3434    interface.implements(IRemoveElementEvent) 
    3535 
    36     def __init__(self, factory, element): 
    37         self.factory = factory 
     36    def __init__(self, service, element): 
     37        self.service = service 
    3838        self.element = element 
    3939 
     
    4242    interface.implements(IModelFactoryEvent) 
    4343 
    44     def __init__(self, factory): 
    45         self.factory = factory 
     44    def __init__(self, service): 
     45        self.service = service 
    4646 
    4747 
     
    4949    interface.implements(IFlushFactoryEvent) 
    5050 
    51     def __init__(self, factory): 
    52         self.factory = factory 
     51    def __init__(self, service): 
     52        self.service = service 
    5353 
  • gaphor/trunk/gaphor/UML/interfaces.py

    r1121 r1170  
    44 
    55from zope import interface 
    6  
     6from gaphor.interfaces import IService, IServiceEvent 
    77 
    88class IElementChangedEvent(interface.Interface): 
     
    2525 
    2626 
    27 class IFactoryEvent(interface.Interface): 
    28     """Events related to creation/deletion of model elements. 
    29     """ 
    30     factory = interface.Attribute("The ElementFactory emiting the event") 
    31  
    32  
    33 class IModelFactoryEvent(IFactoryEvent): 
     27class IModelFactoryEvent(IServiceEvent): 
    3428    """A new model is loaded into the ElementFactory. 
    3529    """ 
    3630 
    3731 
    38 class IFlushFactoryEvent(IFactoryEvent): 
     32class IFlushFactoryEvent(IServiceEvent): 
    3933    """All elements are removed from the ElementFactory. 
    4034    """ 
    4135 
    4236 
    43 class IFactoryElementEvent(IFactoryEvent): 
     37class IFactoryElementEvent(IServiceEvent): 
    4438    """Events related to individual model elements. 
    4539    """ 
  • gaphor/trunk/gaphor/UML/tests/test_elementfactory.py

    r1121 r1170  
    1414last_event = None 
    1515 
    16 @component.adapter(IFactoryEvent) 
     16@component.adapter(IServiceEvent) 
    1717def handler(event): 
    1818    global handled, events, last_event 
     
    111111        self.assertTrue(IFlushFactoryEvent.providedBy(last_event) ) 
    112112 
     113    def testUndo(self): 
     114        pass 
     115        # TODO: implement 
     116        from gaphor.services.undomanager import get_undo_manager 
     117        get_undo_manager().begin_transaction() 
     118        ef = self.factory 
     119        p = ef.create(Parameter) 
     120 
     121        assert get_undo_manager().can_undo() 
     122        get_undo_manager().commit_transaction() 
     123        assert get_undo_manager().can_undo() 
     124        assert ef.size() == 1 
     125        get_undo_manager().undo_transaction() 
     126        assert not get_undo_manager().can_undo() 
     127        assert get_undo_manager().can_redo() 
     128 
  • gaphor/trunk/gaphor/__init__.py

    r1135 r1170  
    3131                    }) 
    3232 
     33 
    3334class GaphorError(Exception): 
    3435    """ 
     
    5051    import actions 
    5152    # Load plugin definitions: 
    52     import pluginmanager 
     53    import services.pluginmanager 
     54    import services.undomanager 
     55 
    5356    from ui.mainwindow import MainWindow 
    5457 
  • gaphor/trunk/gaphor/actions/diagramactions.py

    r1132 r1170  
    3535 
    3636register_action(CloseTabAction) 
    37  
    38  
    39 class UndoStackAction(Action): 
    40     """Dummy action that triggers the undo and redo actions to update 
    41     themselves. 
    42     """ 
    43     id = 'EditUndoStack' 
    44      
    45     def init(self, window): 
    46         pass 
    47  
    48 register_action(UndoStackAction) 
    49  
    50  
    51 class UndoAction(Action): 
    52     id = 'EditUndo' 
    53     stock_id = 'gtk-undo' 
    54     label = '_Undo' 
    55     tooltip = 'Undo the most recent changes' 
    56     accel = 'C-z' 
    57  
    58     # TODO: check if the diagram can undo. 
    59  
    60     def init(self, window): 
    61         self._window = window 
    62  
    63     def update(self): 
    64         diagram_tab = self._window.get_current_diagram_tab() 
    65         self.sensitive = diagram_tab and get_undo_manager().can_undo() 
    66  
    67     def execute(self): 
    68         get_undo_manager().undo_transaction() 
    69         self.update() 
    70         self._window.execute_action('EditUndoStack') 
    71  
    72 register_action(UndoAction, 'EditUndoStack') 
    73  
    74  
    75 class RedoAction(Action): 
    76     id = 'EditRedo' 
    77     stock_id = 'gtk-redo' 
    78     tooltip = 'Redo the undone changes' 
    79     accel = 'C-r' 
    80  
    81     def init(self, window): 
    82         self._window = window 
    83  
    84     def update(self): 
    85         diagram_tab = self._window.get_current_diagram_tab() 
    86         self.sensitive = diagram_tab and get_undo_manager().can_redo() 
    87  
    88     def execute(self): 
    89         get_undo_manager().redo_transaction() 
    90         self.update() 
    91         self._window.execute_action('EditUndoStack') 
    92  
    93 register_action(RedoAction, 'EditUndoStack') 
    94  
    9537 
    9638class ToolChangeAction(Action): 
  • gaphor/trunk/gaphor/actions/mainactions.py

    r1121 r1170  
    600600 
    601601class UndoStackAction(Action): 
    602     """Dummy action that triggers the undo and redo actions to update 
     602    """ 
     603    Dummy action that triggers the undo and redo actions to update 
    603604    themselves. 
    604605    """ 
     
    627628    def execute(self): 
    628629        get_undo_manager().undo_transaction() 
    629         #self.update() 
     630        self.update() 
    630631        self._window.execute_action('UndoStack') 
    631632 
  • gaphor/trunk/gaphor/diagram/__init__.py

    r1135 r1170  
    9090 
    9191 
     92## 
     93## Direct revert-statements from gaphas to the undomanager 
     94### 
     95 
     96from gaphas import state 
     97from gaphor.undomanager import get_undo_manager, transactional 
     98 
     99print 'state', state 
     100state.observers.add(state.revert_handler) 
     101 
     102def _undo_handler(event): 
     103    get_undo_manager().add_undo_action(lambda: state.saveapply(*event)); 
     104 
     105state.subscribers.add(_undo_handler) 
     106 
    92107# vim:sw=4:et 
  • gaphor/trunk/gaphor/event.py

    r610 r1170  
    22from gaphor.interfaces import * 
    33 
    4 class DiagramItemFocused(object): 
    5     interface.implements(IDiagramElementReceivedFocus) 
    6      
    7     def __init__(self, diagramItem): 
    8         self.diagramItem = diagramItem 
  • gaphor/trunk/gaphor/interfaces.py

    r1121 r1170  
     1""" 
     2Top level interface definitions for Gaphor. 
     3""" 
     4 
    15from zope import interface 
    2 from zope import component 
    3 class IGaphorAction(interface.Interface): 
    4     """Action interface for use in Gaphor""" 
    56 
    6 class IMenuAction(interface.Interface): 
    7     """An interface to hook up items to.""" 
    8      
    97 
    10 class TestAdapter(object): 
    11     def __init__(self, context): 
    12         self.context = context 
     8class IService(interface.Interface): 
     9    """ 
     10    Base interface for all services in Gaphor. 
     11    """ 
    1312 
    14 #component.provideAdapter( 
    15     #factory=TestAdapter, 
    16     #adapts=[IGaphorAction], 
    17     #provides=IZopeMenu, 
    18     #name="Test adapter name") 
     13    def init(self, application): 
     14        """ 
     15        Initialize the service, this method is called after all services 
     16        are instantiated. 
     17        """ 
    1918 
    20 #class TestAdapter2(object): 
    21     #def __init__(self, context): 
    22         #self.context = context 
    2319 
    24 #component.provideAdapter( 
    25     #factory=TestAdapter2, 
    26     #adapts=[IGaphorAction], 
    27     #provides=IZopeMenu, 
    28     #name="Test adapter 2 name") 
     20class IServiceEvent(interface.Interface): 
     21    """ 
     22    An event emitted by a service. 
     23    """ 
     24    service = interface.Attribute("The service that emits the event") 
    2925 
    30 #class TestAction(object): 
    31     #interface.implements(IGaphorAction) 
    32      
    33 class IDiagramElementReceivedFocus(interface.Interface): 
    34     """A diagram item received focus""" 
    35     diagramItem = interface.Attribute("The diagram item that received focus") 
    36      
    37      
    38 class IWidget(interface.Interface): 
    39     """A GTK widget""" 
    40      
    41 class IDetailsPage(IWidget): 
    42     """A property page which can display itself in a notebook""" 
    43      
     26 
     27# vim:sw=4:et 
  • gaphor/trunk/gaphor/services/pluginmanager.py

    r1135 r1170  
    2222User provided plugins overrule the system provided plugins. 
    2323""" 
     24import imp 
    2425import os 
    25 import imp 
    2626import os.path 
    2727import glob 
    2828import sys 
    2929from xml.sax import handler, make_parser 
     30 
     31from zope import interface 
     32from gaphor.interfaces import IService 
     33 
    3034from gaphor import resource 
    31  
    3235from gaphor.parser import ParserException 
    3336from gaphor.misc.action import register_action_for_slot 
    3437from gaphor.misc.odict import odict 
     38 
    3539 
    3640XMLNS='http://gaphor.sourceforge.net/gaphor/plugin' 
     
    4953    A plugin represents one plugin loaded from the file system. 
    5054    """ 
     55    interface.implements(IService) 
    5156 
    5257    def __init__(self): 
     
    6065        self.module = None 
    6166        self.status = '' 
     67 
     68    def init(self, app): 
     69        self._app = app 
    6270 
    6371    def requirements_met(self, manager): 
  • gaphor/trunk/gaphor/services/undomanager.py

    r1135 r1170  
    1515""" 
    1616 
     17from zope import interface 
     18from zope import component 
     19from gaphor.interfaces import IService, IServiceEvent 
    1720 
    1821def get_undo_manager(): 
     
    4144 
    4245 
    43 class undoableproperty(object): 
    44     """ 
    45     Property with state preservation. 
    46     Set and del statements preserve the original value before the operation 
    47     is performed 
    48     """ 
    49  
    50     def __init__(self, fget=None, fset=None, fdel=None, doc=None, 
    51                  property=None, undo_manager=None): 
    52         if property: 
    53             self.fget = property.fget 
    54             self.fset = property.fset 
    55             self.fdel = property.fdel 
    56             self.__doc__ = property.__doc__ 
    57         else: 
    58             self.fget = fget 
    59             self.fset = fset 
    60             self.fdel = fdel 
    61             self.__doc__ = doc 
    62         self._undo_manager = undo_manager or get_undo_manager() 
    63  
    64     def _preserve_state(self, obj): 
    65         try: 
    66             val = self.__get__(obj) 
    67         except AttributeError: 
    68             def _del_action(): 
    69                 action = self._preserve_state(obj) 
    70                 self.__delete__(obj) 
    71                 return action 
    72             return _del_action 
    73         else: 
    74             def _set_action(): 
    75                 action = self._preserve_state(obj) 
    76                 self.__set__(obj, val) 
    77                 return action 
    78             return _set_action 
    79  
    80     def __get__(self, obj, class_=None): 
    81         if obj: 
    82             return self.fget(obj) 
    83         return self.fget 
    84  
    85     def __set__(self, obj, value): 
    86         self._undo_manager.add_undo_action(self._preserve_state(obj)) 
    87         return self.fset(obj, value) 
    88  
    89     def __delete__(self, obj): 
    90         self._undo_manager.add_undo_action(self._preserve_state(obj)) 
    91         return self.fdel(obj) 
    92  
    93  
    9446class TransactionError(Exception): 
    9547 
     
    11668        return self._actions and True or False 
    11769 
     70    @transactional 
    11871    def execute(self): 
    11972        self._actions.reverse() 
    120         contra_transaction = Transaction() 
    12173        for action in self._actions: 
    12274            try: 
    123                 contra_action = action() 
    124                 contra_transaction.add(contra_action or action) 
     75                action() 
    12576            except Exception, e: 
    12677                log.error('Error while undoing action %s' % action, e) 
    127         return contra_transaction 
     78 
     79 
     80class UndoManagerStateChanged(object): 
     81    """ 
     82    Event class used to send state changes on the ndo Manager. 
     83    """ 
     84    interface.implements(IServiceEvent) 
     85 
     86    def __init__(self, service): 
     87        self.service = service 
     88 
    12889 
    12990class UndoManager(object): 
     
    13899    """ 
    139100 
     101    interface.implements(IService) 
     102 
    140103    def __init__(self): 
    141         self._in_undo = False 
    142104        self._undo_stack = [] 
    143105        self._redo_stack = [] 
     
    146108        self._transaction_depth = 0 
    147109 
     110    def init(self, app): 
     111        self._app = app 
     112 
    148113    def clear_undo_stack(self): 
    149114        self._undo_stack = [] 
     
    157122        Add an action to the current transaction 
    158123        """ 
    159         if self._in_undo: 
    160             return 
    161  
    162         #log.debug('begin_transaction') 
    163124        if self._current_transaction: 
    164125            self._transaction_depth += 1 
     
    182143 
    183144        self._current_transaction.add(action) 
     145        component.handle(UndoManagerStateChanged(self)) 
    184146 
    185147    def commit_transaction(self): 
    186         if self._in_undo: 
    187             return 
    188  
    189148        #log.debug('commit_transaction') 
    190149        if not self._current_transaction: 
     
    204163        Roll back the transaction we're in. 
    205164        """ 
    206         if self._in_undo: 
    207             return 
    208  
    209165        if not self._current_transaction: 
    210166            raise TransactionError, 'No transaction to rollback' 
     
    215171            self._current_transaction = None 
    216172        # else: mark for rollback? 
     173        component.handle(UndoManagerStateChanged(self)) 
    217174 
    218175    def discard_transaction(self): 
    219         if self._in_undo: 
    220             return 
    221176 
    222177        if not self._current_transaction: 
     
    226181        if self._transaction_depth == 0: 
    227182            self._current_transaction = None 
     183        component.handle(UndoManagerStateChanged(self)) 
    228184 
    229185    def undo_transaction(self): 
     
    235191            self.commit_transaction() 
    236192        transaction = self._undo_stack.pop() 
    237         try: 
    238             self._in_undo = True 
    239             redo_transaction = transaction.execute() 
    240         finally: 
    241             self._in_undo = False 
    242         self._redo_stack.append(redo_transaction) 
     193 
     194        transaction.execute() 
     195        component.handle(UndoManagerStateChanged(self)) 
    243196 
    244197    def redo_transaction(self): 
     
    247200 
    248201        transaction = self._redo_stack.pop() 
    249         try: 
    250             self._in_undo = True 
    251             undo_transaction = transaction.execute() 
    252         finally: 
    253             self._in_undo = False 
    254         self._undo_stack.append(undo_transaction) 
     202 
     203        transaction.execute() 
     204        component.handle(UndoManagerStateChanged(self)) 
    255205 
    256206    def in_transaction(self): 
     
    264214 
    265215 
    266 # Register as resource: 
    267 import gaphor 
    268 _default_undo_manager = gaphor.resource(UndoManager) 
    269 del gaphor 
    270  
     216from gaphor import resource 
     217_default_undo_manager = resource(UndoManager) 
     218 
  • gaphor/trunk/gaphor/ui/diagramtab.py

    r1121 r1170  
    1313from gaphor.ui.abstractwindow import AbstractWindow 
    1414 
    15 from gaphor.event import DiagramItemFocused 
     15from event import DiagramItemFocused 
    1616from zope import component 
    1717 
  • gaphor/trunk/gaphor/ui/mainwindow.py

    r1121 r1170  
    1717 
    1818 
    19 from gaphor.interfaces import * 
     19from interfaces import IDiagramElementReceivedFocus 
     20from gaphor.interfaces import IServiceEvent 
    2021from zope import component 
    2122 
     
    457458#        #resource.set('ui.toolbox.%s' % box_name, visible, persistent=True) 
    458459 
    459     def on_undo(self, *args): 
    460         self.execute_action('UndoStack') 
    461  
    462460#    def on_transient_window_closed(self, window): 
    463461#        assert window in self._transient_windows 
     
    474472 
    475473gtk.accel_map_add_filter('gaphor') 
     474 
     475@component.adapter(IServiceEvent) 
     476def on_undo(*args): 
     477    resource(MainWindow).execute_action('UndoStack') 
     478 
     479component.provideHandler(on_undo) 
     480 
  • gaphor/trunk/gaphor/ui/objectinspector.py

    r1121 r1170  
    11import gtk 
    2 from gaphor.interfaces import * 
     2from interfaces import * 
    33from gaphor.diagram import items 
    44from zope import component