Logo Search packages:      
Sourcecode: mayavi2 version File versions  Download package

workbench_action_proxy.py

00001 """ A proxy for a workbench action. """


# Enthought library imports.
from enthought.pyface.api import ImageResource
from enthought.envisage import Application
from enthought.traits.api import Any, Bool, Instance, List, Property, Str

# Local imports.
from selection_listener_action import SelectionListenerAction
from workbench_action import WorkbenchAction

# fixme: Hacks!
from enthought.envisage.action.action_plugin_definition import \
      DisabledWhen, EnabledWhen



00019 class WorkbenchActionProxy(SelectionListenerAction):
    """ A proxy for a workbench action.

    The proxy lazily loads the actual action implementation when the action
    is first performed.

    """

    #### 'Action' interface ###################################################

    # The action's image (displayed on tool bar tools etc).
    image = Property(Any)

    #### 'WorkbenchActionProxy' interface #####################################

    # The application that the proxy is part of.
    application = Instance(Application)

    # The action that we are a proxy for (lazily loaded from the class name).
    action = Property(Instance(WorkbenchAction))

    # The name of the class that implements the action that we are a proxy
    # for.
    class_name = Str

    # The Id of the plugin that the action was defined in.
    defined_in = Any#Str

    # The path to the image (usually relative to a plugin's definition file).
    image_path = Str

    # The search path to use for the action image.  If not specified, the
    # plugin's location will be used instead.
    image_search_path = List(Str)

    # Should the action be lazy loaded.
    lazy_load = Bool(True)


    # fixme: Dodgy traits that need cleaning up.... use at your own peril!
    bundle = Any
    menu_bar_path = Str
    tool_bar_path = Str
    enabled_when = Instance(EnabledWhen, allow_none=True)
    disabled_when = Instance(DisabledWhen, allow_none=True)

    #### Private interface ####################################################

    # Shadow trait for the 'action' property.
    _action = Any

    # Shadow trait for the 'image' property.
    _image = Any

    ###########################################################################
    # 'object' interface.
    ###########################################################################

00077     def __init__(self, **traits):
        """ Creates a new action proxy. """

        # Base class constructor.
        super(WorkbenchActionProxy, self).__init__(**traits)

        # Listen for changes to the checked state of the action (we can't use
        # a static trait handler here in case the checked state is set in the
        # call to this constructor.
        self.on_trait_change(self._on_checked_changed, 'checked')

        # fixme: This is a hack, but the intent is that if an action is for
        # ALL resource types then don't lazy load it... This is so that
        # actions like copy and paste etc can control their own enablement.
        if hasattr(self.bundle, 'resource_type'):
            if len(self.bundle.resource_type) == 0:
                self.lazy_load = False

        return

    ###########################################################################
    # 'Action' interface.
    ###########################################################################

    #### Properties ###########################################################

    # image
00104     def _get_image(self):
        """ Returns the action's label image. """

        if self._image is None:

            registry   = self.application.plugin_definition_registry
            definition = registry.get_definition(self.defined_in)

            # Determine the image search path to use.  If one wasn't explicitly
            # specified, we use the definition location.
            if self.image_search_path is not None and \
                len(self.image_search_path) > 0:
                search_path = self.image_search_path
            else:
                search_path = [definition.location]

            # Create the action's image resource relative to that directory.
            self._image = ImageResource(name=self.image_path,
                search_path=search_path
            )

        return self._image

    ###########################################################################
    # 'WorkbenchActionProxy' interface.
    ###########################################################################

    #### Properties ###########################################################

    # action
00134     def _get_action(self):
        """ Returns the actual action. """

        if self._action is None:
            # fixme: Quick hacks to get function and object actions in!
            if len(self.bundle.function_name) > 0:
                from function_action import FunctionAction
                self._action = FunctionAction(
                    function_name=self.bundle.function_name
                )
                return self._action

            if len(self.bundle.object) > 0:
                from object_action import ObjectAction
                self._action = ObjectAction(
                    uol     = self.bundle.object,
                    method_name = self.bundle.method_name
                )

                return self._action

            # We are about to actually import the action class, so make sure
            # that the plugin that contributed it has been started.
            self.application.start_plugin(self.defined_in)

            # Import the implementation class
            klass = self.application.import_symbol(self.class_name)

            # Create an instance of it.
            self._action = klass(
                name=self.name, style=self.style, window=self.window
            )

            self._action.on_trait_change(self._on_enabled_changed, 'enabled')

            # We don't set this is in the constructor in case the action uses
            # a static trait handler to listen for changes to the 'checked'
            # trait (which is a common idiom).  If we did set it in the
            # constructor then it might fire before the name, style and window
            # traits had been initialized (since we can't guarantee the order
            # of traits initialization via a **kw argument).
            self._action.checked = self.checked

        return self._action

    ###########################################################################
    # 'Action' interface.
    ###########################################################################

00183     def perform(self, event):
        """ Performs the action. """

        self.action.checked = self.checked

        import inspect

        # fixme: the 'perform' method without taking a context is deprecated!
        args, varargs, varkw, dflts = inspect.getargspec(self.action.perform)

        # If the only argument is 'self' then this is the DEPRECATED
        # interface.
        if len(args) == 1:
            self.action.perform()

        else:
            self.action.perform(event)

        return

    ###########################################################################
    # 'SelectionListenerAction' interface.
    ###########################################################################

00207     def refresh(self):
        """ Refresh the enabled/disabled state of the action etc. """

        if self.window is not None:
            selection = self.window.selection

            if not self.lazy_load:
                self.action.window = self.window
                self.enabled = self.action.enabled

            if self.enabled_when is not None:
                # Enabled when...
                if len(self.enabled_when.resource_type) > 0:
                    self._check_resource_type(
                        self.enabled_when.resource_type, selection
                    )

                elif len(self.enabled_when.cookie) > 0:
                    self._check_cookie(
                        self.enabled_when.cookie, selection
                    )

                elif len(self.enabled_when.parent_cookie) > 0:
                    self._check_parent_cookie(
                        self.enabled_when.parent_cookie, selection
                    )


            if self.disabled_when is not None:
                # Disabled when...
                if len(self.disabled_when.resource_type) > 0:
                    self._check_disable_resource_type(
                        self.disabled_when.resource_type, selection
                    )

                elif len(self.disabled_when.cookie) > 0:
                    self._check_disable_cookie(
                        self.disabled_when.cookie, selection
                    )

                elif len(self.disabled_when.parent_cookie) > 0:
                    self._check_disable_parent_cookie(
                        self.disabled_when.parent_cookie, selection
                    )

        return

    ###########################################################################
    # Private interface.
    ###########################################################################

    #### Trait event handlers #################################################

00260     def _on_checked_changed(self):
        """ Called when the checked state of the action is changed. """

        self.action.checked = self.checked

        return

00267     def _on_enabled_changed(self):
        """ Called when the checked state of the action is changed. """

        self.enabled = self.action.enabled

        return

    def _check_resource_type(self, id, selection):

        rm = self.application.get_service(
            'enthought.envisage.resource.IResourceManager'
        )
        rt = rm.lookup(id)

        for binding in selection:
            if rm.get_type_of(binding.obj) is not rt:
                self.enabled = False
                break

        else:
            self.enabled = True


        return

    def _check_cookie(self, id, selection):

        from enthought.envisage.core.import_manager import ImportManager
        im = ImportManager()
        klass = im.import_symbol(id)

        cm = self.application.get_service(
            'enthought.envisage.resource.ICookieManager'
        )

        for binding in selection:
            cookie = cm.get_cookie(klass, binding.obj)
            if cookie is None:
                self.enabled = False
                break

        else:
            self.enabled = True

        return

    def _check_parent_cookie(self, id, selection):

        from enthought.envisage.core.import_manager import ImportManager
        im = ImportManager()
        klass = im.import_symbol(id)

        from enthought.envisage.project.cookie_manager import CookieManager
        cm = CookieManager()

        for binding in selection:
            if binding.context is None:
                self.enabled = False
                break

            cookie = cm.get_cookie(klass, binding.context)
            if cookie is None:
                self.enabled = False
                break

        else:
            self.enabled = True

        return

    def _check_disable_resource_type(self, id, selection):

        rm = self.application.get_service(
            'enthought.envisage.resource.IResourceManager'
        )
        rt = rm.lookup(id)

        for binding in selection:
            if rm.get_type_of(binding.obj) is rt:
                self.enabled = False
                break

        else:
            self.enabled = True


        return

    def _check_disable_cookie(self, id, selection):

        from enthought.envisage.core.import_manager import ImportManager
        im = ImportManager()
        klass = im.import_symbol(id)

        from enthought.envisage.project.cookie_manager import CookieManager
        cm = CookieManager()

        for binding in selection:
            cookie = cm.get_cookie(klass, binding.obj)
            if cookie is not None:
                self.enabled = False
                break

        else:
            self.enabled = True

        return

    def _check_disable_parent_cookie(self, id, selection):

        from enthought.envisage.core.import_manager import ImportManager
        im = ImportManager()
        klass = im.import_symbol(id)

        from enthought.envisage.project.cookie_manager import CookieManager
        cm = CookieManager()

        for binding in selection:
            if binding.context is None:
                self.enabled = True
                break

            cookie = cm.get_cookie(klass, binding.context)
            if cookie is not None:
                self.enabled = False
                break

        else:
            self.enabled = True

        return

#### EOF ######################################################################

Generated by  Doxygen 1.6.0   Back to index