1# (C) Copyright 2007-2019 Enthought, Inc., Austin, TX
2# All rights reserved.
3#
4# This software is provided without warranty under the terms of the BSD
5# license included in LICENSE.txt and may be redistributed only
6# under the conditions described in the aforementioned license.  The license
7# is also available online at http://www.enthought.com/licenses/BSD.txt
8# Thanks for using Enthought open source!
9""" An extensible workbench window. """
10
11
12# Standard library imports.
13import logging
14
15# Enthought library imports.
16import pyface.workbench.api as pyface
17
18from envisage.api import IExtensionPointUser, IExtensionRegistry
19from envisage.api import IServiceRegistry
20from envisage.api import ExtensionPoint, ServiceRegistry
21from envisage.ui.action.api import ActionSet
22from pyface.action.api import StatusBarManager
23from traits.api import Delegate, Instance, List, Property, provides
24
25# Local imports.
26from .workbench_action_manager_builder import WorkbenchActionManagerBuilder
27from .workbench_editor_manager import WorkbenchEditorManager
28
29
30# Logging.
31logger = logging.getLogger(__name__)
32
33
34@provides(IServiceRegistry, IExtensionPointUser)
35class WorkbenchWindow(pyface.WorkbenchWindow):
36    """ An extensible workbench window. """
37
38    # Extension point Ids.
39    ACTION_SETS    = 'envisage.ui.workbench.action_sets'
40    VIEWS          = 'envisage.ui.workbench.views'
41    PERSPECTIVES   = 'envisage.ui.workbench.perspectives'
42    SERVICE_OFFERS = 'envisage.ui.workbench.service_offers'
43
44    #### 'WorkbenchWindow' interface ##########################################
45
46    # The application that the window is part of.
47    #
48    # This is equivalent to 'self.workbench.application', and is provided just
49    # as a convenience since windows often want access to the application.
50    application = Delegate('workbench', modify=True)
51
52    # The action sets that provide the toolbars, menus groups and actions
53    # used in the window.
54    action_sets = List(Instance(ActionSet))
55
56    # The service registry for 'per window' services.
57    service_registry = Instance(IServiceRegistry, factory=ServiceRegistry)
58
59    #### 'IExtensionPointUser' interface ######################################
60
61    # The extension registry that the object's extension points are stored in.
62    extension_registry = Property(Instance(IExtensionRegistry))
63
64    #### Private interface ####################################################
65
66    # The workbench menu and tool bar builder.
67    #
68    # The builder is used to create the window's tool bar and menu bar by
69    # combining all of the contributed action sets.
70    _action_manager_builder = Instance(WorkbenchActionManagerBuilder)
71
72    # Contributed action sets (each contribution is actually a factory).
73    _action_sets = ExtensionPoint(id=ACTION_SETS)
74
75    # Contributed views (each contribution is actually a factory).
76    _views = ExtensionPoint(id=VIEWS)
77
78    # Contributed perspectives (each contribution is actually a factory).
79    _perspectives = ExtensionPoint(id=PERSPECTIVES)
80
81    # Contributed service offers.
82    _service_offers = ExtensionPoint(id=SERVICE_OFFERS)
83
84    # The Ids of the services that were automatically registered.
85    _service_ids = List
86
87    ###########################################################################
88    # 'IExtensionPointUser' interface.
89    ###########################################################################
90
91    def _get_extension_registry(self):
92        """ Trait property getter. """
93
94        return self.application
95
96    ###########################################################################
97    # 'pyface.Window' interface.
98    ###########################################################################
99
100    #### Trait initializers ###################################################
101
102    def _menu_bar_manager_default(self):
103        """ Trait initializer. """
104
105        return self._action_manager_builder.create_menu_bar_manager('MenuBar')
106
107    def _status_bar_manager_default(self):
108        """ Trait initializer. """
109
110        return StatusBarManager()
111
112    def _tool_bar_managers_default(self):
113        """ Trait initializer. """
114
115        return self._action_manager_builder.create_tool_bar_managers('ToolBar')
116
117    #### Trait change handlers ################################################
118
119    def _opening_changed(self):
120        """ Static trait change handler. """
121
122        self._service_ids = self._register_service_offers(self._service_offers)
123
124        return
125
126    def _closed_changed(self):
127        """ Static trait change handler. """
128
129        self._unregister_service_offers(self._service_ids)
130
131        return
132
133    ###########################################################################
134    # 'pyface.WorkbenchWindow' interface.
135    ###########################################################################
136
137    #### Trait initializers ###################################################
138
139    def _editor_manager_default(self):
140        """ Trait initializer. """
141
142        return WorkbenchEditorManager(window=self)
143
144    def _icon_default(self):
145        """ Trait initializer. """
146
147        return self.workbench.application.icon
148
149    def _perspectives_default(self):
150        """ Trait initializer. """
151
152        return [factory() for factory in self._perspectives]
153
154    def _title_default(self):
155        """ Trait initializer. """
156
157        return self.workbench.application.name
158
159    def _views_default(self):
160        """ Trait initializer. """
161
162        return [factory(window=self) for factory in self._views]
163
164    ###########################################################################
165    # 'WorkbenchWindow' interface.
166    ###########################################################################
167
168    def _action_sets_default(self):
169        """ Trait initializer. """
170
171        return [factory(window=self) for factory in self._action_sets]
172
173    ###########################################################################
174    # 'IServiceRegistry' interface.
175    ###########################################################################
176
177    def get_service(self, protocol, query='', minimize='', maximize=''):
178        """ Return at most one service that matches the specified query. """
179
180        service = self.service_registry.get_service(
181            protocol, query, minimize, maximize
182        )
183
184        return service
185
186    def get_service_properties(self, service_id):
187        """ Return the dictionary of properties associated with a service. """
188
189        return self.service_registry.get_service_properties(service_id)
190
191    def get_services(self, protocol, query='', minimize='', maximize=''):
192        """ Return all services that match the specified query. """
193
194        services = self.service_registry.get_services(
195            protocol, query, minimize, maximize
196        )
197
198        return services
199
200    def register_service(self, protocol, obj, properties=None):
201        """ Register a service. """
202
203        service_id = self.service_registry.register_service(
204            protocol, obj, properties
205        )
206
207        return service_id
208
209    def set_service_properties(self, service_id, properties):
210        """ Set the dictionary of properties associated with a service. """
211
212        self.service_registry.set_service_properties(service_id, properties)
213
214        return
215
216    def unregister_service(self, service_id):
217        """ Unregister a service. """
218
219        self.service_registry.unregister_service(service_id)
220
221        return
222
223    ###########################################################################
224    # Private interface.
225    ###########################################################################
226
227    def __action_manager_builder_default(self):
228        """ Trait initializer. """
229
230        action_manager_builder = WorkbenchActionManagerBuilder(
231            window=self, action_sets=self.action_sets
232        )
233
234        return action_manager_builder
235
236    def _register_service_offers(self, service_offers):
237        """ Register all service offers. """
238
239        return list(map(self._register_service_offer, service_offers))
240
241    def _register_service_offer(self, service_offer):
242        """ Register a service offer. """
243
244        # Add the window to the service offer properties (this is so that it
245        # is available to the factory when it is called to create the actual
246        # service).
247        service_offer.properties['window'] = self
248
249        service_id = self.register_service(
250            protocol   = service_offer.protocol,
251            obj        = service_offer.factory,
252            properties = service_offer.properties
253        )
254
255        return service_id
256
257    def _unregister_service_offers(self, service_ids):
258        """ Unregister all service offers. """
259
260        # Unregister the services in the reverse order that we registered
261        # them.
262        service_ids_copy = service_ids[:]
263        service_ids_copy.reverse()
264
265        for service_id in service_ids_copy:
266            self.unregister_service(service_id)
267
268        return
269
270#### EOF ######################################################################
271