Index: main/waeup.sirp/trunk/src/waeup/sirp/browser/theming.py
===================================================================
--- main/waeup.sirp/trunk/src/waeup/sirp/browser/theming.py	(revision 5967)
+++ main/waeup.sirp/trunk/src/waeup/sirp/browser/theming.py	(revision 5968)
@@ -26,5 +26,6 @@
 from zope.component import getUtilitiesFor
 from zope.interface import Interface
-from waeup.sirp.interfaces import IThemesProvider
+from zope.schema.interfaces import IVocabularyFactory
+from waeup.sirp.interfaces import SimpleWAeUPVocabulary
 from waeup.sirp.browser.interfaces import ITheme
 from waeup.sirp.browser.resources import waeuptheme_red1, waeuptheme_gray1
@@ -58,10 +59,38 @@
         yield name, theme
 
-class ThemesProvider(grok.GlobalUtility):
-    """A global utility providing all themes available.
+class ThemesVocabulary(grok.GlobalUtility):
+    """A vocabulary that provides all themes available.
+
+    A named global utility implementing
+
+      :class:`zope.schema.interfaces.IVocabularyFactory
+
+    and registered under the name
+
+      'waeup.sirp.browser.theming.ThemesVocabulary'
+    
+    Interface fields that wish to provide a list of available themes
+    can require a 'named vocabulary', i.e. set:
+
+      vocabulary = 'waeup.sirp.browser.theming.ThemesVocabulary'
+
+    and the vocabulary will deliver themes and their descriptive text
+    for instance in select boxes of forms.
+
+    The name is chosen so that the location of this vocabulary can be
+    found easily when used in an interface definition.
     """
-    grok.implements(IThemesProvider)
-    grok.name('default')
+    grok.implements(IVocabularyFactory)
+    grok.name('waeup.sirp.browser.theming.ThemesVocabulary')
+    
+    def __call__(self, context):
+        """Deliver a vocabulary of available themes.
 
-    def __call__(self):
-        return get_all_themes()
+        The `description`s of available themes are used as 'title' and
+        the utility names delivering the different themes as 'value'
+        and 'token'.
+        """
+        terms = [(theme.description, name)
+                 for name, theme in get_all_themes()]
+        vocab = SimpleWAeUPVocabulary(*terms)
+        return vocab
Index: main/waeup.sirp/trunk/src/waeup/sirp/interfaces.py
===================================================================
--- main/waeup.sirp/trunk/src/waeup/sirp/interfaces.py	(revision 5967)
+++ main/waeup.sirp/trunk/src/waeup/sirp/interfaces.py	(revision 5968)
@@ -14,70 +14,4 @@
 from waeup.sirp.permissions import RoleSource
 
-class IThemesProvider(Interface):
-    """A component that delivers all themes defined.
-
-    We normally do not deal with browser-related stuff in `waeup.sirp`
-    but leave that to the `browser` subpackage. With themes (aka
-    skins) we cannot follow that path because we need a theme as an
-    attribute of each `University` instance.
-
-    Therefore we must tell the browser subpackage how we expect themes
-    to be announced code-wise.
-
-    What we tell here is that we might ask for a utility providing
-    IThemeProvider and that this component then should be callable to
-    give us a list of themes and their respective internal names.
-    """
-    def __call__():
-        """Get a list of all themes available.
-
-        Returns a list of ``(<NAME>, <THEME>)`` tuples where
-        ``<NAME>`` is the internal name under which a theme was
-        registered and ``<THEME>`` is the real theme.
-
-        Each <THEME> must have a `description` attribute.
-        """
-
-class ThemesSource(BasicSourceFactory):
-    """A source for themes.
-    """
-    def getValues(self):
-        """Get names of themes.
-        """
-        themes_provider = getUtility(IThemesProvider, name="default")
-        return [x for x, y in themes_provider()]
-    
-    def getTitle(self, value):
-        """Get a user-presentable description for a theme.
-        """
-        themes_provider = getUtility(IThemesProvider, name="default")
-        for name, theme in themes_provider():
-            if name == value:
-                return theme.description
-        return u'unnamed'
-
-class ThemesSourceBinder(object):
-    """A source binder for the `ThemeSource`.
-
-    Normally, we can pass instances of a source (like `ThemeSource`)
-    directly to fields in interfaces (writing something like ``source
-    = ThemeSource()``. With `ThemeSource` we cannot do this, because
-    the set of available themes is not available before the whole
-    `waeup.sirp` package was grokked (and parsed).
-
-    We bypass that problem by defining this trivial source-binder,
-    which is asked for themes only when the values of the source are
-    really needed and after the process of grokking and parsing
-    everything on startup.
-
-    So, although this binder binds to some context (`IUniversity` is
-    currently the only interface making use of this source, so
-    `University` instances are the only context used), the context
-    does not really matter.
-    """
-    implements(schema.interfaces.IContextSourceBinder)
-
-    def __call__(self, context):
-        return ThemesSource()
 
 class FatalCSVError(Exception):
@@ -92,5 +26,4 @@
     return SimpleVocabulary([
             SimpleTerm(value, value, title) for title, value in terms])
-
 
 class IWAeUPObject(Interface):
@@ -113,5 +46,5 @@
         title = u'Skin',
         default = u'waeuptheme-gray1.css',
-        source = ThemesSourceBinder(),
+        vocabulary = 'waeup.sirp.browser.theming.ThemesVocabulary',
         required = True,
         )
