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

plugin_implementation.py

#-----------------------------------------------------------------------------
#
#  Copyright (c) 2005-2007 by Enthought, Inc.
#  All rights reserved.
#
#  Author: Dave Peterson <dpeterson@enthought.com>
#
#-----------------------------------------------------------------------------

"""
The implementation of the single project plugin.

"""

# Standard library imports
import logging

# Enthought library imports
from enthought.envisage.action import ActionSetManager, DefaultMenuBuilder
from enthought.envisage.core.plugin import Plugin
from enthought.envisage.resource.resource_plugin import ResourcePlugin
from enthought.pyface.action.api import MenuManager

# Local imports.
from model_service import ModelService
from plugin_definition import FactoryDefinition, NO_SELECTION_MENU_ID, \
    SingleProjectActionSet, SyncProjectSelection, UIServiceFactory
from services import IPROJECT_MODEL, IPROJECT_UI


# Setup a logger for this module.
logger = logging.getLogger(__name__)


00035 class PluginImplementation(Plugin):
    """
    The implementation of the single project plugin.

    """

    ##########################################################################
    # 'Plugin' interface.
    ##########################################################################

    ### public interface #####################################################

00047     def start(self, application):
        """
        Starts the plugin.

        Overridden here to start up our services and load the project
        that was open when we were last shut-down.

        """

        super(PluginImplementation, self).start(application)

        # Create and register the model service we offer
        model_service = self._create_model_service()
        self.register_service(IPROJECT_MODEL, model_service)

        # Create and register the ui service we offer
        ui_service = self._create_ui_service(model_service)
        self.register_service(IPROJECT_UI, ui_service)

        # Set up any listeners interested in the current project selection
        self._register_selection_listeners(model_service)

        return


00072     def save_preferences(self):
        """
        Saves the plugin's user preferences.

        Overridden here to add our custom preferences to those being saved.

        """

        logger.debug("Saving preference for PluginImplementation [%s]", self)

        # Ensure that if we don't have a current project, then we don't reuse
        # the last project from when we started.
        self.preferences.set('project location', "")

        # Record the location of any current project.
        current = self.get_service(IPROJECT_MODEL).project
        if current and current.location:
            self.preferences.set('project location', current.location)

        # Save 'em!
        super(PluginImplementation, self).save_preferences()

        return


    ##########################################################################
    # 'PluginImplementation' interface.
    ##########################################################################

    ### protected interface ##################################################

00103     def _create_model_service(self):
        """
        Creates a model service for this plugin.

        """

        # Get a reference to the default resource manager.
        # FIXME: According to Martin Chilvers, we should probably be using
        # our own resource manager to allow different 'contexts' in which
        # resources can be treated differently.
        resource_manager = self.get_service(ResourcePlugin.IRESOURCE_MANAGER)

        # Determine which contributed project factory to use.
        factory = self._get_contributed_project_factory()

        # Create the project service instance.
        result = ModelService(self.application, resource_manager, factory,
            preferences=self.preferences)

        return result


00125     def _create_ui_service(self, model_service):
        """
        Creates a UI service for this plugin.

        """

        # Create the menu manager representing the context menu we show when
        # nothing is selected in the project view.
        menu_manager = self._get_no_selection_context_menu_manager()

        # Get the UI service factory.
        ui_service_factory = self._get_contributed_ui_service_factory()

        # Create the ui service instance
        ui_service = ui_service_factory.create_ui_service(model_service,
            menu_manager)

        return ui_service


00145     def _get_contributed_project_factory(self):
        """
        Retrieves the instance of the project factory to use with this
        plugin.

        The instance is generated from the contributed factory definition
        that was the first one with the highest priority.

        """

        # Retrieve all the factory definition contributions
        extensions = self.application.load_extensions(FactoryDefinition)

        # Find the winning contribution
        definition = None
        for extension in extensions:
            if not definition or extension.priority > definition.priority:
                definition = extension

        # Create an instance of the winning project factory
        logger.info("Using ProjectFactory [%s]", definition.class_name)
        klass = self.import_symbol(definition.class_name)
        factory = klass()

        return factory


00172     def _get_contributed_ui_service_factory(self):
        """
        Retrieves the instance of the UiService factory to use with this
        plugin.

        The instance is generated from the contributed factory definition
        that was the first one with the highest priority.

        """

        # Retrieve all the factory definition contributions
        extensions = self.application.load_extensions(UIServiceFactory)

        # Find the winning contribution
        definition = None
        for extension in extensions:
            if not definition or extension.priority > definition.priority:
                definition = extension

        # Create an instance of the winning factory
        logger.info("Using UiService Factory [%s]", definition.class_name)
        class_name = definition.class_name
        klass = self.import_symbol(class_name)
        factory = klass()

        return factory


00200     def _get_no_selection_context_menu_manager(self):
        """
        Generates a menu manager representing the context menu shown when
        nothing is selected within the project view.  That is, when the
        user right clicks on any empty space within our associated UI.

        """

        # Retrieve all contributions for the no-selection context menu.
        extensions = self.application.load_extensions(SingleProjectActionSet)

        # Populate a menu manager from the extensions.
        menu_manager = MenuManager()
        if len(extensions) > 0:
            action_set_manager = ActionSetManager(action_sets=extensions)
            menu_builder = DefaultMenuBuilder(application=self.application)
            menu_builder.initialize_menu_manager(menu_manager,
                action_set_manager, NO_SELECTION_MENU_ID)

        return menu_manager


00222     def _register_selection_listeners(self, model_service):
        """
        Registers any extension-requested listeners on the project
        selection.

        """

        for sps in self.get_extensions(SyncProjectSelection):
            object = self.application.lookup_application_object(sps.uol)
            if object is not None:
                name = sps.name
                self._register_selection_handler(object, name, model_service)
            else:
                logger.error('Could not resolve the SyncProjectSelection ' + \
                    'UOL: "%s"', sps.uol )

        return


00241     def _register_selection_handler(self, object, name, model_service):
        """
        Creates a handler and registers it.

        """

        def handler():
            # The key to this method is to realize that our goal is to
            # make it as easy as possible to create recipients for
            # notification.  Using traits as the recipients makes
            # creation very simple because we can rely on the type
            # knowledge within that trait to ensure only valid values
            # get assigned to the recipient.  That is the recipient
            # doesn't need to do anything complex to validate the
            # values they get assigned.  This method also works if the
            # recipient isn't a trait, but in that case, they will
            # have to handle multiple selection of the project
            # bindings.
            #
            # First, try to provide the recipient with a multiple
            # selection type value i.e. a list of bindings.
            try:
                setattr(object, name, model_service.selection)
                return
            except:
                pass

            # If that didn't work, remove the binding wrappers and try
            # notification of the resulting list.
            selection = [s.obj for s in model_service.selection]
            try:
                setattr(object, name, selection)
                return
            except:
                pass

            # If that didn't work, and only a single item is selected,
            # then try to provide that item to the recipient.
            if len(selection) == 1:
                try:
                    setattr(object, name, selection[0])
                    return
                except:
                    pass

            # The recipient must not be accepting the type of the
            # current selection, so let's clear its current selection
            # instead.  If this fails, then something has gone wrong
            # with the declaration of the recipient.
            try:
                setattr(object, name, None)
            except:
                logger.debug('Error informing object [%s] of project '
                    'selection change via attribute [%s]', object, name)

        model_service.on_trait_change(handler, 'selection')
        model_service.on_trait_change(handler, 'selection_items')

        return


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


Generated by  Doxygen 1.6.0   Back to index