Move event management into a separate service

This commit is contained in:
Arjan Molenaar 2019-05-08 08:17:00 +02:00
parent 158dcb5155
commit 7026772caa
29 changed files with 214 additions and 187 deletions

View File

@ -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)

View File

@ -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):

View File

@ -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()

View File

@ -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 _

View File

@ -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):

View File

@ -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)

View File

@ -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)

View File

@ -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):

View File

@ -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):
"""

View 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)

View File

@ -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

View File

@ -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)

View File

@ -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):

View File

@ -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):

View File

@ -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)

View File

@ -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."""

View File

@ -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."""

View File

@ -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:

View File

@ -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)
)

View File

@ -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)
)

View File

@ -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

View File

@ -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

View File

@ -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(

View File

@ -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:

View File

@ -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)
)

View File

@ -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)

View File

@ -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):

View File

@ -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"

View File

@ -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",