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

new_named_resource_page.py

00001 """ A wizard page for creating a named resource. """


# Major package imports.
import wx

# Enthought library imports.
from enthought.envisage import get_application
from enthought.envisage.project.project_plugin import ProjectPlugin
from enthought.envisage.resource.resource_plugin import ResourcePlugin
from enthought.envisage.resource.ui import ResourceTree
from enthought.envisage.resource.ui.resource_filter import AllowOnlyFolders
from enthought.naming.api import Binding, Context
from enthought.pyface.api import HeadingText, ImageResource, Sorter, Filter
from enthought.pyface.wizard.api import WizardPage
from enthought.traits.api import Any, Str, HasTraits, Instance

00018 class Details(HasTraits):
    """ The details of the new resource. """

    name = Str


00024 class NewNamedResourcePage(WizardPage):
    """ A wizard page for creating a named resource. """

    # The image used when displaying error messages.
    ERROR_IMAGE = ImageResource('error')

    #### 'NewResourceWizard' interface ########################################

    # The text shown in the 'pretty' title bar.
    text = Str

    # The preifx to use for the default name.
    prefix = Str('New Resource')

    # The object that the wizard is configuring.
    obj = Any

    # The filter for restricting placement of the new resource.
    filter = Instance(Filter)

    ###########################################################################
    # 'WizardPage' interface.
    ###########################################################################

00048     def create_page(self, parent):
        """ Creates the wizard page. """

        panel = wx.Panel(parent, -1, style=wx.CLIP_CHILDREN)
        sizer = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(sizer)
        panel.SetAutoLayout(True)

        # The 'pretty' title bar ;^)
        title = HeadingText(panel, text=self.text)
        sizer.Add(title.control, 0, wx.EXPAND | wx.BOTTOM, 5)

        # The tree used to select the resource's parent folder.
        tree = self._create_tree(panel)
        sizer.Add(tree.control, 1, wx.EXPAND)

        # The resource details.
        details = self._create_details(panel)
        sizer.Add(details, 0, wx.EXPAND)

        # A panel used to display any error messages etc.
        self._error_panel = error_panel = self._create_error_panel(panel)
        error_panel.Show(False)
        sizer.Add(error_panel, 0, wx.EXPAND | wx.TOP | wx.LEFT, 5)

        # Resize the panel to match the sizer's minimum size.
        sizer.Fit(panel)

        # This catches the case when the page is complete by default.
        self._validate()

        return panel

    ###########################################################################
    # Protected 'NewResourcePage' interface.
    ###########################################################################

00085     def _create_details(self, parent):
        """ Creates the resource details panel. """

        if self.obj.parent_folder is not None:
            default_name = self._get_default_name(
                self.prefix, self.obj.parent_folder.obj
            )

        else:
            default_name = self.prefix

        self.obj.name = default_name

        details = Details(name=default_name)
        details.on_trait_change(self._on_name_changed, 'name')

        ui = details.edit_traits(parent=parent, kind='subpanel')
        ui.control.SetFocus()

        return ui.control

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

00110     def _create_tree(self, parent):
        """ Creates the tree used to select the resource's parent folder. """

        resource_manager = get_application().service_registry.get_service(
                  ResourcePlugin.IRESOURCE_MANAGER
            )
        workspace = get_application().service_registry.get_service(
                  ProjectPlugin.IWORKSPACE_SERVICE
            )

        tree = ResourceTree(
            parent,

            # Debugging.
            _name            = 'New named resource tree',

            # Content.
            resource_manager = resource_manager,
            root             = Binding(name='Workspace', obj=workspace),

            # Visualization.
            read_only        = True,
            selection_mode   = 'single',
            show_root        = False,

            # Filtering/sorting.
            filters          = [self.filter],
            sorter           = Sorter()
        )

        # If a default parent folder is specified then make sure that it is
        # visible and selected.
        if self.obj.parent_folder is not None:
            tree.ensure_visible(self.obj.parent_folder)
            tree.select(self.obj.parent_folder)

        # Listen for selection changes.
        tree.on_trait_change(self._on_selection_changed, 'selection')

        return tree

00151     def _create_error_panel(self, parent):
        """ Creates the error panel. """

        panel = wx.Panel(parent, -1, style=wx.CLIP_CHILDREN)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        panel.SetSizer(sizer)
        panel.SetAutoLayout(True)

        # The error bitmap.
        bmp = self.ERROR_IMAGE.create_image().ConvertToBitmap()
        error_bitmap = wx.StaticBitmap(panel, -1, bmp)
        sizer.Add(error_bitmap, 0, wx.EXPAND)

        # The error text.
        self._error_text = wx.StaticText(panel, -1, '')
        sizer.Add(self._error_text, 1, wx.EXPAND | wx.LEFT, 5)

        # Resize the panel to match the sizer's minimum size.
        sizer.Fit(panel)

        return panel

00173     def _validate(self):
        """ Validate the current state to see if the wizard can finish. """

        # fixme: Clean this up!
        if self.obj.parent_folder is not None:
            parent_folder = self._as_context(self.obj.parent_folder)

        else:
            parent_folder= None

        name = self.obj.name

        if parent_folder is None:
            self.complete = False
            return

        if len(name) > 0:
            if name in parent_folder.list_names(''):
                self._error_text.SetLabel(
                    'A resource named "%s" already exists in folder "%s"' \
                    % (name, parent_folder.name)
                )
                self.complete = False
                # fixme: race hack!
                if self._error_panel is not None:
                    self._error_panel.Show(True)

            else:
                self.complete = True
                if self._error_panel is not None:
                    self._error_panel.Show(False)

        else:
            self.complete = False
            if self._error_panel is not None:
                self._error_panel.Show(False)

        return

00212     def _as_context(self, binding):
        """ Returns the binding object as a resource context """

        type_manager = get_application().get_service(
            'enthought.envisage.core.ITypeManager'
        )

        if isinstance( binding.obj, Context ):
            context = self.obj.parent_folder.obj
        else:
            context = type_manager.object_as(
                binding.obj,
                Context,
                environment=binding.context.environment,
                context=binding.context
            )

        return context

00231     def _get_default_name(self, prefix, context):
        """ Returns a name that is not already bound in a context. """

        names = context.list_names('')
        name  = prefix

        id = 2
        while name in names:
            name = '%s (%d)' % (prefix, id)
            id += 1

        return name

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

    #### Dynamic ####

00248     def _on_selection_changed(self, selection):
        """ Called when a node in the tree is selected. """

        # The tree is in single selection mode.
        if len(selection) > 0:
            # The selection is a list of 'Binding's.
            self.obj.parent_folder = selection[0]
            self._validate()

        return

00259     def _on_name_changed(self, old, new):
        """ Called when the name is changed. """

        self.obj.name = new.strip()
        self._validate()

        return

    #### Trait defaults #######################################################
00268     def _filter_default(self):
        """ Create default filter object - AllowOnlyFolders """

        return AllowOnlyFolders()

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

Generated by  Doxygen 1.6.0   Back to index