Source code for envisage.ui.workbench.workbench_action_manager_builder
# (C) Copyright 2007-2023 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
""" The action manager builder used to build the workbench menu/tool bars. """
# Standard library imports.
import weakref
from pyface.action.api import Action, Group, MenuManager
from pyface.workbench.action.api import MenuBarManager, ToolBarManager
from traits.api import Any, Instance
# Enthought library imports.
from envisage.ui.action.api import AbstractActionManagerBuilder
[docs]class WorkbenchActionManagerBuilder(AbstractActionManagerBuilder):
"""
The action manager builder used to build the workbench menu/tool bars.
"""
#### 'WorkbenchActionManagerBuilder' interface ############################
# The workbench window that we build the menu and tool bars for.
window = Instance("envisage.ui.workbench.api.WorkbenchWindow")
#### Private interface ####################################################
# All action implementations.
_actions = Any
###########################################################################
# Protected 'AbstractActionManagerBuilder' interface.
###########################################################################
def _create_action(self, definition):
"""Create an action implementation from an action definition."""
traits = {"window": self.window}
# Override any traits that can be set in the definition.
if len(definition.name) > 0:
traits["name"] = definition.name
if len(definition.class_name) > 0:
action = self._actions.get(definition.class_name)
if action is None:
klass = self._import_symbol(definition.class_name)
action = klass(**traits)
self._actions[definition.class_name] = action
# fixme: Do we ever actually do this? It seems that in Envisage 3.x
# we always specify an action class!?!
else:
action = Action(**traits)
# fixme: We need to associate the action set with the action to
# allow for dynamic enabling/disabling etc. This is a *very* hacky
# way to do it!
action._action_set_ = definition._action_set_
return action
def _create_group(self, definition):
"""Create a group implementation from a group definition."""
traits = {}
# Override any traits that can be set in the definition.
if len(definition.id) > 0:
traits["id"] = definition.id
if len(definition.class_name) > 0:
klass = self._import_symbol(definition.class_name)
else:
klass = Group
group = klass(**traits)
# fixme: We need to associate the action set with the action to
# allow for dynamic enabling/disabling etc. This is a *very* hacky
# way to do it!
group._action_set_ = definition._action_set_
return group
def _create_menu_manager(self, definition):
"""Create a menu manager implementation from a menu definition."""
# fixme: 'window' is not actually a trait on 'MenuManager'! We set
# it here to allow the 'View' menu to be created. However, it seems
# that menus and actions etc should *always* have a reference to
# the window that they are in?!?
traits = {"window": self.window}
# Override any traits that can be set in the definition.
if len(definition.id) > 0:
traits["id"] = definition.id
if len(definition.name) > 0:
traits["name"] = definition.name
if len(definition.class_name) > 0:
klass = self._import_symbol(definition.class_name)
else:
klass = MenuManager
menu_manager = klass(**traits)
# Add any groups to the menu.
for group in definition.groups:
group._action_set_ = definition._action_set_
menu_manager.insert(-1, self._create_group(group))
# fixme: We need to associate the action set with the action to
# allow for dynamic enabling/disabling etc. This is a *very* hacky
# way to do it!
menu_manager._action_set_ = definition._action_set_
return menu_manager
def _create_menu_bar_manager(self):
"""Create a menu bar manager from the builder's action sets."""
return MenuBarManager(window=self.window)
def _create_tool_bar_manager(self, definition):
"""Create a tool bar manager implementation from a definition."""
traits = {"window": self.window, "show_tool_names": False}
# Override any traits that can be set in the definition.
if len(definition.id) > 0:
traits["id"] = definition.id
if len(definition.name) > 0:
traits["name"] = definition.name
if len(definition.class_name) > 0:
klass = self._import_symbol(definition.class_name)
else:
klass = ToolBarManager
# fixme: 'window' is not actually a trait on 'ToolBarManager'! We
# set it here because it is set on the 'MenuManager'! However, it
# seems that menus and actions etc should *always* have a reference
# to the window that they are in?!?
tool_bar_manager = klass(**traits)
# Add any groups to the tool bar.
for group in definition.groups:
group._action_set_ = definition._action_set_
tool_bar_manager.insert(-1, self._create_group(group))
# fixme: We need to associate the action set with the action to
# allow for dynamic enabling/disabling etc. This is a *very* hacky
# way to do it!
tool_bar_manager._action_set_ = definition._action_set_
return tool_bar_manager
###########################################################################
# Private interface.
###########################################################################
def __actions_default(self):
"""Trait initializer."""
return weakref.WeakValueDictionary()
def _import_symbol(self, symbol_path):
"""Import a symbol."""
return self.window.application.import_symbol(symbol_path)