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

action_proxy.py

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


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

# Local imports.

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



00018 class ActionProxy(Action):
    """ A proxy for a menu action.

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

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

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

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

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

    # The action that this a proxy for (lazily loaded from the class name).
    action = Property(Instance(Action))

    # The name of the class that implements the action that this is 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 = Property
    _image_path = Str('None')

    # 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.
    ###########################################################################

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

        # Base class constructor.
        super(ActionProxy, 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.
    ###########################################################################

00096     def destroy(self):
        """ Called when the action is no longer required.

        In this implementation, this method calls destroy() on the action that
        this object is a proxy for, but only if it was instantiated.
        """

        if self._action is not None:
            self.action.destroy()

        return

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

        # Ensure the event has the application specified on it.
        if not hasattr(event, 'application') or event.application is None:
            event.application = self.application

        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


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

    def _get_image_path(self):
        if self._image_path == 'None':
            return None
        return self._image_path
    
    def _set_image_path(self, image_path):
        if image_path is None:
            self._image_path = 'None'
        else:
            self._image_path = image_path

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

        if self._image is None and self.image_path is not None:

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

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

        return self._image

    ###########################################################################
    # 'ActionProxy' interface.
    ###########################################################################

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

    # action
00169     def _get_action(self):
        """ Returns the proxied 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


00215     def refresh(self):
        """ Refreshes the state of the action (such as enabled or disabled 
        state). 
        """

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

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

        self.action.checked = self.checked

        return

00277     def _on_enabled_changed(self):
        """ Called when the enabled 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