Move event management into a separate service
This commit is contained in:
parent
158dcb5155
commit
7026772caa
@ -173,7 +173,7 @@ class ElementFactory:
|
||||
class ElementFactoryService(Service, ElementFactory):
|
||||
"""Service version of the ElementFactory."""
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
def __init__(self):
|
||||
super(ElementFactoryService, self).__init__()
|
||||
@ -234,4 +234,4 @@ class ElementFactoryService(Service, ElementFactory):
|
||||
Handle events coming from elements (used internally).
|
||||
"""
|
||||
if not self._block_events:
|
||||
self.component_registry.handle(event)
|
||||
self.event_manager.handle(event)
|
||||
|
@ -98,8 +98,8 @@ class ElementFactoryServiceTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
Application.init(["element_factory"])
|
||||
self.factory = Application.get_service("element_factory")
|
||||
component_registry = Application.get_service("component_registry")
|
||||
component_registry.register_handler(handler)
|
||||
event_manager = Application.get_service("event_manager")
|
||||
event_manager.subscribe(handler)
|
||||
clearEvents()
|
||||
|
||||
def tearDown(self):
|
||||
|
@ -27,7 +27,7 @@ class ComponentLookupError(LookupError):
|
||||
pass
|
||||
|
||||
|
||||
_ESSENTIAL_SERVICES = ["component_registry", "element_dispatcher"]
|
||||
_ESSENTIAL_SERVICES = ["component_registry", "event_manager", "element_dispatcher"]
|
||||
|
||||
|
||||
class _Application:
|
||||
@ -45,6 +45,7 @@ class _Application:
|
||||
self._app = None
|
||||
self._essential_services = list(_ESSENTIAL_SERVICES)
|
||||
self.component_registry = None
|
||||
self.event_manager = None
|
||||
|
||||
def init(self, services=None):
|
||||
"""
|
||||
@ -104,9 +105,12 @@ class _Application:
|
||||
# Bootstrap hassle:
|
||||
if name == "component_registry":
|
||||
self.component_registry = srv
|
||||
elif name == "event_manager":
|
||||
self.event_manager = srv
|
||||
|
||||
self.component_registry.register(srv, name)
|
||||
self.component_registry.handle(ServiceInitializedEvent(name, srv))
|
||||
if self.event_manager:
|
||||
self.event_manager.handle(ServiceInitializedEvent(name, srv))
|
||||
return srv
|
||||
|
||||
distribution = property(
|
||||
@ -135,7 +139,7 @@ class _Application:
|
||||
|
||||
def shutdown_service(self, name):
|
||||
srv = self.component_registry.get_service(name)
|
||||
self.component_registry.handle(ServiceShutdownEvent(name, srv))
|
||||
self.event_manager.handle(ServiceShutdownEvent(name, srv))
|
||||
self.component_registry.unregister(srv)
|
||||
srv.shutdown()
|
||||
|
||||
|
@ -5,7 +5,7 @@ An average module should only need to import this module.
|
||||
"""
|
||||
|
||||
from gaphor.application import inject, Application
|
||||
from gaphor.services.componentregistry import event_handler
|
||||
from gaphor.services.eventmanager import event_handler
|
||||
from gaphor.transaction import Transaction, transactional
|
||||
from gaphor.action import action, toggle_action, radio_action, build_action_group
|
||||
from gaphor.i18n import _
|
||||
|
@ -8,7 +8,7 @@ from gaphor.ui.event import DiagramSelectionChange
|
||||
|
||||
|
||||
class Alignment(Service, ActionProvider):
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
menu_xml = """
|
||||
<ui>
|
||||
@ -33,11 +33,11 @@ class Alignment(Service, ActionProvider):
|
||||
self._last_update = None
|
||||
|
||||
def init(self, app):
|
||||
self.component_registry.register_handler(self.update)
|
||||
self.event_manager.subscribe(self.update)
|
||||
self.update()
|
||||
|
||||
def shutdown(self):
|
||||
self.component_registry.unregister_handler(self.update)
|
||||
self.event_manager.unsubscribe(self.update)
|
||||
|
||||
@event_handler(DiagramSelectionChange)
|
||||
def update(self, event=None):
|
||||
|
@ -18,6 +18,7 @@ class ActionManager(Service):
|
||||
"""
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
def __init__(self):
|
||||
self.ui_manager = Gtk.UIManager()
|
||||
@ -29,13 +30,13 @@ class ActionManager(Service):
|
||||
logger.debug("Service is %s" % service)
|
||||
self.register_action_provider(service)
|
||||
|
||||
self.component_registry.register_handler(self._service_initialized_handler)
|
||||
self.event_manager.subscribe(self._service_initialized_handler)
|
||||
|
||||
def shutdown(self):
|
||||
|
||||
logger.info("Shutting down")
|
||||
|
||||
self.component_registry.unregister_handler(self._service_initialized_handler)
|
||||
self.event_manager.unsubscribe(self._service_initialized_handler)
|
||||
|
||||
def execute(self, action_id, active=None):
|
||||
|
||||
@ -44,7 +45,7 @@ class ActionManager(Service):
|
||||
a = self.get_action(action_id)
|
||||
if a:
|
||||
a.activate()
|
||||
self.component_registry.handle(ActionExecuted(action_id, a))
|
||||
self.event_manager.handle(ActionExecuted(action_id, a))
|
||||
else:
|
||||
logger.warning("Unknown action %s" % action_id)
|
||||
|
||||
|
@ -4,19 +4,6 @@ A registry for components (e.g. services) and event handling.
|
||||
|
||||
from gaphor.abc import Service
|
||||
from gaphor.application import ComponentLookupError
|
||||
from gaphor.misc.generic.event import Manager
|
||||
|
||||
|
||||
def event_handler(*event_types):
|
||||
"""
|
||||
Mark a function/method as an event handler for a particular type of event.
|
||||
"""
|
||||
|
||||
def wrapper(func):
|
||||
func.__event_types__ = event_types
|
||||
return func
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class ComponentRegistry(Service):
|
||||
@ -26,7 +13,6 @@ class ComponentRegistry(Service):
|
||||
|
||||
def init(self, app):
|
||||
self._comp = set()
|
||||
self._events = Manager()
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
@ -57,33 +43,3 @@ class ComponentRegistry(Service):
|
||||
|
||||
def all(self, base):
|
||||
return ((c, n) for c, n in self._comp if isinstance(c, base))
|
||||
|
||||
def register_handler(self, handler):
|
||||
"""
|
||||
Register a handler. Handlers are triggered (executed) when specific
|
||||
events are emitted through the handle() method.
|
||||
"""
|
||||
event_types = getattr(handler, "__event_types__", None)
|
||||
if not event_types:
|
||||
raise Exception(f"No event types provided for function {handler}")
|
||||
|
||||
for et in event_types:
|
||||
self._events.subscribe(handler, et)
|
||||
|
||||
def unregister_handler(self, handler=None, event_types=None):
|
||||
"""
|
||||
Unregister a previously registered handler.
|
||||
"""
|
||||
event_types = getattr(handler, "__event_types__", None)
|
||||
if not event_types:
|
||||
raise Exception(f"No event types provided for function {handler}")
|
||||
|
||||
for et in event_types:
|
||||
self._events.unsubscribe(handler, et)
|
||||
|
||||
def handle(self, *events):
|
||||
"""
|
||||
Send event notifications to registered handlers.
|
||||
"""
|
||||
for e in events:
|
||||
self._events.handle(e)
|
||||
|
@ -27,7 +27,7 @@ class CopyService(Service, ActionProvider):
|
||||
on the canvas and make the uml element visible again.
|
||||
"""
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
element_factory = inject("element_factory")
|
||||
main_window = inject("main_window")
|
||||
|
||||
@ -52,11 +52,11 @@ class CopyService(Service, ActionProvider):
|
||||
self.action_group.get_action("edit-copy").props.sensitive = False
|
||||
self.action_group.get_action("edit-paste").props.sensitive = False
|
||||
|
||||
self.component_registry.register_handler(self._update)
|
||||
self.event_manager.subscribe(self._update)
|
||||
|
||||
def shutdown(self):
|
||||
self.copy_buffer = set()
|
||||
self.component_registry.unregister_handler(self._update)
|
||||
self.event_manager.unsubscribe(self._update)
|
||||
|
||||
@event_handler(DiagramSelectionChange)
|
||||
def _update(self, event):
|
||||
|
@ -99,7 +99,7 @@ class ElementDispatcher(Service):
|
||||
|
||||
logger = getLogger("ElementDispatcher")
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
def __init__(self):
|
||||
# Table used to fire events:
|
||||
@ -111,12 +111,12 @@ class ElementDispatcher(Service):
|
||||
self._reverse = dict()
|
||||
|
||||
def init(self, app):
|
||||
self.component_registry.register_handler(self.on_model_loaded)
|
||||
self.component_registry.register_handler(self.on_element_change_event)
|
||||
self.event_manager.subscribe(self.on_model_loaded)
|
||||
self.event_manager.subscribe(self.on_element_change_event)
|
||||
|
||||
def shutdown(self):
|
||||
self.component_registry.unregister_handler(self.on_element_change_event)
|
||||
self.component_registry.unregister_handler(self.on_model_loaded)
|
||||
self.event_manager.unsubscribe(self.on_element_change_event)
|
||||
self.event_manager.unsubscribe(self.on_model_loaded)
|
||||
|
||||
def _path_to_properties(self, element, path):
|
||||
"""
|
||||
|
60
gaphor/services/eventmanager.py
Normal file
60
gaphor/services/eventmanager.py
Normal file
@ -0,0 +1,60 @@
|
||||
"""
|
||||
Event Manager.
|
||||
"""
|
||||
|
||||
from gaphor.abc import Service
|
||||
from gaphor.misc.generic.event import Manager as _Manager
|
||||
|
||||
|
||||
def event_handler(*event_types):
|
||||
"""
|
||||
Mark a function/method as an event handler for a particular type of event.
|
||||
"""
|
||||
|
||||
def wrapper(func):
|
||||
func.__event_types__ = event_types
|
||||
return func
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
class EventManager(Service):
|
||||
"""
|
||||
The Event Manager.
|
||||
"""
|
||||
|
||||
def init(self, app):
|
||||
self._events = _Manager()
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
def subscribe(self, handler):
|
||||
"""
|
||||
Register a handler. Handlers are triggered (executed) when specific
|
||||
events are emitted through the handle() method.
|
||||
"""
|
||||
event_types = getattr(handler, "__event_types__", None)
|
||||
if not event_types:
|
||||
raise Exception(f"No event types provided for function {handler}")
|
||||
|
||||
for et in event_types:
|
||||
self._events.subscribe(handler, et)
|
||||
|
||||
def unsubscribe(self, handler, event_types=None):
|
||||
"""
|
||||
Unregister a previously registered handler.
|
||||
"""
|
||||
event_types = getattr(handler, "__event_types__", None)
|
||||
if not event_types:
|
||||
raise Exception(f"No event types provided for function {handler}")
|
||||
|
||||
for et in event_types:
|
||||
self._events.unsubscribe(handler, et)
|
||||
|
||||
def handle(self, *events):
|
||||
"""
|
||||
Send event notifications to registered handlers.
|
||||
"""
|
||||
for e in events:
|
||||
self._events.handle(e)
|
@ -38,7 +38,7 @@ class FileManager(Service, ActionProvider):
|
||||
The file service, responsible for loading and saving Gaphor models.
|
||||
"""
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
element_factory = inject("element_factory")
|
||||
main_window = inject("main_window")
|
||||
properties = inject("properties")
|
||||
@ -194,7 +194,7 @@ class FileManager(Service, ActionProvider):
|
||||
filename = self.recent_files[index]
|
||||
|
||||
self.load(filename)
|
||||
self.component_registry.handle(FileManagerStateChanged(self))
|
||||
self.event_manager.handle(FileManagerStateChanged(self))
|
||||
|
||||
def load(self, filename):
|
||||
"""Load the Gaphor model from the supplied file name. A status window
|
||||
@ -396,7 +396,7 @@ class FileManager(Service, ActionProvider):
|
||||
# main_window.select_element(diagram)
|
||||
# main_window.show_diagram(diagram)
|
||||
|
||||
self.component_registry.handle(FileManagerStateChanged(self))
|
||||
self.event_manager.handle(FileManagerStateChanged(self))
|
||||
|
||||
@action(name="file-new-template", label=_("New from template"))
|
||||
def action_new_from_template(self):
|
||||
@ -418,7 +418,7 @@ class FileManager(Service, ActionProvider):
|
||||
if filename:
|
||||
self.load(filename)
|
||||
self.filename = None
|
||||
self.component_registry.handle(FileManagerStateChanged(self))
|
||||
self.event_manager.handle(FileManagerStateChanged(self))
|
||||
|
||||
@action(name="file-open", stock_id="gtk-open")
|
||||
def action_open(self):
|
||||
@ -439,7 +439,7 @@ class FileManager(Service, ActionProvider):
|
||||
|
||||
if filename:
|
||||
self.load(filename)
|
||||
self.component_registry.handle(FileManagerStateChanged(self))
|
||||
self.event_manager.handle(FileManagerStateChanged(self))
|
||||
|
||||
@action(name="file-save", stock_id="gtk-save")
|
||||
def action_save(self):
|
||||
@ -454,7 +454,7 @@ class FileManager(Service, ActionProvider):
|
||||
|
||||
if filename:
|
||||
self.save(filename)
|
||||
self.component_registry.handle(FileManagerStateChanged(self))
|
||||
self.event_manager.handle(FileManagerStateChanged(self))
|
||||
return True
|
||||
else:
|
||||
return self.action_save_as()
|
||||
@ -478,7 +478,7 @@ class FileManager(Service, ActionProvider):
|
||||
|
||||
if filename:
|
||||
self.save(filename)
|
||||
self.component_registry.handle(FileManagerStateChanged(self))
|
||||
self.event_manager.handle(FileManagerStateChanged(self))
|
||||
return True
|
||||
|
||||
return False
|
||||
|
@ -32,7 +32,7 @@ class Properties(Service):
|
||||
|
||||
Properties are persisted to the local file system."""
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
def __init__(self, backend=None):
|
||||
"""Constructor. Initialize the Gaphor application object, the
|
||||
@ -105,7 +105,7 @@ class Properties(Service):
|
||||
|
||||
if value != old_value:
|
||||
resources[key] = value
|
||||
self.component_registry.handle(PropertyChangeEvent(key, old_value, value))
|
||||
self.event_manager.handle(PropertyChangeEvent(key, old_value, value))
|
||||
self._backend.update(resources, key, value)
|
||||
|
||||
|
||||
|
@ -20,7 +20,7 @@ class SanitizerService(Service):
|
||||
|
||||
logger = getLogger("Sanitizer")
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
element_factory = inject("element_factory")
|
||||
property_dispatcher = inject("property_dispatcher")
|
||||
|
||||
@ -28,16 +28,16 @@ class SanitizerService(Service):
|
||||
pass
|
||||
|
||||
def init(self, app=None):
|
||||
self.component_registry.register_handler(self._unlink_on_presentation_delete)
|
||||
self.component_registry.register_handler(self._unlink_on_stereotype_delete)
|
||||
self.component_registry.register_handler(self._unlink_on_extension_delete)
|
||||
self.component_registry.register_handler(self._disconnect_extension_end)
|
||||
self.event_manager.subscribe(self._unlink_on_presentation_delete)
|
||||
self.event_manager.subscribe(self._unlink_on_stereotype_delete)
|
||||
self.event_manager.subscribe(self._unlink_on_extension_delete)
|
||||
self.event_manager.subscribe(self._disconnect_extension_end)
|
||||
|
||||
def shutdown(self):
|
||||
self.component_registry.unregister_handler(self._unlink_on_presentation_delete)
|
||||
self.component_registry.unregister_handler(self._unlink_on_stereotype_delete)
|
||||
self.component_registry.unregister_handler(self._unlink_on_extension_delete)
|
||||
self.component_registry.unregister_handler(self._disconnect_extension_end)
|
||||
self.event_manager.unsubscribe(self._unlink_on_presentation_delete)
|
||||
self.event_manager.unsubscribe(self._unlink_on_stereotype_delete)
|
||||
self.event_manager.unsubscribe(self._unlink_on_extension_delete)
|
||||
self.event_manager.unsubscribe(self._disconnect_extension_end)
|
||||
|
||||
@event_handler(AssociationDeleteEvent)
|
||||
def _unlink_on_presentation_delete(self, event):
|
||||
|
@ -315,8 +315,8 @@ class TestUndoManager(TestCase):
|
||||
def handler(event, events=events):
|
||||
events.append(event)
|
||||
|
||||
compreg = Application.get_service("component_registry")
|
||||
compreg.register_handler(handler)
|
||||
em = Application.get_service("event_manager")
|
||||
em.subscribe(handler)
|
||||
try:
|
||||
a = A(factory=self.element_factory)
|
||||
|
||||
@ -338,7 +338,7 @@ class TestUndoManager(TestCase):
|
||||
assert events[1].property is A.a1
|
||||
|
||||
finally:
|
||||
compreg.unregister_handler(handler)
|
||||
em.unsubscribe(handler)
|
||||
undo_manager.shutdown()
|
||||
|
||||
def test_redo_stack(self):
|
||||
|
@ -109,7 +109,7 @@ class UndoManager(Service, ActionProvider):
|
||||
</ui>
|
||||
"""
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
def __init__(self):
|
||||
self._undo_stack = []
|
||||
@ -122,11 +122,11 @@ class UndoManager(Service, ActionProvider):
|
||||
|
||||
logger.info("Starting")
|
||||
|
||||
self.component_registry.register_handler(self.reset)
|
||||
self.component_registry.register_handler(self.begin_transaction)
|
||||
self.component_registry.register_handler(self.commit_transaction)
|
||||
self.component_registry.register_handler(self.rollback_transaction)
|
||||
self.component_registry.register_handler(self._action_executed)
|
||||
self.event_manager.subscribe(self.reset)
|
||||
self.event_manager.subscribe(self.begin_transaction)
|
||||
self.event_manager.subscribe(self.commit_transaction)
|
||||
self.event_manager.subscribe(self.rollback_transaction)
|
||||
self.event_manager.subscribe(self._action_executed)
|
||||
self._register_undo_handlers()
|
||||
self._action_executed()
|
||||
|
||||
@ -134,11 +134,11 @@ class UndoManager(Service, ActionProvider):
|
||||
|
||||
logger.info("Shutting down")
|
||||
|
||||
self.component_registry.unregister_handler(self.reset)
|
||||
self.component_registry.unregister_handler(self.begin_transaction)
|
||||
self.component_registry.unregister_handler(self.commit_transaction)
|
||||
self.component_registry.unregister_handler(self.rollback_transaction)
|
||||
self.component_registry.unregister_handler(self._action_executed)
|
||||
self.event_manager.unsubscribe(self.reset)
|
||||
self.event_manager.unsubscribe(self.begin_transaction)
|
||||
self.event_manager.unsubscribe(self.commit_transaction)
|
||||
self.event_manager.unsubscribe(self.rollback_transaction)
|
||||
self.event_manager.unsubscribe(self._action_executed)
|
||||
self._unregister_undo_handlers()
|
||||
|
||||
def clear_undo_stack(self):
|
||||
@ -168,7 +168,7 @@ class UndoManager(Service, ActionProvider):
|
||||
"""
|
||||
if self._current_transaction:
|
||||
self._current_transaction.add(action)
|
||||
self.component_registry.handle(UndoManagerStateChanged(self))
|
||||
self.event_manager.handle(UndoManagerStateChanged(self))
|
||||
|
||||
# TODO: should this be placed here?
|
||||
self._action_executed()
|
||||
@ -186,7 +186,7 @@ class UndoManager(Service, ActionProvider):
|
||||
|
||||
self._current_transaction = None
|
||||
|
||||
self.component_registry.handle(UndoManagerStateChanged(self))
|
||||
self.event_manager.handle(UndoManagerStateChanged(self))
|
||||
self._action_executed()
|
||||
|
||||
@event_handler(TransactionRollback)
|
||||
@ -212,14 +212,14 @@ class UndoManager(Service, ActionProvider):
|
||||
# Discard all data collected in the rollback "transaction"
|
||||
self._undo_stack = undo_stack
|
||||
|
||||
self.component_registry.handle(UndoManagerStateChanged(self))
|
||||
self.event_manager.handle(UndoManagerStateChanged(self))
|
||||
self._action_executed()
|
||||
|
||||
def discard_transaction(self):
|
||||
|
||||
self._current_transaction = None
|
||||
|
||||
self.component_registry.handle(UndoManagerStateChanged(self))
|
||||
self.event_manager.handle(UndoManagerStateChanged(self))
|
||||
self._action_executed()
|
||||
|
||||
@action(name="edit-undo", stock_id="gtk-undo", accel="<Primary>z")
|
||||
@ -250,7 +250,7 @@ class UndoManager(Service, ActionProvider):
|
||||
while len(self._redo_stack) > self._stack_depth:
|
||||
del self._redo_stack[0]
|
||||
|
||||
self.component_registry.handle(UndoManagerStateChanged(self))
|
||||
self.event_manager.handle(UndoManagerStateChanged(self))
|
||||
self._action_executed()
|
||||
|
||||
@action(name="edit-redo", stock_id="gtk-redo", accel="<Primary>y")
|
||||
@ -267,7 +267,7 @@ class UndoManager(Service, ActionProvider):
|
||||
finally:
|
||||
self._redo_stack = redo_stack
|
||||
|
||||
self.component_registry.handle(UndoManagerStateChanged(self))
|
||||
self.event_manager.handle(UndoManagerStateChanged(self))
|
||||
self._action_executed()
|
||||
|
||||
def in_transaction(self):
|
||||
@ -295,12 +295,12 @@ class UndoManager(Service, ActionProvider):
|
||||
|
||||
logger.debug("Registering undo handlers")
|
||||
|
||||
self.component_registry.register_handler(self.undo_create_event)
|
||||
self.component_registry.register_handler(self.undo_delete_event)
|
||||
self.component_registry.register_handler(self.undo_attribute_change_event)
|
||||
self.component_registry.register_handler(self.undo_association_set_event)
|
||||
self.component_registry.register_handler(self.undo_association_add_event)
|
||||
self.component_registry.register_handler(self.undo_association_delete_event)
|
||||
self.event_manager.subscribe(self.undo_create_event)
|
||||
self.event_manager.subscribe(self.undo_delete_event)
|
||||
self.event_manager.subscribe(self.undo_attribute_change_event)
|
||||
self.event_manager.subscribe(self.undo_association_set_event)
|
||||
self.event_manager.subscribe(self.undo_association_add_event)
|
||||
self.event_manager.subscribe(self.undo_association_delete_event)
|
||||
|
||||
#
|
||||
# Direct revert-statements from gaphas to the undomanager
|
||||
@ -312,12 +312,12 @@ class UndoManager(Service, ActionProvider):
|
||||
|
||||
logger.debug("Unregistering undo handlers")
|
||||
|
||||
self.component_registry.unregister_handler(self.undo_create_event)
|
||||
self.component_registry.unregister_handler(self.undo_delete_event)
|
||||
self.component_registry.unregister_handler(self.undo_attribute_change_event)
|
||||
self.component_registry.unregister_handler(self.undo_association_set_event)
|
||||
self.component_registry.unregister_handler(self.undo_association_add_event)
|
||||
self.component_registry.unregister_handler(self.undo_association_delete_event)
|
||||
self.event_manager.unsubscribe(self.undo_create_event)
|
||||
self.event_manager.unsubscribe(self.undo_delete_event)
|
||||
self.event_manager.unsubscribe(self.undo_attribute_change_event)
|
||||
self.event_manager.unsubscribe(self.undo_association_set_event)
|
||||
self.event_manager.unsubscribe(self.undo_association_add_event)
|
||||
self.event_manager.unsubscribe(self.undo_association_delete_event)
|
||||
|
||||
state.observers.discard(state.revert_handler)
|
||||
|
||||
@ -336,7 +336,7 @@ class UndoManager(Service, ActionProvider):
|
||||
del factory._elements[element.id]
|
||||
except KeyError:
|
||||
pass # Key was probably already removed in an unlink call
|
||||
self.component_registry.handle(ElementDeleteEvent(factory, element))
|
||||
self.event_manager.handle(ElementDeleteEvent(factory, element))
|
||||
|
||||
self.add_undo_action(_undo_create_event)
|
||||
|
||||
@ -351,7 +351,7 @@ class UndoManager(Service, ActionProvider):
|
||||
|
||||
def _undo_delete_event():
|
||||
factory._elements[element.id] = element
|
||||
self.component_registry.handle(ElementCreateEvent(factory, element))
|
||||
self.event_manager.handle(ElementCreateEvent(factory, element))
|
||||
|
||||
self.add_undo_action(_undo_delete_event)
|
||||
|
||||
|
@ -39,11 +39,11 @@ class TransactionTestCase(TestCase):
|
||||
|
||||
Application.init(services=["component_registry"])
|
||||
|
||||
component_registry = Application.get_service("component_registry")
|
||||
event_manager = Application.get_service("event_manager")
|
||||
|
||||
component_registry.register_handler(handle_begins)
|
||||
component_registry.register_handler(handle_commits)
|
||||
component_registry.register_handler(handle_rollback)
|
||||
event_manager.subscribe(handle_begins)
|
||||
event_manager.subscribe(handle_commits)
|
||||
event_manager.subscribe(handle_rollback)
|
||||
|
||||
del begins[:]
|
||||
del commits[:]
|
||||
@ -53,11 +53,11 @@ class TransactionTestCase(TestCase):
|
||||
"""Finished with the test case. Unregister event handlers that
|
||||
store transaction events."""
|
||||
|
||||
component_registry = Application.get_service("component_registry")
|
||||
event_manager = Application.get_service("event_manager")
|
||||
|
||||
component_registry.unregister_handler(handle_begins)
|
||||
component_registry.unregister_handler(handle_commits)
|
||||
component_registry.unregister_handler(handle_rollback)
|
||||
event_manager.unsubscribe(handle_begins)
|
||||
event_manager.unsubscribe(handle_commits)
|
||||
event_manager.unsubscribe(handle_rollback)
|
||||
|
||||
def test_transaction_commit(self):
|
||||
"""Test committing a transaction."""
|
||||
|
@ -71,7 +71,7 @@ class Transaction:
|
||||
... pass
|
||||
"""
|
||||
|
||||
component_registry = application.inject("component_registry")
|
||||
event_manager = application.inject("event_manager")
|
||||
|
||||
_stack = []
|
||||
|
||||
@ -125,11 +125,11 @@ class Transaction:
|
||||
|
||||
def _handle(self, event):
|
||||
try:
|
||||
component_registry = self.component_registry
|
||||
event_manager = self.event_manager
|
||||
except (application.NotInitializedError, application.ComponentLookupError):
|
||||
log.warning("Could not lookup component_registry. Not emitting events.")
|
||||
else:
|
||||
component_registry.handle(event)
|
||||
event_manager.handle(event)
|
||||
|
||||
def __enter__(self):
|
||||
"""Provide with-statement transaction support."""
|
||||
|
@ -8,8 +8,8 @@ Transaction support is located in module gaphor.transaction:
|
||||
|
||||
Do some basic initialization, so event emission will work:
|
||||
|
||||
>>> Application.init(services=['component_registry'])
|
||||
>>> component_registry = Application.get_service('component_registry')
|
||||
>>> Application.init(services=['event_manager'])
|
||||
>>> event_manager = Application.get_service('event_manager')
|
||||
|
||||
The Transaction class is used mainly to signal the begin and end of a transaction. This is done by the TransactionBegin, TransactionCommit and TransactionRollback events:
|
||||
|
||||
@ -17,18 +17,18 @@ The Transaction class is used mainly to signal the begin and end of a transactio
|
||||
>>> @event_handler(transaction.TransactionBegin)
|
||||
... def transaction_begin_handler(event):
|
||||
... print 'tx begin'
|
||||
>>> component_registry.register_handler(transaction_begin_handler)
|
||||
>>> event_manager.subscribe(transaction_begin_handler)
|
||||
|
||||
Same goes for commit and rollback events:
|
||||
|
||||
>>> @event_handler(transaction.TransactionCommit)
|
||||
... def transaction_commit_handler(event):
|
||||
... print 'tx commit'
|
||||
>>> component_registry.register_handler(transaction_commit_handler)
|
||||
>>> event_manager.subscribe(transaction_commit_handler)
|
||||
>>> @event_handler(transaction.TransactionRollback)
|
||||
... def transaction_rollback_handler(event):
|
||||
... print 'tx rollback'
|
||||
>>> component_registry.register_handler(transaction_rollback_handler)
|
||||
>>> event_manager.subscribe(transaction_rollback_handler)
|
||||
|
||||
|
||||
A Transaction is started by initiating a Transaction instance:
|
||||
|
@ -38,7 +38,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
class DiagramPage(ActionProvider):
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
element_factory = inject("element_factory")
|
||||
action_manager = inject("action_manager")
|
||||
|
||||
@ -89,7 +89,7 @@ class DiagramPage(ActionProvider):
|
||||
self.widget = None
|
||||
self.action_group = build_action_group(self)
|
||||
self.toolbox = None
|
||||
self.component_registry.register_handler(self._on_element_delete)
|
||||
self.event_manager.subscribe(self._on_element_delete)
|
||||
|
||||
title = property(lambda s: s.diagram and s.diagram.name or _("<None>"))
|
||||
|
||||
@ -152,7 +152,7 @@ class DiagramPage(ActionProvider):
|
||||
be done if File->Close was pressed.
|
||||
"""
|
||||
self.widget.destroy()
|
||||
self.component_registry.unregister_handler(self._on_element_delete)
|
||||
self.event_manager.unsubscribe(self._on_element_delete)
|
||||
self.view = None
|
||||
|
||||
@action(name="diagram-zoom-in", stock_id="gtk-zoom-in")
|
||||
@ -276,7 +276,7 @@ class DiagramPage(ActionProvider):
|
||||
self.delete_selected_items()
|
||||
|
||||
def _on_view_selection_changed(self, view, selection_or_focus):
|
||||
self.component_registry.handle(
|
||||
self.event_manager.handle(
|
||||
DiagramSelectionChange(view, view.focused_item, view.selected_items)
|
||||
)
|
||||
|
||||
|
@ -173,7 +173,7 @@ class DiagramToolbox:
|
||||
"""
|
||||
|
||||
element_factory = inject("element_factory")
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
properties = inject("properties")
|
||||
|
||||
def __init__(self, diagram, view):
|
||||
@ -243,7 +243,7 @@ class DiagramToolbox:
|
||||
def _after_handler(self, new_item):
|
||||
if self.properties("reset-tool-after-create", False):
|
||||
self.action_group.get_action("toolbox-pointer").activate()
|
||||
self.component_registry.handle(
|
||||
self.event_manager.handle(
|
||||
DiagramItemCreateEvent(self.element_factory, new_item)
|
||||
)
|
||||
|
||||
|
@ -22,7 +22,7 @@ class ElementEditor(UIComponent, ActionProvider):
|
||||
|
||||
element_factory = inject("element_factory")
|
||||
main_window = inject("main_window")
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
title = _("Element Editor")
|
||||
size = (275, -1)
|
||||
@ -85,8 +85,8 @@ class ElementEditor(UIComponent, ActionProvider):
|
||||
self._selection_change(focused_item=focused_item)
|
||||
|
||||
# Make sure we recieve
|
||||
self.component_registry.register_handler(self._selection_change)
|
||||
self.component_registry.register_handler(self._element_changed)
|
||||
self.event_manager.subscribe(self._selection_change)
|
||||
self.event_manager.subscribe(self._element_changed)
|
||||
|
||||
window.connect("destroy", self.close)
|
||||
|
||||
@ -96,8 +96,8 @@ class ElementEditor(UIComponent, ActionProvider):
|
||||
idempotent if set."""
|
||||
|
||||
log.debug("ElementEditor.close")
|
||||
self.component_registry.unregister_handler(self._selection_change)
|
||||
self.component_registry.unregister_handler(self._element_changed)
|
||||
self.event_manager.unsubscribe(self._selection_change)
|
||||
self.event_manager.unsubscribe(self._element_changed)
|
||||
self.window = None
|
||||
self.vbox = None
|
||||
self._current_item = None
|
||||
|
@ -51,6 +51,7 @@ class MainWindow(Service, ActionProvider):
|
||||
"""
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
properties = inject("properties")
|
||||
element_factory = inject("element_factory")
|
||||
action_manager = inject("action_manager")
|
||||
@ -143,10 +144,10 @@ class MainWindow(Service, ActionProvider):
|
||||
self.window = None
|
||||
save_accel_map()
|
||||
|
||||
cr = self.component_registry
|
||||
cr.unregister_handler(self._on_file_manager_state_changed)
|
||||
cr.unregister_handler(self._on_undo_manager_state_changed)
|
||||
cr.unregister_handler(self._new_model_content)
|
||||
em = self.event_manager
|
||||
em.unsubscribe(self._on_file_manager_state_changed)
|
||||
em.unsubscribe(self._on_undo_manager_state_changed)
|
||||
em.unsubscribe(self._new_model_content)
|
||||
|
||||
def init_action_group(self):
|
||||
self.action_group = build_action_group(self)
|
||||
@ -268,10 +269,10 @@ class MainWindow(Service, ActionProvider):
|
||||
self.window.set_resizable(True)
|
||||
self.window.connect("size-allocate", self._on_window_size_allocate)
|
||||
|
||||
cr = self.component_registry
|
||||
cr.register_handler(self._on_file_manager_state_changed)
|
||||
cr.register_handler(self._on_undo_manager_state_changed)
|
||||
cr.register_handler(self._new_model_content)
|
||||
em = self.event_manager
|
||||
em.subscribe(self._on_file_manager_state_changed)
|
||||
em.subscribe(self._on_undo_manager_state_changed)
|
||||
em.subscribe(self._new_model_content)
|
||||
|
||||
def open_welcome_page(self):
|
||||
"""
|
||||
@ -306,7 +307,7 @@ class MainWindow(Service, ActionProvider):
|
||||
lambda e: e.isKindOf(UML.Diagram)
|
||||
and not (e.namespace and e.namespace.namespace)
|
||||
):
|
||||
self.component_registry.handle(DiagramShow(diagram))
|
||||
self.event_manager.handle(DiagramShow(diagram))
|
||||
|
||||
@event_handler(FileManagerStateChanged)
|
||||
def _on_file_manager_state_changed(self, event):
|
||||
@ -364,7 +365,7 @@ class Diagrams(UIComponent, ActionProvider):
|
||||
title = _("Diagrams")
|
||||
placement = ("left", "diagrams")
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
properties = inject("properties")
|
||||
action_manager = inject("action_manager")
|
||||
|
||||
@ -398,17 +399,17 @@ class Diagrams(UIComponent, ActionProvider):
|
||||
self._notebook = Gtk.Notebook()
|
||||
self._notebook.show()
|
||||
self._notebook.connect("switch-page", self._on_switch_page)
|
||||
self.component_registry.register_handler(self._on_show_diagram)
|
||||
self.component_registry.register_handler(self._on_name_change)
|
||||
self.component_registry.register_handler(self._on_flush_model)
|
||||
self.event_manager.subscribe(self._on_show_diagram)
|
||||
self.event_manager.subscribe(self._on_name_change)
|
||||
self.event_manager.subscribe(self._on_flush_model)
|
||||
return self._notebook
|
||||
|
||||
def close(self):
|
||||
"""Close the diagrams component."""
|
||||
|
||||
self.component_registry.unregister_handler(self._on_flush_model)
|
||||
self.component_registry.unregister_handler(self._on_name_change)
|
||||
self.component_registry.unregister_handler(self._on_show_diagram)
|
||||
self.event_manager.unsubscribe(self._on_flush_model)
|
||||
self.event_manager.unsubscribe(self._on_name_change)
|
||||
self.event_manager.unsubscribe(self._on_show_diagram)
|
||||
self._notebook.destroy()
|
||||
self._notebook = None
|
||||
|
||||
@ -466,7 +467,7 @@ class Diagrams(UIComponent, ActionProvider):
|
||||
self._notebook.set_current_page(page_num)
|
||||
self._notebook.set_tab_reorderable(widget, True)
|
||||
|
||||
self.component_registry.handle(DiagramPageChange(widget))
|
||||
self.event_manager.handle(DiagramPageChange(widget))
|
||||
self._notebook.set_show_tabs(True)
|
||||
|
||||
def tab_label(self, title, widget):
|
||||
@ -509,7 +510,7 @@ class Diagrams(UIComponent, ActionProvider):
|
||||
def _on_switch_page(self, notebook, page, page_num):
|
||||
self._clear_ui_settings()
|
||||
self._add_ui_settings(page_num)
|
||||
self.component_registry.handle(DiagramPageChange(page))
|
||||
self.event_manager.handle(DiagramPageChange(page))
|
||||
|
||||
def _add_ui_settings(self, page_num):
|
||||
action_manager = self.action_manager
|
||||
|
@ -299,7 +299,7 @@ class Namespace(UIComponent, ActionProvider):
|
||||
title = _("Namespace")
|
||||
placement = ("left", "diagrams")
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
element_factory = inject("element_factory")
|
||||
action_manager = inject("action_manager")
|
||||
|
||||
@ -339,13 +339,13 @@ class Namespace(UIComponent, ActionProvider):
|
||||
# Event handler registration is in a separate function,
|
||||
# since putting it in with widget construction will cause
|
||||
# unit tests to fail, on macOS at least.
|
||||
cr = self.component_registry
|
||||
cr.register_handler(self._on_element_create)
|
||||
cr.register_handler(self._on_element_delete)
|
||||
cr.register_handler(self._on_model_factory)
|
||||
cr.register_handler(self._on_flush_factory)
|
||||
cr.register_handler(self._on_association_set)
|
||||
cr.register_handler(self._on_attribute_change)
|
||||
em = self.event_manager
|
||||
em.subscribe(self._on_element_create)
|
||||
em.subscribe(self._on_element_delete)
|
||||
em.subscribe(self._on_model_factory)
|
||||
em.subscribe(self._on_flush_factory)
|
||||
em.subscribe(self._on_association_set)
|
||||
em.subscribe(self._on_attribute_change)
|
||||
|
||||
def open(self):
|
||||
self.init()
|
||||
@ -356,13 +356,13 @@ class Namespace(UIComponent, ActionProvider):
|
||||
self._namespace.destroy()
|
||||
self._namespace = None
|
||||
|
||||
cr = self.component_registry
|
||||
cr.unregister_handler(self._on_element_create)
|
||||
cr.unregister_handler(self._on_element_delete)
|
||||
cr.unregister_handler(self._on_model_factory)
|
||||
cr.unregister_handler(self._on_flush_factory)
|
||||
cr.unregister_handler(self._on_association_set)
|
||||
cr.unregister_handler(self._on_attribute_change)
|
||||
em = self.event_manager
|
||||
em.unsubscribe(self._on_element_create)
|
||||
em.unsubscribe(self._on_element_delete)
|
||||
em.unsubscribe(self._on_model_factory)
|
||||
em.unsubscribe(self._on_flush_factory)
|
||||
em.unsubscribe(self._on_association_set)
|
||||
em.unsubscribe(self._on_attribute_change)
|
||||
|
||||
def construct(self):
|
||||
sorted_model = Gtk.TreeModelSort(self.model)
|
||||
@ -567,7 +567,7 @@ class Namespace(UIComponent, ActionProvider):
|
||||
element = self._namespace.get_selected_element()
|
||||
# TODO: Candidate for adapter?
|
||||
if isinstance(element, UML.Diagram):
|
||||
self.component_registry.handle(DiagramShow(element))
|
||||
self.event_manager.handle(DiagramShow(element))
|
||||
|
||||
else:
|
||||
log.debug("No action defined for element %s" % type(element).__name__)
|
||||
@ -602,7 +602,7 @@ class Namespace(UIComponent, ActionProvider):
|
||||
diagram.name = "New diagram"
|
||||
|
||||
self.select_element(diagram)
|
||||
self.component_registry.handle(DiagramShow(diagram))
|
||||
self.event_manager.handle(DiagramShow(diagram))
|
||||
self.tree_view_rename_selected()
|
||||
|
||||
@action(
|
||||
|
@ -15,13 +15,14 @@ logging.basicConfig(level=logging.DEBUG)
|
||||
class DiagramItemConnectorTestCase(TestCase):
|
||||
services = TestCase.services + ["main_window", "action_manager", "properties"]
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
def setUp(self):
|
||||
super(DiagramItemConnectorTestCase, self).setUp()
|
||||
mw = self.get_service("main_window")
|
||||
mw.open()
|
||||
self.main_window = mw
|
||||
self.component_registry.handle(DiagramShow(self.diagram))
|
||||
self.event_manager.handle(DiagramShow(self.diagram))
|
||||
|
||||
def test_item_reconnect(self):
|
||||
# Setting the stage:
|
||||
|
@ -70,6 +70,7 @@ class HandleToolTestCase(unittest.TestCase):
|
||||
"""
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
def setUp(self):
|
||||
Application.init(
|
||||
@ -107,7 +108,7 @@ class HandleToolTestCase(unittest.TestCase):
|
||||
"""
|
||||
element_factory = Application.get_service("element_factory")
|
||||
diagram = element_factory.create(UML.Diagram)
|
||||
self.component_registry.handle(DiagramShow(diagram))
|
||||
self.event_manager.handle(DiagramShow(diagram))
|
||||
comment = diagram.create(
|
||||
CommentItem, subject=element_factory.create(UML.Comment)
|
||||
)
|
||||
@ -147,7 +148,7 @@ class HandleToolTestCase(unittest.TestCase):
|
||||
"""
|
||||
element_factory = Application.get_service("element_factory")
|
||||
diagram = element_factory.create(UML.Diagram)
|
||||
self.component_registry.handle(DiagramShow(diagram))
|
||||
self.event_manager.handle(DiagramShow(diagram))
|
||||
comment = diagram.create(
|
||||
CommentItem, subject=element_factory.create(UML.Comment)
|
||||
)
|
||||
|
@ -14,6 +14,7 @@ class MainWindowTestCase(unittest.TestCase):
|
||||
)
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
|
||||
def tearDown(self):
|
||||
Application.shutdown()
|
||||
@ -34,5 +35,5 @@ class MainWindowTestCase(unittest.TestCase):
|
||||
element_factory = Application.get_service("element_factory")
|
||||
diagram = element_factory.create(UML.Diagram)
|
||||
main_w.open()
|
||||
self.component_registry.handle(DiagramShow(diagram))
|
||||
self.event_manager.handle(DiagramShow(diagram))
|
||||
self.assertEqual(self.get_current_diagram(), diagram)
|
||||
|
@ -32,7 +32,7 @@ class Toolbox(UIComponent, ActionProvider):
|
||||
title = _("Toolbox")
|
||||
placement = ("left", "diagrams")
|
||||
|
||||
component_registry = inject("component_registry")
|
||||
event_manager = inject("event_manager")
|
||||
main_window = inject("main_window")
|
||||
properties = inject("properties")
|
||||
|
||||
@ -63,14 +63,14 @@ class Toolbox(UIComponent, ActionProvider):
|
||||
self.main_window.window.connect_after(
|
||||
"key-press-event", self._on_key_press_event
|
||||
)
|
||||
self.component_registry.register_handler(self._on_diagram_page_change)
|
||||
self.event_manager.subscribe(self._on_diagram_page_change)
|
||||
return widget
|
||||
|
||||
def close(self):
|
||||
if self._toolbox:
|
||||
self._toolbox.destroy()
|
||||
self._toolbox = None
|
||||
self.component_registry.unregister_handler(self._on_diagram_page_change)
|
||||
self.event_manager.unsubscribe(self._on_diagram_page_change)
|
||||
|
||||
def construct(self):
|
||||
def toolbox_button(action_name, stock_id, label, shortcut):
|
||||
|
@ -52,6 +52,7 @@ gaphorconvert = 'gaphor.tools.gaphorconvert:main'
|
||||
|
||||
[tool.poetry.plugins."gaphor.services"]
|
||||
"component_registry" = "gaphor.services.componentregistry:ComponentRegistry"
|
||||
"event_manager" = "gaphor.services.eventmanager:EventManager"
|
||||
"properties" = "gaphor.services.properties:Properties"
|
||||
"undo_manager" = "gaphor.services.undomanager:UndoManager"
|
||||
"element_factory" = "gaphor.UML.elementfactory:ElementFactoryService"
|
||||
|
1
setup.py
1
setup.py
@ -103,6 +103,7 @@ setup(
|
||||
],
|
||||
"gaphor.services": [
|
||||
"component_registry = gaphor.services.componentregistry:ComponentRegistry",
|
||||
"event_manager = gaphor.services.eventmanager:EventManager",
|
||||
"properties = gaphor.services.properties:Properties",
|
||||
"undo_manager = gaphor.services.undomanager:UndoManager",
|
||||
"element_factory = gaphor.UML.elementfactory:ElementFactoryService",
|
||||
|
Loading…
x
Reference in New Issue
Block a user