def _copy_theme ( self, theme ):
        """ Copies the specified DockWindowTheme *theme* into the global default
            theme and signals that the theme has been changed.
        """
        if self._theme is None:
            self._theme = DockWindowTheme()

        self._theme.copy_theme( theme )
class DockWindowThemeFactory ( SingletonHasFacets ):
    """ Defines a factory for producing standard DockWindow themes.
    """

    #-- Facet Definitions ------------------------------------------------------

    # The default theme:
    theme = Property

    # The factory name of the default theme (may be the empty string):
    name = Property

    # The list of all available theme names:
    themes = Property

    #-- Private Facets ---------------------------------------------------------

    # A cache of all dynamically loaded themes:
    _theme_cache = Any( {} ) # { name: ( theme, file_time_stamp ) }

    # The default theme:
    _theme = Instance( DockWindowTheme )

    # The factory name of the current theme (may be the empty string):
    _name = Str

    #-- Property Implementations -----------------------------------------------

    def _get_theme ( self ):
        if self._theme is None:
            name  = (facets_env.theme or
                     self.facet_db_get( 'default', 'default' ))
            theme = getattr( self, name, None )
            if theme is None:
                print ("The FACETS_THEME environment variable is '%s', which "
                       "is not a defined theme.\nThe default theme will be "
                       "used instead.\n\nThe defined themes are:") % name
                for name in self.themes:
                    print ' ', name

                theme = self.default
                name  = 'default'

            self._copy_theme( theme )
            self._name = name
            self.facet_property_set( 'name', '' )

        return self._theme

    def _set_theme ( self, theme ):
        if not isinstance( theme, DockWindowTheme ):
            raise FacetError( 'The value must be a DockWindowTheme' )

        self._copy_theme( theme )
        old_name, self._name = self._name, ''
        self.facet_property_set( 'name', old_name )


    def _get_name ( self ):
        return self._name

    def _set_name ( self, name ):
        old_name = self._name
        if name != old_name:
            self._copy_theme( getattr( self, name ) )
            self._name = name
            self.facet_db_set( 'default', name )
            self.facet_property_set( 'name', old_name )


    def _get_themes ( self ):
        themes = []
        for theme in listdir( theme_path ):
            theme, ext = splitext( theme )
            if ext == '.theme':
                themes.append( theme )

        themes.sort()

        return themes

    #-- object Method Overrides ------------------------------------------------

    def __getattr__ ( self, name ):
        """ Overrides attribute lookup failure to handle unknown attributes as
            possible theme names.
        """
        global theme_environment

        if name[:1] != '_':
            file_name = join( theme_path, name + '.theme' )
            if isfile( file_name ):
                file_time_stamp = stat( file_name )[ ST_MTIME ]
                cache           = self._theme_cache
                info            = cache.get( name )
                if info is not None:
                    theme, theme_time_stamp = info
                    if theme_time_stamp >= file_time_stamp:
                        return theme

                theme_environment[ 'theme' ] = None
                execfile( file_name, theme_environment )
                theme = theme_environment.get( 'theme' )
                if isinstance( theme, DockWindowTheme ):
                    cache[ name ] = ( theme, file_time_stamp )

                    return theme

        raise AttributeError(
            "'%s' object has no attribute '%s'" %
            ( self.__class__.__name__, name )
        )

    #-- Private Methods --------------------------------------------------------

    def _copy_theme ( self, theme ):
        """ Copies the specified DockWindowTheme *theme* into the global default
            theme and signals that the theme has been changed.
        """
        if self._theme is None:
            self._theme = DockWindowTheme()

        self._theme.copy_theme( theme )